Hashmat Khalil
Hashmat Khalil

Reputation: 1816

continuos smooth incremental rotation of a node (camera)

I'm trying to incrementally rotate the camera around x-axis by 5 degrees. it works fine except for animation at 355 jumps suddenly. it happens due to animation chaining. if my following method is called in SCNSceneRendererDelegate then it is not time based rotation. the SCNSceneRendererDelegate is triggered in each frame. and it means my scene animation action with duration is not ready yet. by lowering the animation duration, the animation is not smooth anymore. doing a timer based with same interval as the animation duration looks bad as well. is there anyway to get this animation smooth?

-(void) updateCameraRotation
{
     SCNQuaternion oldRotScnQuat = _cameraNode.presentationNode.rotation;
     GLKQuaternion glQuatOldRot = GLKQuaternionMakeWithAngleAndAxis(oldRotScnQuat.w, oldRotScnQuat.x, oldRotScnQuat.y, oldRotScnQuat.z);

     float xan = GLKMathDegreesToRadians(5);
     GLKQuaternion newx = GLKQuaternionIdentity;
     GLKVector3 vec = GLKVector3Normalize(GLKVector3Make(1, 0, 0));
     double result = sinf(xan/2);
     newx = GLKQuaternionMakeWithAngleAndAxis(cosf(xan/2), vec.x *result, vec.y * result, vec.z * result);
     newx = GLKQuaternionNormalize(newx);
     glQuatOldRot = GLKQuaternionMultiply(glQuatOldRot, newx);

     axis = GLKQuaternionAxis(glQuatOldRot);
     angle = GLKQuaternionAngle(glQuatOldRot);


    [_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(axis.x, axis.y, axis.z, angle) duration:1]];
}

Upvotes: 0

Views: 457

Answers (2)

Aviad Ben Dov
Aviad Ben Dov

Reputation: 6409

Try to provide a CABasicAnimation with byValue set to your 5 degrees and set repititions to be infinite. Won't that work?

Upvotes: 0

Gouda
Gouda

Reputation: 1005

SLERP is used to make smooth rotations between two known attitudes. Try and avoid needless conversions between axis-angle and quaternions (leave them in quaternions if possible). http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

You will also need to calculate the angle between the quaternion axes: https://math.stackexchange.com/questions/90081/quaternion-distance

I have used both these functions myself and they work well. Rather than adding 5 degrees per frame, you can specify a scalar t in the range of [0, 1].

For instance, when rotating from quaternion P to Q, R = SLERP(P,Q,t) will give you the quaternion R from P to Q. If t = 0 then R = P, if t = 1 then R = Q.

Upvotes: 1

Related Questions