Slerp вопросы, перспективное деформирование

Я по сути работаю над функцией для slerping и хотя это вроде как работает, у меня странная перспективная проблема, которую я застрял, пытаясь решить прямо сейчас.

Quaternion sLerp(Quaternion start, Quaternion end, float s)
{
float dot = qDot(start, end);
float theta = std::acos(dot);
float sTheta = std::sin(theta);

float w1 = sin((1.0f-s)*theta) / sTheta;
float w2 = sin(s*theta) / sTheta;

Quaternion Temp(0,0,0,0);

Temp = start*w1 + end*w2;

return Temp;
}

По сути, то, что он делает (или должен делать), это просто разбрасывает между двумя значениями, чтобы обеспечить вращение, и результат этого преобразовывается в матрицу вращения. Но то, что идет не так, это ужасно, ужасно растянутое представление … по какой-то причине во время вращения оно растягивало все, начиная со всего слишком длинного / тонкого и достигая середины гораздо меньшей длины, прежде чем снова становиться худым. Любая помощь будет отличной.

1

Решение

Ваш код Slerp кажется нормальным, хотя обычно нужно убедиться, что dot>=0 потому что иначе вы вращаете длинный круг. В общем, также важно убедиться, что dot!=1 потому что вы столкнетесь с деления на ноль проблемы.

Правильный кватернион никогда не должен растягивать взгляд. Либо вы передаете в кватернионы не единичной длины для start или же endили ваш код кватерниона к матрице является подозрительным (или вы получаете странное поведение, потому что угол между двумя кватернионами очень мал, а вы делите почти на ноль).


Мой код для преобразования из кватерниона в матрицу для использования в OpenGL:

// First row
glMat[ 0] = 1.0f - 2.0f * ( q[1] * q[1] + q[2] * q[2] );
glMat[ 1] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
glMat[ 2] = 2.0f * (q[0] * q[2] - q[1] * q[3]);
glMat[ 3] = 0.0f;

// Second row
glMat[ 4] = 2.0f * ( q[0] * q[1] - q[2] * q[3] );
glMat[ 5] = 1.0f - 2.0f * ( q[0] * q[0] + q[2] * q[2] );
glMat[ 6] = 2.0f * (q[2] * q[1] + q[0] * q[3] );
glMat[ 7] = 0.0f;

// Third row
glMat[ 8] = 2.0f * ( q[0] * q[2] + q[1] * q[3] );
glMat[ 9] = 2.0f * ( q[1] * q[2] - q[0] * q[3] );
glMat[10] = 1.0f - 2.0f * ( q[0] * q[0] + q[1] * q[1] );
glMat[11] = 0.0f;

// Fourth row
glMat[12] = 0.0;
glMat[13] = 0.0;
glMat[14] = 0.0;
glMat[15] = 1.0f;
1

Другие решения

Нужно ли нормализовать кватернион?

Я думаю следующее:

float sTheta = std::sin(theta);

должно быть:

float sTheta = sqrt(1.0f - sqr(theta));
0

По вопросам рекламы [email protected]