swiftmatrixsimdrotational-matricestransformation-matrix

Inverting the rotation along the X and the Y axis while keeping Z intact


I have a simd_float4x4 matrix that is the transformation matrix of a camera.

Inside that matrix, we have the tx, ty and tz that is the translation vector and 0x, 0y, 0z, 1x, 1y, 1z, 2x, 2y and 2z, that is the rotation matrix.

┌                  ┐
|  0x  1x  2x  tx  |
|  0y  1y  2y  ty  |
|  0z  1z  2z  tz  |
|  0   0   0   1   |
└                  ┘

When I test the rotation matrix I have on a 3D application, I see that the rotations along the X and the Y axis are inverted, while the rotation along Z is correct.

So, on axis X and Y, any rotation the real camera did clockwise is shown anticlockwise.

I need to invert those rotations.

Bear with me because my matrix algebra is rusty.

So, the rotation matrices for the axis are, as stated by the next picture of this SO answer

enter image description here

If I am on the right path, I need to multiply my rotation matrix by Rx and Ry, right?

If I want to invert the rotations in X and Y, my Rx and Ry will be equal to:

     ┌             ┐
     |  1   0   0  |
Rx = |  0  -1   0  |
     |  0   0  -1  |
     └             ┘

     ┌             ┐
     |  -1  0   0  |
Ry = |   0  1   0  |
     |   0  0  -1  |
     └             ┘

I can multiply Rx and Ry to obtain the final matrix I have to use:

    ┌              ┐
    |  -1   0   0  |
R = |   0  -1   0  |
    |   0   0   1  |
    └              ┘

So, all I have to do, is to multiply my rotation matrix by R to get the rotations along X and Y inverted, right?

Nope, the final result is the same... the only thing that happens is that the camera appears to have rotated in Y.

I am using this code

import simd

extension simd_float4x4 {

  var rotatedXY: simd_float4x4 {

    let c0 = SIMD3<Float>(-1.0, 0.0, 0.0)
    let c1 = SIMD3<Float>(0.0, -1.0, 0.0)
    let c2 = SIMD3<Float>(0.0,  0.0, 1.0)
    let inverse = simd_float3x3(c0,c1,c2)

    let cx0 = SIMD3<Float>(columns.0.x, columns.0.y, columns.0.z)
    let cx1 = SIMD3<Float>(columns.1.x, columns.1.y, columns.1.z)
    let cx2 = SIMD3<Float>(columns.2.x, columns.2.y, columns.2.z)
    let matrix = simd_float3x3(cx0,cx1,cx2)

    let multiplication = matrix * inverse

    var resultado = self

    resultado.columns.0.x = multiplication.columns.0.x
    resultado.columns.0.y = multiplication.columns.0.y
    resultado.columns.0.z = multiplication.columns.0.z

    resultado.columns.1.x = multiplication.columns.1.x
    resultado.columns.1.y = multiplication.columns.1.y
    resultado.columns.1.z = multiplication.columns.1.z

    resultado.columns.2.x = multiplication.columns.2.x
    resultado.columns.2.y = multiplication.columns.2.y
    resultado.columns.2.z = multiplication.columns.2.z

    return resultado
  }
}

What am I missing?


Solution

  • I realized that I had this line inverted.

    let multiplication = matrix * inverse
    

    the correct is

    let multiplication = inverse * matrix