Maya中的关节权重插值
在Maya中,如何计算一个面上某个点的联合权重值呢?比如我们有一个平面,想要计算在这个平面上某个随机点的插值权重。我知道Maya中的“复制皮肤权重”工具在进行这种插值时表现得很好,但我不太清楚背后的数学原理。
import maya.cmds as cmds
if __name__ == '__main__':
# Build two planes. One with no subdivs and one with 2.
plane = cmds.polyPlane(name="plane_GEO",
subdivisionsX=1,
subdivisionsY=1,
width=10.0,
height=10.0)
planeRef = cmds.polyPlane(name="plane_cn_GEO",
subdivisionsX=2,
subdivisionsY=2,
width=10.0,
height=10.0)
#Move vertices.
cmds.move(2, 0, 0, "%s.vtx[1]" % planeRef[0], relative=True)
cmds.move(2, 0, 0, "%s.vtx[4]" % planeRef[0], relative=True)
cmds.move(2, 0, 0, "%s.vtx[7]" % planeRef[0], relative=True)
cmds.move(0, 0, 2, "%s.vtx[3:5]" % planeRef[0], relative=True)
#Make joints.
cmds.select(clear=True)
jntA = cmds.joint(name="a_JNT", p=[5, 0, -5])
cmds.select(clear=True)
jntB = cmds.joint(name="b_JNT", p=[5, 0, 5])
cmds.select(clear=True)
jntC = cmds.joint(name="c_JNT", p=[-5, 0, 5])
cmds.select(clear=True)
jntD = cmds.joint(name="d_JNT", p=[-5, 0, -5])
cmds.select(clear=True)
#Bind joints.
skinA = cmds.skinCluster([jntA, jntB, jntC, jntD],
plane[0],
name='%s_SKNCLUST' % plane[0],
toSelectedBones=True,
skinMethod=1,
normalizeWeights=1)
skinB = cmds.skinCluster([jntA, jntB, jntC, jntD],
planeRef[0],
name='%s_SKNCLUST' % planeRef[0],
toSelectedBones=True,
skinMethod=1,
normalizeWeights=1)
#Copy skin weight for reference of what joint weight is supposed to be.
cmds.copySkinWeights(sourceSkin=skinA[0],
destinationSkin=skinB[0],
noMirror=True,
surfaceAssociation="closestPoint",
influenceAssociation="name")
#Hide it.
cmds.setAttr(planeRef[0] + ".visibility", 0)
#Make a locator at a position.
loc = cmds.spaceLocator(name="anno_LOC")
cmds.move(2, 0, 2, loc[0])
#Make an annotation.
ano = cmds.annotate(loc[0],
tx="What is the joint weight values at this point?",
p=[2, 5, 2])
anoTrans = cmds.listRelatives(ano, parent=True)
cmds.rename(anoTrans, "weight_ANNOTATE")
这是一个简单的场景,用来展示我所说的内容。希望能帮助你理解这个概念。
谢谢你的帮助。
1 个回答
1
谢谢你,joojaa!
转换后的Python函数:
import maya.OpenMaya as OpenMaya
def barycentricInterp(vecA, vecB, vecC, vecP):
'''
Calculates barycentricInterpolation of a point in a triangle.
:param vecA - OpenMaya.MVector of a vertex point.
:param vecB - OpenMaya.MVector of a vertex point.
:param vecC - OpenMaya.MVector of a vertex point.
:param vecP - OpenMaya.MVector of a point to be interpolated.
Returns list of 3 floats representing weight values per each point.
'''
v0 = vecB - vecA
v1 = vecC - vecA
v2 = vecP - vecA
d00 = v0 * v0
d01 = v0 * v1
d11 = v1 * v1
d20 = v2 * v0
d21 = v2 * v1
denom = d00 * d11 - d01 * d01
v = (d11 * d20 - d01 * d21) / denom
w = (d00 * d21 - d01 * d20) / denom
u = 1.0 - v - w
return [u, v, w]
插值的计算方式和Maya中的copySkinWeights命令完全一样。