节点(相机)的连续平滑增量旋转

continuos smooth incremental rotation of a node (camera)

我正在尝试将相机绕 x 轴增量旋转 5 度。它工作正常,除了突然跳 355 次的动画。它是由于动画链接而发生的。如果在 SCNSceneRendererDelegate 中调用了我的以下方法,则它不是基于时间的轮换。 SCNSceneRendererDelegate 在每一帧中被触发。这意味着我的持续时间场景动画动作还没有准备好。通过降低动画持续时间,动画不再流畅。做一个基于与动画持续时间相同的间隔的计时器看起来也很糟糕。有没有办法让这个动画流畅?

-(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]];
}

SLERP 用于在两个已知姿态之间进行平滑旋转。尝试避免在轴角和四元数之间进行不必要的转换(如果可能,将它们保留在四元数中)。 http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

您还需要计算四元数轴之间的角度:https://math.stackexchange.com/questions/90081/quaternion-distance

这两个功能我都用过,效果不错。 您可以指定 [0, 1].

范围内的标量 t,而不是每帧添加 5 度

例如,当从四元数 P 旋转到 Q 时,R = SLERP(P,Q,t) 将为您提供从 P 到 Q 的四元数 R。如果 t = 0,则 R = P,如果 t = 1那么 R = Q.

尝试提供一个 CABasicAnimation,将 byValue 设置为您的 5 度并将重复次数设置为无限。那行不通吗?