Reputation: 1816
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
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
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