我正在寻找一种在具有四元数的 3D 模型上进行轨迹球旋转的简单实现,特别是在 iOS 上使用 GLKit。到目前为止,我已经检查了以下来源:
- 使用 GLKit 进行轨迹球旋转 http://thestrangeagency.com/arcball-rotation-with-glkit/
- 如何使用 OpenGL 通过触摸旋转 3D 对象 http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl
我也一直在尝试理解源代码和数学here http://www.idevgames.com/articles/quaternions and here http://ofps.oreilly.com/titles/9780596804824/。我可以旋转我的物体,但它总是以某些角度跳跃,所以我担心万向节锁在起作用。我使用手势识别器来控制旋转(平移手势影响滚动和偏航,旋转手势影响俯仰)。我附加了四元数处理以及模型视图矩阵转换的代码。
变量:
四元数处理:
- (void)rotateWithXY:(float)x and:(float)y
{
const float rate = M_PI/360.0f;
GLKVector3 up = GLKVector3Make(0.0f, 1.0f, 0.0f);
GLKVector3 right = GLKVector3Make(1.0f, 0.0f, 0.0f);
up = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), up);
self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(x*rate, up));
right = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), right);
self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(y*rate, right));
}
- (void)rotateWithZ:(float)z
{
GLKVector3 front = GLKVector3Make(0.0f, 0.0f, -1.0f);
front = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), front);
self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(z, front));
}
模型视图矩阵变换(绘制循环内):
// Get Quaternion Rotation
GLKVector3 rAxis = GLKQuaternionAxis(self.transformations.rotationE);
float rAngle = GLKQuaternionAngle(self.transformations.rotationE);
// Set Modelview Matrix
GLKMatrix4 modelviewMatrix = GLKMatrix4Identity;
modelviewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -0.55f);
modelviewMatrix = GLKMatrix4Rotate(modelviewMatrix, rAngle, rAxis.x, rAxis.y, rAxis.z);
modelviewMatrix = GLKMatrix4Scale(modelviewMatrix, 0.5f, 0.5f, 0.5f);
glUniformMatrix4fv(self.sunShader.uModelviewMatrix, 1, 0, modelviewMatrix.m);
非常感谢任何帮助,但我确实想让它尽可能简单并坚持使用 GLKit。