• Advertisement
Sign in to follow this  

Quaternion Interpolation - Camera 'Popping" during interpolation

This topic is 1948 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having some difficulty replicating a bit of code, after switching from Euler, to Quaternions. The rotation value (a vec3) in my transform class, has each value (x, y, z) constrained between -180 and 180. So, if I was to rotate an object with 0 degrees rotation, 190 degrees, the new rotation would be -170.

My camera's transform needs to be rubber banded to the player. Heres how it was setup with Euler angles (This was called each frame):


vec3 posDif = coreTransform->getTranslation() - lastCoreTransform->getTranslation();
vec3 rotDif = coreTransform->getRotation() - lastCoreTransform->getRotation();

//Adjust values
if( rotDif.x > 180.0f )
rotDif.x -= 360;
if( rotDif.y > 180.0f )
rotDif.y -= 360;
if( rotDif.z > 180.0f )
rotDif.z -= 360;
if( rotDif.x < -180.0f )
rotDif.x += 360;
if( rotDif.y < -180.0f )
rotDif.y += 360;
if( rotDif.z < -180.0f )
rotDif.z += 360;

//reduce the position and rotation by a %
posDif *= 0.25f;
rotDif *= 0.5f;
vec3 newRot = -(lastCoreTransform->getRotation() + rotDif);
vec3 newPos = lastCoreTransform->getTranslation() + posDif;


Here, it is pretty easy to constrain the rotation difference. That way if last rotation was 170, and new rotation is -170, the difference will be the correct 20, rather than -340. So my question is, how do I replicate this with Quaternions? Here is the current interpolation code:


//Interpolate between this transform, and the passed in 'target'
Transform* Transform::interpolate( Transform *target, float rotMultiplier, float posMultiplier )
{
quat thisQuat = cdata->quaternion;
quat targetQuat = target->getQuat();
quat newRotQuat = glm::mix( thisQuat, targetQuat, rotMultiplier );

//check for infinities in return values
if ( newRotQuat.w <= FLT_MAX && newRotQuat.w >= -FLT_MAX)
{
//Number is real, within boudaries.
}
else
{
//then our quat has returned overflow numbers, either to large or too small
// -1.#IND or 1.#IND
newRotQuat = target->getQuat();
}

vec3 newRot = glm::eulerAngles( newRotQuat );

vec3 newPos = cdata->translation + ( (target->getTranslation() - cdata->translation ) * posMultiplier );

//create the new Transform, and pass in values
Transform *nTrans = new Transform();
//nTrans->setMatrix( newPos, newRot, vec3(1.0f, 1.0f, 1.0f) );
nTrans->setMatrix( vec3(0.0f,0.0f,0.0f), newRot, vec3(1.0f, 1.0f, 1.0f) );
return nTrans;
}


It causes the camera to start spinning wildly after a certain rotation is reached. How can I properly constrain the value like I used to, while the code for quaternion interpolation is handled through GLM? (glm::mix)


EDIT:
Alternatively, if anyone has a suggestion, for another way to add easing animation to the camera, I'd be interested in trying it. Edited by gbMike

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement