我正在阅读Jason L. McKesson的在线“学习现代3D图形编程”书
到目前为止,我要解决万向节锁定问题以及如何使用四元数来解决它。
然而,就在这里,在四元数页面上。
问题的一部分是,我们试图将方向存储为一系列3个累积的轴向旋转。方向是方向,而不是旋转。方向当然不是一系列旋转。因此,我们需要将船舶的方向视为方向,作为特定数量。
我想这是我开始感到困惑的第一个地方,原因是因为我看不到方向和旋转之间的巨大差异。我也不明白为什么方向不能通过一系列旋转来表示...
也:
为此,首先想到的是将方向保持为矩阵。当需要修改方向时,我们只需对此矩阵进行转换,将结果存储为新的当前方向。
这意味着应用于当前方向的每个偏航,俯仰和横滚都将相对于该当前方向。正是我们所需要的。如果用户应用正偏航,则希望该偏航相对于它们当前指向的位置而不是相对于某个固定坐标系旋转它们。
我理解这个概念,但是我不理解如果累积矩阵变换可以解决此问题,那么上一页中给出的代码不仅如此。
这是代码:
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutil::MatrixStack currMatrix;
currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
currMatrix.RotateX(g_angles.fAngleX);
DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
currMatrix.RotateY(g_angles.fAngleY);
DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
currMatrix.RotateZ(g_angles.fAngleZ);
DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));
glUseProgram(theProgram);
currMatrix.Scale(3.0, 3.0, 3.0);
currMatrix.RotateX(-90);
//Set the base color for this object.
glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));
g_pObject->Render("tint");
glUseProgram(0);
glutSwapBuffers();
}
据我了解,他所做的(修改堆栈上的矩阵)不是考虑累积矩阵,因为作者将所有单独的旋转变换组合为一个矩阵,该矩阵存储在堆栈的顶部。
我对矩阵的理解是,它们用于获取相对于原点(比如说……模型)的点,并使它相对于另一原点(相机)。我很确定这是一个安全的定义,但是我觉得缺少一些东西使我无法理解此万向节锁定问题。
对我来说没有意义的一件事是:如果矩阵确定了两个“空间”之间的相对差,那么绕着Y轴旋转(比如说滚动)的结果如何不会将点放在“滚动空间”中“然后可以相对于该滚动再次进行转换。换句话说,不应对此点进行任何进一步的转换以与此新的“滚动空间”相关,因此旋转不应相对于先前的“模型空间”,这会导致云台锁定。
这就是为什么发生万向节锁定的原因?这是因为我们绕着X,Y和Z轴旋转对象,而不是绕着自己的相对轴旋转对象。还是我错了?
既然我链接的这段代码显然不是矩阵变换的累积,您可以举一个使用此方法的解决方案示例。
因此,总而言之:
- 旋转和方向之间有什么区别?
- 为什么链接的代码不是矩阵转换累积的示例?
- 如果矩阵错误,矩阵的真正特定目的是什么?
- 如何使用矩阵变换的累积来实现万向节锁定问题的解决方案?
- 另外,作为奖励:为什么旋转后的变换仍然相对于“模型空间”?
- 另一个好处是:我认为在转换之后,相对于当前的转换将发生进一步的转换,我是否错了?
另外,如果没有暗示,则我使用的是OpenGL,GLSL,C ++和GLM,因此,如果没有必要,则非常感谢您提供有关这些示例和说明的信息。
细节越多越好!
提前致谢。