BabylonJS / Exporters

Exporters for Babylon.js and gltf file formats
Other
610 stars 314 forks source link

Maya skeletal animation export breaks when model is posed. #737

Open Drigax opened 4 years ago

Drigax commented 4 years ago

When exporting a scene that includes a skeletally animated model, if the scene is exported with the playhead set to a frame where the model is deformed, the exported model appears skinned using the rest pose skeleton rigged to the deformed mesh, or the deformed skeleton rigged to the rest pose mesh:

Exported from Bind pose frame (Frame -10): image

image

Exported from Frame 80: image

image

Testing scene can be found here: https://www.dropbox.com/s/ahr0m7jeam8kobc/Exporters_737.zip?dl=0

Drigax commented 4 years ago

This bug took almost as much focus as a feature, mainly due to the implementation complexity. Currently, when exporting a skinned mesh, the mesh data is exported posed:

For example, the timeline was scrubbed to frame 57, and the alien scene was exported as so when skeleton deformation is disabled: image

Where the pose and skeleton information is baked into the mesh data.

This is circumventable by traversing the mesh hierarchy and using a child MFnMesh to the current one in scene. I believe that Maya stores intermediate mesh calculations in scene as children internally, only visible to the API. when we use this child mesh data instead of the parent, we get: image

When skeleton deformation is disabled: image

A marked improvement, as we're now properly exporting the undeformed mesh data, but something seems off with the skinning information.

If one was to see this animate, it would suggest that the weighting and bone indices are correct, the mesh appears properly rigged. My current suspicion is that the bone-to-world matrices are incorrect, I believe that our skeleton is exported using bone-to-world matrices of the posed mesh, and with node coordinates of the original mesh as well, causing the skeleton to be doubly deformed, as the skinning is resolved using the bone transfrom, and the bone to world matrices.

I'll have to look closer as to why exactly this is so.

Drigax commented 4 years ago

This continues to be a difficult problem to solve. I've found that the only noticeable difference between frame exports are the initial position of the joint transforms. The API seems nebulous regarding retrieving the rest positions of the skeleton transforms. My current efforts attempt to retreive this via our retrieved MFnDagNode for each transform in the skeleton, but MFnDagNode.MFnTransformMatrix.getRestPosition() doesn't yield any meaningful information. I've contacted Maya regarding how to properly use the API to retrieve this information.

deltakosh commented 4 years ago

Any update? Is it done or still stalled?

Drigax commented 3 years ago

This work is still stalled, we should reach out to Maya again regarding how to use the Maya API to retrieve node rest pose information. Currently we retrieve the Local-space transform of nodes in scene and calculate skinning binding matrices using the current transform at the frame export is started from, causing inconsistency in exported scenes, especially if export is started after an edit to a particular frame, or during animation playback.

pandaGaume commented 2 years ago

We continue to have issues using skin and animation. The complexity of the code and the lack of documentation make the thing difficult to track. We may first retro engeneering the code against the Maya way of work before trying to apply new strategy of export. Therefore, complexity has been introduced when moving the exporter from Babylon only to GLTF. We may first get back to a Babylon JS workable version ( which is the only one it survive an official Autodesk GLTF exporter).

pandaGaume commented 2 years ago

I took a closer look and the behavior is because we needed to hold the morph target at this time. The side effect was that with this scene with multiple skins, the reference was taken on different meshes. Thanks to previous PR, it's not necessary to keep the morph target anymore (which is the best practice for Autodesk) Deleting the morph targets solved the problem. This is now an edge effect and spend more time on it will be not valuable because we have a clear procedure to avoid it. @bghgary do we keep this open ?