我用Blender3D,但答案可能并不API排他性的。
我有一些矩阵我需要分配给PoseBones。 得到的姿态看起来很好的时候没有骨骼层次(养育)和搞砸了的时候有。
我上传的着装模式的样本混合,文字动画进口商和测试的动画文件的存档位置: http://www.2shared.com/file/5qUjmnIs/sample_files.html
通过选择电枢和运行的“公会”文件导入进口动画。 这样做对两个电枢。
这就是我给你的姿态在现实(复)进口商:
matrix_bases = ... # matrix from file
animation_matrix = matrix_basis * pose.bones['mybone'].matrix.copy()
pose.bones[bonename].matrix = animation_matrix
如果我去到编辑模式,选择所有的骨头,然后按Alt + P键来撤消育儿,姿势看起来好起来的。
API文档说,PoseBone.matrix在“对象空间”,但它似乎很清楚,我从这些测试,他们是相对父骨骼。
约束和驱动程序后,最终4x4矩阵施加( 对象空间)
我试图做这样的事情:
matrix_basis = ... # matrix from file
animation_matrix = matrix_basis * (pose.bones['mybone'].matrix.copy() * pose.bones[bonename].bone.parent.matrix_local.copy().inverted())
pose.bones[bonename].matrix = animation_matrix
但它看起来更糟。 试行的操作顺序,没有运气所有。
为了记录在案,老2.4 API在这工作就像一个魅力:
matrix_basis = ... # matrix from file
animation_matrix = armature.bones['mybone'].matrix['ARMATURESPACE'].copy() * matrix_basis
pose.bones[bonename].poseMatrix = animation_matrix
pose.update()
Blender链接到API参考:
http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.BlendData.html#bpy.types.BlendData
http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.PoseBone.html#bpy.types.PoseBone
“对象空间”,可能也意味着相对于父骨。 您可以通过乘以时间从全局转换为本地父的逆变换的矩阵。 你也可能会发现,你会希望所有家长逆串联乘以转换:乘B1 *逆(B0)和B2 *(逆(B1)*逆(B0))。
下面是一些示例代码,做类似的事情(在Panda3D中,没有搅拌机,但同样的总体思路)。 我们有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)