Search code examples
pythonmatrix3dsmax

Change a left handed coordinate matrix to a right handed in python for 3ds max


I'm working to import transformation from a left coordinate system (unity/maya) to 3ds max, which is right handed from a file.

3ds Max uses a 3x4 matrix, but it's the same as a 4x4 matrix but with the last column removed (which does not really do anything so no data is lost)

The translation in the matrix is kind of easy, since i just have to swap the last row from [x y z] to [-x z y] when getting the original matrix, swapping the y value for the z value and setting the x to negative.

Is not as easy for the rotation though.

I kind of tried to do a workaround, by getting the quaternion of the matrix, changing it to euler, doing the same swap as stated previously and putting it as a quaternion again, and the rotation comes a bit off.

I was wondering if there is a sequence of matrix operations that can be done to the original matrix to make it ready to set for right-handed 3ds max coordinates, since the initial ones are left-handed.

I saw in some docs to set the z value as negative, but that did not really work.

Is there any good documentation about this or any place i can follow? every doc i look has different solutions and this begins to be confusing.


Solution

  • I fixed this by doing the following:

    1. Import the scene/models the way it is.
    2. If there isn't a root, create it and link all objects that don't have a parent to the root created.
    3. Rotate the root to apply that transform to everything until you have the desired result.

    If you are in 3ds Max, you can go to the maxscript listener and type: "$.transform". This will give you the transform of the object you are currently selecting, so select the root and write it on the console and you will get a transformation matrix that you need to apply.

    Now, you can either save this matrix on a file and apply it, or if you want to be more precise, everytime you are going to work with it, do the third step from above in a script to a dummy object and then you can just multiply it to any object in the scene. For example:

    root = Dummy()
    root.rotation = (quat 0 -0.707107 0.707107 0)
    root.scale = Point3 -1 -1 -1
    

    Every coordinate system is it's own thing, so you'll get different values. Now you just have to do the following to any object:

    object.transform *= root.transform
    

    That will give you the proper transform you need.