“对象空间”可能确实意味着相对于父骨骼。您可以通过乘以父变换矩阵的逆矩阵来从全局转换为局部。您可能还会发现您需要乘以所有父级逆变换的串联:乘以 B1 * inverse(B0) 和 B2 * (inverse(B1) * inverse(B0))。
下面是一些执行类似操作的示例代码(在 Panda3D 中,不是 Blender,但总体思路相同)。我们从具有全局位置和旋转值的 3 个骨骼开始,将它们放在一起,并将全局坐标转换为正确的局部矩阵。
# Load three boxes ('bones'), give them global position and rotation
# each is 3 units long, at a 30 degree angle.
self.bone1=loader.loadModel("box.egg")
self.bone1.reparentTo(render)
self.bone2=loader.loadModel("box.egg")
self.bone2.reparentTo(self.bone1)
self.bone3=loader.loadModel("box.egg")
self.bone3.reparentTo(self.bone2)
'''
equivalent code, in local coordinates
self.bone1.setPos(0,0,0)
self.bone1.setHpr(0,0,30)
self.bone2.setPos(0,0,3)
self.bone2.setHpr(0,0,30)
self.bone3.setPos(0,0,3)
self.bone3.setHpr(0,0,30)
'''
# give each a global rotation value
R1=Mat4()
R1.setRotateMat(30,Vec3(0,1,0))
R2=Mat4()
R2.setRotateMat(60,Vec3(0,1,0))
R3=Mat4()
R3.setRotateMat(90,Vec3(0,1,0))
# set global translation values
T1=Mat4()
# position of bone 2 in global coords
T2 = Mat4.translateMat(1.271,0,2.606)
# position of bone 3 in global coords
T3 = Mat4.translateMat(3.782,0,4.036)
# set the matrix for bone 1
M1 = R1 * T1
self.bone1.setMat(M1)
# get inverse of matrix of parent
I1 = Mat4()
I1.invertFrom (M1)
# multiply bone2 matrix times inverse of parent
M2 = R2 * T2
M2 = M2 * I1
self.bone2.setMat(M2)
# get inverse of parent for next bone
I2 = Mat4()
I2.invertFrom(M2)
M3 = R3 * T3
# notice that M3 * I2 isn't enough - needs to be M3 * (I1 * I2)
M3 = M3 * (I1 * I2)
self.bone3.setMat(M3)