我正在构建一个建模程序,我想对自己空间中的对象进行转换,然后将该单个对象分配给一个组,以围绕该组旋转的另一个轴旋转。但是,我也希望能够在对象自己的空间中进行转换。
操纵单个物体,我选择物体的中心。
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),这只会在它自己的空间中正确地翻译对象: / p>
///Rotating object in its own space///
glm::mat4 R = obj.groupRotation;
obj.rotation = glm::inverse(R) * obj.rot * R;
同样,轮换不正确。我想也许我必须撤消groupR的轴转换?然后在某处重新应用它?
答案 0 :(得分:4)
假设我们有一个被移动,旋转和缩放的对象,我们定义一个转换矩阵如下:
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 ) );
我们可以通过这些信息进行多次轮换。 首先,我们想要在其局部轴上旋转对象:
glm::mat4 modelMat = objMat * rotMat;
围绕世界起源的旋转可以这样执行:
glm::mat4 modelMat = rotMat * objMat;
为了围绕世界坐标系中对象的原点旋转,我们必须消除对象的旋转:
glm::mat4 modelMat = objMat * (glm::inverse(objRot) * rotMat * objRot);
围绕世界起源的旋转与你必须做的相反的对象相关:
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 )
要生成仅旋转矩阵,您必须提取标准化的轴向量:
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;
答案 1 :(得分:1)
以下是我想要的行为和我使用的设置的部分答案。这似乎是我需要做的,以便在组旋转的同时在对象空间中获得正确的变换。 在这里,我有一个由7个不同的单独网格组成的模型,这些网格围绕y轴上的(0,5,0)原点旋转,这只是我选择进行测试的任意旋转。
for (int i = 0; i < models.at(currentSelectedPointer.x)->meshes.size()i++)
{
glm::mat4 rotMat;
rotMat = glm::translate(rotMat, glm::vec3(5, 0, 0));
rotMat = glm::rotate(rotMat, f, glm::vec3(0, 1.0, 0.0));
rotMat = glm::translate(rotMat, glm::vec3(-5, 0, 0));
models.at(currentSelectedPointer.x)->meshes.at(i).groupRotation = rotMat;
}
现在所有的网格都在(0,5,0)作为一组旋转,而不是在Y轴上的(0,5,0)。
对它自己的对象空间中的单个对象进行正确的旋转变换,我必须撤消groupRotation原点的位置(对于凌乱的代码我很抱歉,但是我这样做是为了让所有内容保持分离并且很容易disectable)。此外,单个对象的翻译和缩放都有一个单位矩阵。
//These will be used to shift the groupRotation origin back to the
// origin in order to rotate around the object's origin.
glm::mat4 gotoGroupAxis;
gotoGroupAxis= glm::translate(gotoGroupAxis, glm::vec3(5, 0, 0));
glm::mat4 goBack ;
goBack = glm::translate(goBack , glm::vec3(-5, 0, 0));
////////Group rotation and it's inverse
glm::mat4 tempGroupRot = goBack *obj.groupRotation*gotoGroupAxis;
glm::mat4 tempGroupRotInverse= glm::inverse(tempGroupRot);
//thisRot and lastRot are matrix variables I use to accumulate and
//save rotations
obj.thisRot = tempGroupRotInverse*
glm::toMat4(currentRotation)*tempGroupRot *
obj.lastRot;
//now I translate the object's rotation origin to it's center.
glm::mat4 transform = glm::translate(transform, -obj.meshCenter);
glm::mat4 transform1 = glm::translate(transform1, obj.meshCenter);
//Finally I rotate the object in it's own space.
obj.rotation = transform1*obj.thisRot*transform;
更新
//Translation works as well with
obj.finalTranslation= tempGroupRotInverse*
obj.translation * tempGroupRot ;
这只是一个部分答案,因为我将在对象级别和组级别进行转换,我几乎可以肯定某些事情会在答案未考虑的情况下出错我发布了。