四元数 - >矩阵[16] - 好的,现在怎么样? (如何从四元数中显示对象?)

时间:2010-10-26 05:41:33

标签: opengl

我的对象在四元数中的旋转和平移,我已经转换为矩阵[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();

显示如预期。唯一的问题是由于顺序施加,我的旋转是棘手的。因此我希望使用四元数。

2 个答案:

答案 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;

以上是上述表格的搜索和替换,所以我真的希望我没有搞砸。