OpenGL转换具有不同轴多次旋转的对象

我正在构建一个建模程序,我想对它们自己空间中的对象进行转换,然后将该单个对象分配给一个组以围绕该组旋转的另一个轴旋转.但是,我还希望能够在对象自身的空间中进行转换.

I am building a modeling program and I'd like to do transformations on objects in their own space and then assign that single object to a group to rotate around another axis which the group rotates around. However, I'd also like to be able to do transformations in the object's own space when it's combined.

操纵单个对象,我选择对象的中心.

Manipulating the individual object, I pick the object's center.

glm::mat4 transform;
transform = glm::translate(transform, - obj.meshCenter);
glm::mat4 transform1;
transform1 = glm::translate(transform1, obj.meshCenter);
obj.rotation =  transform1*obj.thisRot*transform;

然后我将它发送到着色器,

I then send this off to the shader,

glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(obj.translation*obj.rotation*objscale);

我现在想围绕另一个轴旋转这个对象,比如 45 度的 (5,0,0) 轴.

I would now like to rotate this object around another axis, say an axis of (5,0,0) of 45 degrees.

我现在有:

glm::mat4 groupR;
groupR = glm::rotate(groupR,glm::degrees(45.0f),glm::vec3(5,0,0));
obj.groupRotation = groupR;
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, 
glm::value_ptr(obj.groupRotation*obj.translation*obj.rotation*objscale)

我现在已经将对象从它的本地空间移动到了组空间.当与 Group 的旋转相结合时,我现在在对象自己的空间中操作转换有点困难.当我将 groupR 轴设置为 (0,1,0) 时,我的成功有限:

I've now moved the object from it's local space to the Group space. I'm having a bit of difficulty now operating tranformations in the object's own space when combined with the Group's rotation. I've had limited success when I set the groupR axis to (0,1,0) like so:

///Translating object in its own space///
glm::mat4 R = obj.groupRotation;
obj.translation = glm::inverse(R) * obj.translate * R;

这里的问题是,如果 R 的旋转轴(组的旋转)等于 (0,1,0),这只会在它自己的空间中正确平移对象:

the problem here is that this will only translate the object correctly in it's own space if the axis of rotation of R (Group's rotation) is equal to (0,1,0):

///Rotating object in its own space///
glm::mat4 R = obj.groupRotation;
obj.rotation = glm::inverse(R) * obj.rot * R;

再一次,旋转不正确.我在想也许我必须撤消 groupR 的轴平移?然后在某个地方重新应用它?

Again, the rotations are incorrect. I'm thinking that maybe I have to undo the groupR's axis translation? and then re-apply it somewhere?

推荐答案

假设我们有一个被移动、旋转和缩放的对象,我们定义一个变换矩阵如下:

Let's assume we have an object that is moved, rotated and scaled, and we define a transformation matrix as follows:

glm::mat4 objTrans ...; // translation 
glm::mat4 objRot ...;   // roation 
glm::mat4 objScale ...; // scaling

glm::mat4 objMat = objTrans * objRot * objScale;

我们有想要在对象上运行的旋转矩阵.在这种情况下,我们围绕 Z 轴旋转:

And we have rotation matrix that we want to run on the object. In this case we have rotation around the Z-axis:

foat angle ...; // rotation angle

glm::mat4 rotMat = glm::rotate( angle, glm::vec3( 0.0, 0.0, 1.0 ) ); 

我们可以利用这些信息进行多次轮换.首先我们要在其局部轴上旋转对象:

We have several rotations we can do with this information. First we want to rotate the object on its local axis:

glm::mat4 modelMat = objMat * rotMat;

可以像这样执行绕世界原点的旋转:

A Rotation around the worlds origin can be performed like this:

glm::mat4 modelMat = rotMat * objMat;

为了在世界坐标系中围绕物体的原点旋转,我们必须消除物体的旋转:

In order to rotate around the origin of the object in the world coordinate system, we must eliminate the rotation of the object:

glm::mat4 modelMat = objMat * (glm::inverse(objRot) * rotMat * objRot);

相对于对象的绕世界原点的旋转,你必须做相反的事情:

A Rotation around the worlds origin in relation to the object you have to do the opposite:

glm::mat4 modelMat = (objRot * rotMat * glm::inverse(objRot)) * objMat;

如果你有一个对象的完整变换矩阵,但你不知道旋转部分,那么它可以很容易地确定.

If you have a complete transformations matrix for an object and you do not know the rotation part, then it can be easily determined.

请注意,转换矩阵通常如下所示:

Note that a transformation matrix usually looks like this:

( X-axis.x, X-axis.y, X-axis.z, 0 )
( Y-axis.x, Y-axis.y, Y-axis.z, 0 )
( Z-axis.x, Z-axis.y, Z-axis.z, 0 )
( trans.x,  trans.y,  trans.z,  1 )

要生成仅旋转矩阵,您必须提取归一化的轴向量:

To generate a rotation only matrix you have to extract the normalized axis vectors:

glm::mat4 a ...; // any matrix
glm::vec3 x = glm::normalize( a[0][0], a[0][1], a[0][2] );
glm::vec3 y = glm::normalize( a[1][0], a[1][1], a[1][2] );
glm::vec3 z = glm::normalize( a[2][0], a[2][1], a[2][2] );

glm::mat4 r;
r[0][0] = x[0]; r[0][1] = x[1]; r[0][2] = x[2]; r[0][3] = 0.0f;
r[1][0] = y[0]; r[1][1] = y[1]; r[1][2] = y[2]; r[0][3] = 0.0f;
r[2][0] = z[0]; r[2][1] = z[1]; r[2][2] = z[2]; r[0][3] = 0.0f;
r[3][0] = 0.0f; r[3][1] = 0.0f; r[3][2] = 0.0f; r[0][3] = 1.0f; 

相关文章