HLFX.Ru Forum
Показать все 6 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- Интерполяция углов и кватернионов (https://hlfx.ru/forum/showthread.php?threadid=4710)


Отправлено ILZM 29-12-2015 в 16:40:

Интерполяция углов и кватернионов

Привет всем.

Занимаюсь тут анимациями и не могу побороть один баг (а может быть и фичу, а может быть и свою глупость). Если работать с кватернионами и интерполировать их(слерпить), то все гладко идет, но если вместо кватернионов интерполировать углы, а потом уже конечный угол перевести в кватернион, то в анимациях происходит каша. Типа угол выходит за пределы 180 или -180 градусов(Эх, Кармак). Это константы где-то неравные или что?

C++ Source Code:
1
void NormalizeAngles( Vector &angles, bool rad)
2
{
3
 
4
  for( int i = 0; i < 3; i++ )
5
  {
6
    if ( !rad )
7
    {
8
      if ( angles[i] > 180.0f )
9
      {
10
        angles[i] -= 360.0f;
11
      }
12
 
13
      if ( angles[i] < -180.0f )
14
      {
15
        angles[i] += 360.0f;
16
      }
17
    }
18
    else
19
    {
20
      angles[i] = RAD2DEG ( angles[i] );
21
 
22
      if( angles[i] > 180 ) angles[i] -= 360;
23
      else if( angles[i] < -180 ) angles[i] += 360;
24
 
25
      angles[i] = DEG2RAD ( angles[i] );
26
    }
27
  }
28
}


C++ Source Code:
1
void InterpolateAngles( const Vector &start, const Vector &end, Vector &output, float frac, bool deg )
2
{
3
  for( int i = 0; i < 3; i++ )
4
  {
5
    output[i] = start[i] + ( end[i] - start[i] ) * frac;
6
 
7
    if ( deg )
8
    {
9
      if( output[i] > 180 ) output[i] -= 360;
10
      else if( output[i] < -180 ) output[i] += 360;
11
    }
12
    else
13
    {
14
      output[i] = RAD2DEG ( output[i] );
15
 
16
      if( output[i] > 180 ) output[i] -= 360;
17
      else if( output[i] < -180 ) output[i] += 360;
18
 
19
      output[i] = DEG2RAD ( output[i] );
20
    }
21
  }
22
}


Вот тута просиходит складывание углов анимаций. Не стал делать кватернионами, потому что зачем все время их переводить туда-сюда. Вдруг немного значения потеряется

C++ Source Code:
1
for ( int i = 0; i < m_pStudioHeader->numbones; i++, pbones++, panim++ )
2
{
3
  a [ i ] += a3 [ i ] - a2 [ i ];
4
  p [ i ] += p3 [ i ] - p2 [ i ];
5
 
6
  NormalizeAngles ( a [ i ], false );
7
 
8
  AngleQuaternion ( a [ i ], q [ i ], false );
9
}


На неоптимизированный код не обращайте внимание, делал на коленке.

Вопрос: лучше кватернионы использовать или углы? Мне надо скласть два кватерниона(фактически две анимации). Мб у кого-то есть код? Видел формулу если надо сложить два угла в виде кватернионов, то надо каждые элементы кватернионов перемножить друг на друга resultQuat=Quat1*Quat2


Отправлено XaeroX 29-12-2015 в 16:54:

ILZM
Ты джва года интерполируешь углы и до сих пор не понял, что этого делать нельзя?
Вот уж, право, упорство, достойное вхождения в анналы форумов.


Отправлено ILZM 29-12-2015 в 18:24:

XaeroX медальку за это дают?
2 года ничего не делал. Да. А недавно начал делать новую систему анимаций, да и способ нашел как из ксго анимации выдернуть.

Почему нельзя интерполировать? Работает же, но с огрехами

Добавлено 29-12-2015 в 21:24:

Код теперь правильный, но все равно иногда выходит за пределы...

C++ Source Code:
1
void InterpolateAngles( const Vector &start, const Vector &end, Vector &output, float frac, bool deg )
2
{
3
  /*#if 0
4
  	Vector4D src, dest;
5
 
6
  	// convert to quaternions
7
  	AngleQuaternion( start, src, true );
8
  	AngleQuaternion( end, dest, true );
9
 
10
  	Vector4D result;
11
  	Vector out;
12
 
13
  	// slerp
14
  	QuaternionSlerp( src, dest, frac, result );
15
 
16
  	// convert to euler
17
  	QuaternionAngle( result, out );
18
 
19
  	if( back ) output += out;
20
  	else output = out;
21
#else*/
22
  for ( int i = 0; i < 3; i++ )
23
  {
24
    float diff = end [ i ] - start [ i ];
25
 
26
    if ( deg )
27
    {
28
      if ( diff >= 180 ) { diff -= 360; }
29
        else if ( diff <= -180 ) { diff += 360; }
30
        }
31
        else
32
        {
33
          diff = RAD2DEG ( diff );
34
 
35
      if ( diff >= 180 ) { diff -= 360; }
36
        else if ( diff <= -180 ) { diff += 360; }
37
 
38
      diff = DEG2RAD ( diff );
39
    }
40
 
41
    output [ i ] = start [ i ] + diff * frac;
42
  }
43
 
44
  NormalizeAngles ( output, true );
45
  //#endif
46
}


Отправлено XaeroX 29-12-2015 в 19:22:

Цитата:
ILZM писал:
медальку за это дают?

Дают. Чугунную.
Цитата:
ILZM писал:
Почему нельзя интерполировать? Работает же, но с огрехами

Это то самое знаменитое "почти работает, я вот-вот доделаю". И так два года.

Добавлено 30-12-2015 в 01:22:

Цитата:
ILZM писал:
Код теперь правильный, но все равно иногда

Главное, что ты сам оценил свой код как "правильный"


Отправлено ~ X ~ 29-12-2015 в 21:31:

*нашёл два места, где можно оптимизировать ф-ю NormalizeAngles(), пошёл дальше предаваться раздумьям*

__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Чат по hl[fx]: [email protected]


Отправлено XaeroX 29-12-2015 в 21:32:

~ X ~
Всего два? Однако.


Временная зона GMT. Текущее время 05:43.
Показать все 6 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024