Docs

MetaHuman DNA

Reading a MetaHuman DNA by pin name from the expression: joints, meshes, blend shapes, controls and skin weights.

Part of the Wrangle reference. Everything on this page goes in the node's Code field, and runs once per element of the current Run Over mode.

Syntax What it does Example
dnacount (mesh) dnacount("Pin", "what", mesh) A per-mesh count for kind "what" - vertices, normals, uvs, layouts, faces, skinweights, maxinfluences, blendshapetargets, meshregions - at the named mesh index. Naming a whole-DNA kind here is a compile error naming the fix. float n = dnacount("Head", "vertices", 0)
dnajoint("Pin", "Name") Compile-time joint-name lookup: the index of the named joint on this DNA, or a compile error listing every joint name present. Case sensitive. float j = dnajoint("Head", "head")
dnamesh("Pin", "Name") Compile-time mesh-name lookup, same rule as dnajoint. float m = dnamesh("Head", "head_lod0")
dnablendshape("Pin", "Name") Compile-time blend shape channel-name lookup, same rule as dnajoint. float c = dnablendshape("Head", "bs_a")
dnacontrol("Pin", "Name") Compile-time raw control-name lookup, same rule as dnajoint. float c = dnacontrol("Head", "raw_a")
dnaguicontrol("Pin", "Name") Compile-time GUI control-name lookup, same rule as dnajoint. float c = dnaguicontrol("Head", "gui_a")
dnaanimatedmap("Pin", "Name") Compile-time animated map-name lookup, same rule as dnajoint. float a = dnaanimatedmap("Head", "am_a")
dnajointparent("Pin", j) Parent joint index of joint j. Out-of-range j returns 0 and is counted. float p = dnajointparent("Head", dnajoint("Head", "head"))
dnajointpos("Pin", j) Neutral (bind) translation of joint j, as a vector. Out-of-range j returns the zero vector and is counted. vector t = dnajointpos("Head", 2)
dnajointrot("Pin", j) Neutral (bind) rotation of joint j, as a vector of Euler degrees. Out-of-range j returns the zero vector and is counted. vector r = dnajointrot("Head", 2)
dnavertex("Pin", "Mesh", i) Vertex position i of the named mesh, as a vector. Out-of-range mesh or vertex index returns the zero vector and is counted. vector p = dnavertex("Head", "head_lod0", 0)
dnanormal("Pin", "Mesh", i) Vertex normal i of the named mesh, as a vector - same guard convention as dnavertex. vector n = dnanormal("Head", "head_lod0", 0)
dnauv("Pin", "Mesh", i) Texture coordinate i of the named mesh, as vec3(u, v, 0). Out-of-range returns the zero vector and is counted. vector t = dnauv("Head", "head_lod0", 0)
dnabschannel("Pin", "Mesh", t) The blend shape channel index that blend shape target t of the named mesh drives. Out-of-range mesh or target returns 0 and is counted. float c = dnabschannel("Head", "head_lod0", 0)
dnadeltacount("Pin", "Mesh", t) Delta count of blend shape target t on the named mesh. Same guard convention as dnabschannel. float n = dnadeltacount("Head", "head_lod0", 0)
dnadelta("Pin", "Mesh", t, k) Delta k of blend shape target t on the named mesh, as a vector. Out-of-range mesh, target or delta index returns the zero vector and is counted. vector d = dnadelta("Head", "head_lod0", 0, 0)
dnadeltavertex("Pin", "Mesh", t, k) The vertex index delta k of blend shape target t moves, on the named mesh. Same guard convention as dnadelta. float v = dnadeltavertex("Head", "head_lod0", 0, 0)
dnaskinweight("Pin", "Mesh", v, j) The skin weight joint j contributes to vertex v of the named mesh, or 0 when joint j does not influence that vertex - absence is a legitimate answer, not counted (the delta()-family convention). An out-of-range mesh or vertex is counted. float w = dnaskinweight("Head", "head_lod0", 0, dnajoint("Head", "head"))
dnaskinweights("Pin", "Mesh", v) Every skin weight influencing vertex v of the named mesh, as a fresh float[] - index-parallel with dnaskinjoints(). Out-of-range mesh or vertex returns an empty array (handle 0) and is counted. float[] w = dnaskinweights("Head", "head_lod0", 0)
dnaskinjoints("Pin", "Mesh", v) The joint index for each entry of dnaskinweights() at the same vertex, as a fresh float[] cast from the DNA's own integer joint indices. Same guard convention as dnaskinweights. float[] j = dnaskinjoints("Head", "head_lod0", 0)
dnaposescale("Pin", p) Scale factor of RBF pose p. Out-of-range p returns 0 and is counted. float s = dnaposescale("Head", 0)

DNA parameter

Add a Parameter of type DNA and it becomes an input DNA pin named as the param - the same "name pins by parameter" rule Delta/WeightMap/Mesh already follow. No bare-read form - read it through the dna*() functions below, by pin name in quotes (case sensitive, unlike bone names elsewhere in this language). Missing/unconnected pin is a compile error: No DNA input named X is connected.

Parameters list, type DNA, name "Head"

dnacount("Pin", "what")

A whole-DNA count for kind "what" - lods, joints, meshes, blendshapechannels, rawcontrols, guicontrols, animatedmaps, mlcontrols, neuralnetworks, jointgroups, psds, jointrows, jointcolumns, meshblendshapemappings, rbfsolvers, rbfposes, rbfposecontrols, twists, swings. Unknown kind is a compile error listing every kind name. Naming a per-mesh kind here (see the next row) is a compile error naming the fix.

wmap("Weights") = dnacount("Head", "joints")

Raw space

Every dna*() function returns the value exactly as the DNA stores it - the DNA's own coordinate system, translation unit and rotation unit, read straight off the file. It is not converted to the app's UE space. For a pin buffer that is Maya/Source ({Left, Up, Front}, cm, degrees), confirm with the descriptor. Convert it with the DNA coordinate-space helpers on the C++ side, or apply the swizzle yourself in the expression.