我的对象在四元数中的旋转和平移,我已经转换为矩阵[16]。
如何将该矩阵提供给OpenGL?我想 - 我可以用我新的花式裤子矩阵glLoadMatrix(),一切都会很好,但我得到一个空白的屏幕。
(我有点像GL n00b,所以请慢慢输入并使用小字;)
我的代码看起来像这样:
glPushMatrix();
[quaternion makeIdentity]; // reset quat
[quaternion setPitch: rotation.x yaw: rotation.y roll: rotation.z]; // Set up with rotation coords (NOTE: setPitch:yaw:roll: is smart about degrees->radians)
GLdouble matrix[16];
[quaternion matrix: &matrix[0]]; // get quat -> matrix
matrix[12] = location.x; // fill in the translation
matrix[13] = location.y;
matrix[14] = location.z;
glLoadMatrixd(matrix);
glScaled(scale.x, scale.y, scale.z);
// draw geometry here -- snip
glPopMatrix();
我觉得我非常接近,但是当我使用这段代码时,我得到一个空白的显示(一切都是glClearColor。)
注意:当我跳过四元数部分并执行以下操作时:
glPushMatrix();
glTranslatef(location.x, location.y, location.z);
glRotated(rotation.z, 0, 0, 1.0);
glRotated(rotation.x, 1.0, 0, 0);
glRotated(rotation.y, 0, 1.0, 0);
// draw geometry here -- snip
glPopMatrix();
显示如预期。唯一的问题是由于顺序施加,我的旋转是棘手的。因此我希望使用四元数。
答案 0 :(得分:2)
如果您忘记将当前矩阵模式设置为GL_MODELVIEW
,则应正确加载矩阵。检查你的quat - >矩阵计算。我将从零角度旋转开始,并将结果与单位矩阵进行比较。
答案 1 :(得分:1)
Quaternions没有翻译部分。必须单独维护翻译,如第二个代码段中的情况。
无论如何,我不确定代码是否能满足要求。如果首先引入万向节锁定的问题,那么四元数将无法解决万向节锁定问题。如果每个帧从俯仰/偏航/滚动重新设置四元数,则会出现与之前相同的问题,并且出于同样的原因。 (如果看起来并非如此,那是因为四元数构造代码与矩阵构造代码可以做的事情相同,但在这种情况下不会:依次围绕每个旋转的轴旋转,而不是围绕a旋转修好了。)
要解决此问题,请将四元数维护为对象状态的一部分,并将每个旋转直接应用于它。尽管如此,这并不能真正买到一个不能用矩阵轻易完成的东西。 (我没有计算过这些操作,所以不是说它可能会变得更有效率,而不是另一种方式。)
四元数的主要优点是它易于在它们之间进行插值,在每个中间步骤得到合理的东西,只需将加权输入相加并对结果进行归一化即可。 SLERP也是一种选择。在某些情况下,对矩阵的等效运算会失效(例如,两个矩阵代表相反的方向,你最终会得到一个完全由零组成的列......),并尝试用俯仰/偏航/滚动来做类似的事情产生了很大的混乱。
至于将一个转换为矩阵,如果你有一个四元数,其向量部分为(qx,qy,qz)
且其标量部分为qw
,你可以使用这样的代码将其转换为OpenGL矩阵:
mtx[0]=1.f-2.f*qy*qy-2.f*qz*qz;
mtx[1]=0.f+2.f*qx*qy+2.f*qw*qz;
mtx[2]=0.f+2.f*qx*qz-2.f*qw*qy;
mtx[3]=0.f;
mtx[4]=0.f+2.f*qx*qy-2.f*qw*qz;
mtx[5]=1.f-2.f*qx*qx-2.f*qz*qz;
mtx[6]=0.f+2.f*qy*qz+2.f*qw*qx;
mtx[7]=0.f;
mtx[8]=0.f+2.f*qx*qz+2.f*qw*qy;
mtx[9]=0.f+2.f*qy*qz-2.f*qw*qx;
mtx[10]=1.f-2.f*qx*qx-2.f*qy*qy;
mtx[11]=0.f;
mtx[12]=0.f;
mtx[13]=0.f;
mtx[14]=0.f;
mtx[15]=1.f;
以上是上述表格的搜索和替换,所以我真的希望我没有搞砸。