且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

GLM - 矩阵的方向是创建行主要而不是列主矩阵?

更新时间:2023-11-17 14:15:10

矩阵M从空间A到空间B的转换具有空间A的基本向量,但是相对于空间B表示。



相机矩阵从世界空间变换到相机空间。因此,照相机矩阵的基本向量是从相机空间看到的世界空间的基本向量。

相机的方向相对于世界空间是 >这种转变。由于旋转矩阵的逆是转置,你有你的问题。

问题不在于矩阵;问题在于你 矩阵说的区别和它实际上说的是什么。


After figuring out the answer to my previous question I have found the cause to be some kind of mathematical oddity.

Using the GLM (OpenGL) library I create an orientation as follows

glm::gtx::quaternion::orientation = 
    glm::gtx::quaternion::angleAxis(pitchAccum, 1.0f, 0.0f, 0.0f) * 
    glm::gtx::quaternion::angleAxis(yawAccum, 0.0f, 1.0f, 0.0f);

Now if I create a matrix from this orientation it is no longer column major but somehow becomes row major

    glm::mat4 view = glm::gtx::quaternion::toMat4(orientation); 

In other words the 3 coordinates axes are found by accessing the matrix using row major indices

view[0][0], view[1][0], view[2][0]  // X axis
view[0][1], view[1][1], view[2][1]  // Y axis
view[0][2], view[1][2], view[2][2]  // Z axis

In other words the transpose of the rotation part.

The translation part of the matrix should still be set using column major in order for the final view matrix to work as intended.

view[3][0] = -glm::dot(glm::vec3(view[0][0], view[1][0], view[2][0]), position);    // Right
view[3][1] = -glm::dot(glm::vec3(view[0][1], view[1][1], view[2][1]), position);    // Up
view[3][2] = -glm::dot(glm::vec3(view[0][2], view[1][2], view[2][2]), position);    // Forward

Why is the rotation matrix flipped from column major to row major (transposed?) when using the orientation?

EDIT:

// Move forward
if (glfwGetKey('W') == GLFW_PRESS)
{
    //movement += glm::vec3(view[2][0], view[2][1], view[2][2]);  // incorrect
    movement += -glm::vec3(view[0][2], view[1][2], view[2][2]);   // correct
}
// Move backward
if (glfwGetKey('S') == GLFW_PRESS)
{
    //movement += -glm::vec3(view[2][0], view[2][1], view[2][2]); // incorrect
    movement += glm::vec3(view[0][2], view[1][2], view[2][2]);    // correct
}
// Strafe left
if (glfwGetKey('A') == GLFW_PRESS)
{
    //movement += -glm::vec3(view[0][0], view[0][1], view[0][2]);  // incorrect
    movement += -glm::vec3(view[0][0], view[1][0], view[2][0]);    // correct
}
// Strafe right
if (glfwGetKey('D') == GLFW_PRESS)
{
    //movement += glm::vec3(view[0][0], view[0][1], view[0][2]);  // incorrect
    movement += glm::vec3(view[0][0], view[1][0], view[2][0]);    // correct
}

A matrix M which transforms from the space A to the space B has the basis vectors of space A, but expressed relative to space B.

The camera matrix transforms from world space to camera space. Thus, the basis vectors of the camera matrix are the basis vectors of world space, as seen from camera space. Not the basis vectors of camera space.

The orientation of the camera, relative to world space, is the inverse of this transformation. And since the inverse of a rotation matrix is it's transpose, you have your issue.

The problem isn't with the matrix; the problem is with the difference between what you think the matrix says and what it actually says.