Y-Up to Z-Up (maya to in-game) via Custom Exporter (pymel)

Hey all,

I’m writing a custom exporter (in python) to get some locator/mesh data out of Maya and into JSON.

So I’m tripping over converting from the Maya Y-up space to the in-game Z-up space (we’re using Gamebryo, which uses Max-like space). It’s one of those cases where it’s like yes, I know what needs to be done, I’m just stumbling over the best way to do it.

There’s this: http://blog.duber.cz/3ds-max/the-transformation-matrix-is-useful-when-understood which is doing the same thing, just from the other direction.

This is a fairly common thing – I’m wondering what others have done to handle this.

thx~

-abm

We ran into a case like that, and in the end, the programmers just rotated the top-node of the assets, in-game. There were gotchas, I’m sure (one was to omit weapons and props that are parented to in-game stuff, as they’ll be double-rotated). I think they spent a lot of time trying to actually convert the exported assets to z-space, but went with the top-node rotate fix in the end. (this was all for character related art)

The ‘world node’ solution is probably the most common thing I’ve seen too. The spatial transformation part is easy, it’s just a matrix multiply – but if you have to worry about things like tangent space windings or animated hierarchies it gets irritating really quickly because of the negative scale. So, people default to the cheapo ‘move me into the world’ solution instead.

These two funcs give you max-to-maya and maya-to-max matrices as API matrices, if it helps:



def APIMatrix ( valList ):
    mat = OpenMaya.MMatrix()
    OpenMaya.MScriptUtil.createMatrixFromList( valList, mat )
    return mat

def maya_to_max( scale=1 ):
    '''
    Returns the maya to max transform an OpenMaya.mMatrix (with the supplied scale factor to handle unit conversion)
    '''
    x = [1, 0, 0, 0]
    y = [0, 0, 1, 0]
    z = [0, -1, 0, 0]
    w = [0, 0, 0, 0]
    m2m = APIMatrix( x + y + z + w )
    m2m *= scale
    return m2m

def max_to_maya( scale=1 ):
    '''
    Returns the maya to max transform an OpenMaya.mMatrix (with the supplied scale factor to handle unit conversion)
    '''
    x = [ 1.0, 0.0, 0.0, 0.0 ]
    y = [ 0.0, 0.0, -1.0, 0.0 ]
    z = [ 0.0, 1.0, 0.0, 0.0 ]
    w = [ 0.0, 0.0, 0.0, 1.0 ]

    m2m = APIMatrix( x + y + z + w )
    m2m *= scale
    return m2m




If you don’t care about hierarchy, tangent spaces, etc. you can just iterate over the worldspace vertices and vert normals of your mesh, turning them into MPoints and multiplying them agains the matrix for the direction you’re going. Worldspace matrices can be done the same way. Other stuff, though, like hierarchies, tanget frames, etc… not so easy.

Hah Theo, I have the exact same functions. I just called them “D3D_to_Max” and “Max_to_D3D”. :wink:

SamiV.

Ah, that’s exactly what I had in mind, but it hadn’t quite crystallized yet.

Right on.

Thanks, guys.

If it’s OK with your bosses, this would be a fun thing to put on the TAO wiki as a recipe, it’s a common problem