c++ - OpenGL 变换具有不同轴多次旋转的对象

标签 c++ opengl rotation glm-math coordinate-transformation

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

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

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

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

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

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

我现在有:

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)

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

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

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

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

同样,旋转不正确。我在想也许我必须撤消 groupR 的轴平移?然后在某处重新应用它?

最佳答案

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

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

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

并且我们有要在对象上运行的旋转矩阵。在这种情况下,我们绕着 Z 轴旋转:

foat angle ...; // rotation angle

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

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

enter image description here

glm::mat4 modelMat = objMat * rotMat;

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

enter image description here

glm::mat4 modelMat = rotMat * objMat;

要使物体在世界坐标系中绕原点旋转,必须消除物体的旋转:

enter image description here

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

A Rotation around the world origin relative to the object 你必须做相反的事情:

enter image description here

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

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

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

( 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 )

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

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; 

关于c++ - OpenGL 变换具有不同轴多次旋转的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45091505/

相关文章:

c - 二维变换、矩阵乘法

css - 设备旋转时的 Bootstrap 响应 css 和/或视口(viewport)问题/错误

opengl-es - OpenGL制裁剪体面部相机

c++ - Nim 游戏 - 堆栈选择

c++ - 遵循教程后 OpenGL 不渲染任何东西

c++ - 当我们在 C++ 中说 "initialize the object"时,它实际上意味着什么?

c++ - 有没有办法使用 glDrawPixels 渲染单 channel 灰度图像?

c++ - 跨产品混淆

c++ - 如何为此制作模板功能?

c++ - 覆盖 CRT 的 _purecall 实现