• Create Account

Quaternion Interpolation - Camera 'Popping" during interpolation

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

No replies to this topic

#1gbMike  Members

152
Like
0Likes
Like

Posted 21 September 2012 - 03:07 PM

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();

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, 24 September 2012 - 01:47 PM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.