matrixopengllwjgljoml

How to rotateX or rotateZ view matrix around specified axis?


I would like to rotate view matrix (I supposed to think this represents camera position).

I already rotate view matrix about Y-axis by using Matrix4f#rotateY successfully.

However, about rotateX this requires the target position at (0,0,0) center of the world, I would like to rotate the view matrix around a specified position.

I tried to rotate the matrix like following:

targetCenter = Vector3f(x, y, z)

viewMatrix
    .translate(targetCenter)
    .rotateX(rotation)
    .translate(targetCenter.mul(-1.0f))

However, this make the rendered model twice. Is this the correct method to rotate view matrix around specified axis ?

EDIT

fun Matrix4f.orbitBy(modelCenter: Vector3f, angleY: Float, angleX: Float, focalLength: Float) {
    // Setup both camera's view matrices
    val modelCenterCp = Vector3f(modelCenter)
    val recenter = Matrix4f().translate(modelCenterCp.mul(-1.0f)) //not needed if world origin
    val rotation = Matrix4f()
            .rotateY(angleY)
            .rotateX(angleX)
    val moveBack = Matrix4f().translate(modelCenter) //not needed if world origin
    val transfer = moveBack.mul(rotation).mul(recenter) //order from right to left

    val eye = Vector3f(0f, modelCenter.y, -focalLength).mulProject(transfer)
    val up = Vector3f(0f, 1f, 0f)
    this.setLookAt(eye, modelCenter, up)
} 

Solution

  • It works in your example because I suppose your target equals the world origin. If you want to rotate around the world origin, you don't need the translation part. If it's around a point it will become mandatory.

    What I like to use when computing the view Matrix is to keep 3 values inside my camera:

    If you want to orbit around your target point you need to apply your rotation on your eye and upVector, once done you can recompute the viewMatrix using a mat4 lookAt(eye, center, up)

    void orbitBy(float yaw, vec3 rotationCenter) {
         mat4 recenter = translate(mat4(1.0), -rotationCenter); //not needed if world origin
         mat4 rotation = rotateY(mat4(1.0), yaw); //can be replaced by glm::eulerAngleZXY(yaw, pitch, roll) ...
         mat4 moveBack = translate(mat4(1.0, rotationCenter)); //not needed if world origin
         mat4 transfo = moveBack * rotation * recenter; //order from right to left
         m_eye = transfo * m_eye;
         m_up = transfo * m_up; 
         m_viewMatrix = lookAt(m_eye, m_center, m_up);
    }
    

    I prefer this approach cause it gives you simpler values which are very helpfull for debugging