Skip to main content
gamedev.net
🔒 Locked

SLERP problem

Started by cppcdr 3 replies 1k views
Original Post
cppcdr
cppcdr
Hi, I am currently working on a milkshape loader and have gotten everything to work except the rotations in the animation. Here is my code.
R3D_Ms3dKeyFrame *pCur = &pJoint->m_RotKeyFrames[frame];
R3D_Ms3dKeyFrame *pPrev = &pJoint->m_RotKeyFrames[frame-1];
// Get the time between the two frames
float fDeltaT = pCur->m_fTime - pPrev->m_fTime;
float fInterp = (fTime - pPrev->m_fTime) / fDeltaT;
D3DXQUATERNION qCur, qPrev, qFinal;
D3DXQuaternionRotationYawPitchRoll(&qCur, pCur->m_fParam[1], pCur->m_fParam[0], pCur->m_fParam[2]);
D3DXQuaternionRotationYawPitchRoll(&qPrev, pPrev->m_fParam[1], pPrev->m_fParam[0], pPrev->m_fParam[2]);
D3DXQuaternionSlerp(&qFinal, &qCur, &qPrev, fInterp);
fRotation[0] = qFinal.x;
fRotation[1] = qFinal.y;
fRotation[2] = qFinal.z;

// Make the matrix 0
m_pJoints.m_matLocal.Zero();
// Rotate the matrix with the original rotation + new rotation
m_pJoints.m_matLocal.Rotate(m_pJoints.m_fRotation[0]+fRotation[0], m_pJoints.m_fRotation[1]+fRotation[1], m_pJoints.m_fRotation[2]+fRotation[2]);
// Translate the matrix with the original translation + new translation
m_pJoints.m_matLocal.SetTranslation(R3DVector(m_pJoints.m_fPosition[0]+fTranslation[0], m_pJoints.m_fPosition[1]+fTranslation[1], m_pJoints.m_fPosition[2]+fTranslation[2]));



the qCur->m_fParam are the rotation values (x(0), y(1), z(2)) for the current frame and pPrev are for the previous frame. The translation works fine but the rotation doesn't. It keeps jumping at odd moments.
jollyjeffers
jollyjeffers
Have you definitely narrowed it down to D3DXQuarternionSlerp()? Are you getting any debug warnings, any error codes?

Occasional jumps sound like a potential timing problem - you hear of similar problems on some multicore CPU's for example or when using low-res timers. Alternatively it could be some numerical instability - at which point printing out intermediary values might help point out the patterns that cause a jump.

Have you tried implementation SLERP yourself? I'm sure there are plenty of examples kicking around - might be useful for further debugging/validation.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
cppcdr
cppcdr
Thanks for the reply. I know that it is the slerp that is causing the problem because the translations work fine and they run with the same timing code.

I don't know what I am doing wrong, but mayby it is my way of getting the rotations out of the quaternions? I don't know if that is the right way...
_neutrin0_
_neutrin0_
Quote:

fRotation[0] = qFinal.x;
fRotation[1] = qFinal.y;
fRotation[2] = qFinal.z;


Ok, I don't really know what your exact implementation details are, but are you assuming qFinal.x, qFinal.y and qFinal.z are pitch, yaw and roll? In that case there is a flaw. The X, Y and Z components of a quaternion are not direct rotations the way you think. They represent a arbitrary axis in 4D. The w component forms the angle of rotation.

To get the 3D axis of rotation and the angle

register float n = sqrtf(x*x + y*y + z*z);if( n > 0.0f ){    axis.x = x/n;    axis.y = y/n;    axis.z = z/n;    angle = 2.0f * acosf(w);}else{    axis.x = 1.0f;    axis.y = 0.0f;    axis.z = 0.0f;    angle = 0.0f;}


To get pitch yaw and roll
void GetPitchYawRoll(float x, float y, float z, float w, float& pitch,float& yaw,float& roll){	register float s = 2.0f * (w*y - x*z);	if( s < 1.0f )	{		if( -1.0f < s )		{			pitch = atan2f( 2.0f * (y*z + w*x), 1.0f - 2.0f * (x*x + y*y));			yaw = asinf( s );			roll = atan2f( 2.0f * (x*y + w*z),1.0f-2.0f*(y*y + z*z) );		}		else		{			pitch = -atan2f( 2.0f * (x*y - w*z), 1.0f - 2.0f * (x*x + z*z) );			yaw = -1.57079632679489661923f;			roll = 0.0f;		}	}	else	{		pitch = atan2f( 2.0f * (x*y - w*z), 1.0f - 2.0f * (x*x + z*z));		yaw = 1.57079632679489661923f;		roll = 0.0f;	}}
++ My::Game ++
cppcdr
cppcdr
Thank you SO much! That solved my problem.
My animations display perfectly with no jumps or skips in them. :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.