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) |
4 | for( int i = 0; i < 3; i++ ) |
8 | if ( angles[i] > 180.0f ) |
13 | if ( angles[i] < -180.0f ) |
20 | angles[i] = RAD2DEG ( angles[i] ); |
22 | if( angles[i] > 180 ) angles[i] -= 360; |
23 | else if( angles[i] < -180 ) angles[i] += 360; |
25 | angles[i] = DEG2RAD ( angles[i] ); |
C++ Source Code:
1 | void InterpolateAngles( const Vector &start, const Vector &end, Vector &output, float frac, bool deg ) |
3 | for( int i = 0; i < 3; i++ ) |
5 | output[i] = start[i] + ( end[i] - start[i] ) * frac; |
9 | if( output[i] > 180 ) output[i] -= 360; |
10 | else if( output[i] < -180 ) output[i] += 360; |
14 | output[i] = RAD2DEG ( output[i] ); |
16 | if( output[i] > 180 ) output[i] -= 360; |
17 | else if( output[i] < -180 ) output[i] += 360; |
19 | output[i] = DEG2RAD ( output[i] ); |
Вот тута просиходит складывание углов анимаций. Не стал делать кватернионами, потому что зачем все время их переводить туда-сюда. Вдруг немного значения потеряется
C++ Source Code:
1 | for ( int i = 0; i < m_pStudioHeader->numbones; i++, pbones++, panim++ ) |
3 | a [ i ] += a3 [ i ] - a2 [ i ]; |
4 | p [ i ] += p3 [ i ] - p2 [ i ]; |
6 | NormalizeAngles ( a [ i ], false ); |
8 | AngleQuaternion ( a [ i ], q [ i ], false ); |
На неоптимизированный код не обращайте внимание, делал на коленке.
Вопрос: лучше кватернионы использовать или углы? Мне надо скласть два кватерниона(фактически две анимации). Мб у кого-то есть код? Видел формулу если надо сложить два угла в виде кватернионов, то надо каждые элементы кватернионов перемножить друг на друга 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 ) |
6 | // convert to quaternions |
7 | AngleQuaternion( start, src, true ); |
8 | AngleQuaternion( end, dest, true ); |
14 | QuaternionSlerp( src, dest, frac, result ); |
17 | QuaternionAngle( result, out ); |
19 | if( back ) output += out; |
22 | for ( int i = 0; i < 3; i++ ) |
24 | float diff = end [ i ] - start [ i ]; |
28 | if ( diff >= 180 ) { diff -= 360; } |
29 | else if ( diff <= -180 ) { diff += 360; } |
33 | diff = RAD2DEG ( diff ); |
35 | if ( diff >= 180 ) { diff -= 360; } |
36 | else if ( diff <= -180 ) { diff += 360; } |
38 | diff = DEG2RAD ( diff ); |
41 | output [ i ] = start [ i ] + diff * frac; |
44 | NormalizeAngles ( output, true ); |
Отправлено 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 ~
Всего два? Однако. 