Skip to content

Instantly share code, notes, and snippets.

@awforsythe
Created August 30, 2020 23:48
Show Gist options
  • Save awforsythe/f132a0f67ad5608af98362e7d53b759b to your computer and use it in GitHub Desktop.
Save awforsythe/f132a0f67ad5608af98362e7d53b759b to your computer and use it in GitHub Desktop.
Quick Maya script that uses the OpenMaya API to make one joint hierarchy match the pose of another. Created so I could take a Unreal SkeletalMeshes authored in T-pose and rebind them in A-pose to exactly match the UE4 Mannequin from the AnimStarterPack.
"""
This is a quick Maya script designed to update a skeletal mesh (dst) to match
the joint transforms of a different skeletal mesh (src). This will only work
if both meshes have the same set of joints with identical names and joint
orientations.
My initial rationale for needing this script:
The UE4 Mannequin included in Epic's Animation Starter Pack is authored in
A-Pose, whereas the meshes in the Prototype Characters pack (from Ying Pei
Games on the UE4 Marketplace) are authored in T-Pose. The joint hierarchies
are otherwise identical, so rather than messing around with retargeting all
the ASP assets to the HeroTPP characters in-editor, I decided to just edit
the Prototype Characters so that their bind pose matches the Mannequin, so
I could then reimport them to use the Mannequin skeleton directly.
How I used this script to accomplish that:
1. Reference the A-pose mannequin into a new Z-up Maya scene, with a namespace
2. Import the T-pose character to be modified, from an FBX
3. Ensure that __src_root_name__ and __dst_root_name__ are set below
4. Run this script: the imported character should now match the reference
5. Delete the mannequin reference
6. Export the original skin weights- I used this script:
https://github.com/Animatic33/MayaPython/tree/master/agMayaJSONSkinExport
7. Unbind the character mesh, baking history so it stays in A-pose
8. Delete the old bindPose node
9. Re-bind the mesh to the skeleton
10. Restore the original skin weights
11. Clean up scene hierarchy, export to FBX, import into Unreal
You can probably skip all the bind pose stuff and just enable T0 as ref pose
when importing into Unreal, but this way makes sure everything's squeaky-clean
if we need to use the mesh in DCC apps (for authoring animations etc).
"""
import maya.api.OpenMaya as om
__src_root_name__ = 'SK_Mannequin:root'
__dst_root_name__ = 'SK_Player_Male|root'
def get_transform(name):
""" Returns an MFnTransform given a (full or partial) dag path string. """
sl = om.MSelectionList()
sl.add(name)
return om.MFnTransform(sl.getDagPath(0))
def visit_joints(top_transform, f):
""" Recurses over the given transform and all descendant joints. """
f(top_transform)
for i in xrange(top_transform.childCount()):
child_obj = top_transform.child(i)
if child_obj.apiType() == om.MFn.kJoint:
child_dagpath = om.MDagPath.getAPathTo(child_obj)
child_transform = om.MFnTransform(child_dagpath)
visit_joints(child_transform, f)
def update_dst_joint(src_joint_transform):
""" Finds the corresponding dst joint and aligns it with the src joint. """
name = src_joint_transform.name().rsplit(':', 1)[-1]
dst_joint_transform = get_transform(name)
joint_transformation = src_joint_transform.transformation()
dst_joint_transform.setTransformation(joint_transformation)
if __name__ == '__main__':
visit_joints(get_transform(__src_root_name__), find_dst_joint)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment