Tutorial: MetaHuman: DNA Calibration Deep Dive

This session is an overview of the MetaHuman DNA Calibration library that enables you to directly edit DNA files, which are the core of MetaHumans. We will highlight what can be achieved with the current library implementation, before showcasing how easily users can change a DNA file in a demonstration using Maya and the DNA Calibration library.

We will demonstrate both simple and more advanced use case scenarios, using multiple tools included in the DNA Calibration library, and employing rigging skills in order to make some modifications to the DNA file.

We will also show best practices for preparing and exporting the modified FBX files to Unreal Engine, detailing proper import settings, Skeletal Mesh setup, and applying animation to the newly imported character in the Level Sequencer.

https://dev.epicgames.com/community/learning/tutorials/EoPj/metahuman-dna-calibration-deep-dive

is there a way to get the code snippets mentioned in this talk?

Where can we get code snippets from the talk? Also, is it currently possible to a) Change the joint animation in behaviour layer? b) Use DNACalib with different topology than the metahuman one?

Those where posted 2 months ago in the DNA Calib GitHub repo GitHub - EpicGames/MetaHuman-DNA-Calibration

I am seeking your assistance. My English is not very good, and without subtitles, I find it difficult to deeply understand and learn from your videos. I hope you can upload subtitles generated by YouTube. If it’s convenient, sending me the video file directly would also be very helpful. I will generate subtitles locally and watch the video for learning purposes. Thank you very much!

Not sure that I missed something in the video but found that the example script doesn’t have a part that transform the joints according to the adjusted mesh.
So I inserted these snippets to the script, hope it helps.

def get_closest_vertex(mesh: str, pos: List[float]):
    pnt = om.MPoint(*pos)
    sel = om.MSelectionList()
    sel.add(mesh)
    mdagpath = om.MDagPath()
    sel.getDagPath(0, mdagpath)
    fn_mesh = om.MFnMesh(mdagpath)

    closest_pnt = om.MPoint()
    util = om.MScriptUtil()
    util.createFromInt(0)
    id_ptr = util.asIntPtr()
    fn_mesh.getClosestPoint(pnt, closest_pnt, om.MSpace.kWorld, id_ptr)
    id = om.MScriptUtil(id_ptr).asInt()

    vtx_ids = om.MIntArray()
    fn_mesh.getPolygonVertices(id, vtx_ids)

    vertex_distances = []
    for vtx_id in vtx_ids:
        vtxpnt = om.MPoint()
        fn_mesh.getPoint(vtx_id, vtxpnt, om.MSpace.kWorld)
        dist = vtxpnt.distanceTo(pnt)
        delta = om.MVector(pnt) - om.MVector(vtxpnt)
        vertex_distances.append([vtx_id, [delta.x, delta.y, delta.z], dist])

    return min(vertex_distances, key=lambda x: x[2])

# Collect current joint to vertex position deltas
mesh = dna.meshes.names[0]
reader = load_dna_reader(CHARACTER_DNA)
joints_to_vertices = []
for i in range(reader.getJointCount()):
    joint_name = reader.getJointName(i)
    pos = cmds.xform(joint_name, q=True, t=True, ws=True)
    vid, delta, _ = get_closest_vertex(mesh, pos)
    joints_to_vertices.append([joint_name, f"{mesh}.vtx[{vid}]", delta])


# Loaded data - end of 3rd step
##################################

##################################
# Modify rig in maya, 4th step
##################################

# Update joint positions
for jnt, vtx, delta in joints_to_vertices:
    vpos_as_vec = om.MVector(
        *mc.xform(vtx, q=True, t=True, ws=True)
    )
    delta_as_vec = om.MVector(*delta)
    jpos = vpos_as_vec + delta_as_vec
    mc.xform(jnt, t=[jpos.x, jpos.y, jpos.z], ws=True)