在Blender 2.6 API中,PoseBone用于动画骨骼。 PoseBone.matrix是一种方法。 API称PoseBone.matrix位于“对象空间”。
PoseBone.matrix完全不是我见过的。 我仍然无法让我的动画导入器工作。 和PoseBone.matrix有什么关系?在Blender 2.4 API中有两个矩阵:一个在局部空间,一个在电枢空间。
但新的PoseBone.matrix既不是!它不是一个局部矩阵:
位置不是本地的,而是全球性的。
但轮换
<Euler (x=1.5708, y=-0.7854, z=-0.0000), order='XYZ'>
是
那么API说PoseBone.matrix在这个“对象空间”是什么?
我正在尝试将我的电枢空间矩阵分配给层次结构的电枢,但我无法将它们弄好。
我尝试分解我的矩阵,撤消父旋转然后再重新组合矩阵,然后再将其设置为“PoseBone.matrix”。 它只是不起作用。
oldmatrix = myMatrix
loc, rot, scale = oldmatrix.decompose()
#rot = rot * pose.bones[bonename].parent.rotation_quaternion.conjugated()
for i in pose.bones[bonename].parent_recursive:
rot = rot * i.conjugated()
newmatrix = rot.to_matrix().to_4x4()
newmatrix[0][3] = loc.x
newmatrix[1][3] = loc.y
newmatrix[2][3] = loc.z
pose.bones[bonename].matrix = newmatrix
答案 0 :(得分:1)
修改强>: 我找到了将这些对象空间变换转换为骨骼局部空间的解决方案。
简而言之 - 这是一个完成任务的代码片段:
poseBone = C.object.pose.bones[2] # <----- set your bone here
# poseBone.matrix is in object space - we need to convert it to local space
if poseBone.parent is not None:
parentRefPoseMtx = poseBone.parent.bone.matrix_local
boneRefPoseMtx = poseBone.bone.matrix_local
parentPoseMtx = poseBone.parent.matrix
bonePoseMtx = poseBone.matrix
boneLocMtx = ( parentRefPoseMtx.inverted() * boneRefPoseMtx ).inverted() * ( parentPoseMtx.inverted() * bonePoseMtx )
else:
boneRefPoseMtx = poseBone.bone.matrix_local
bonePoseMtx = poseBone.matrix
boneLocMtx = boneRefPoseMtx.inverted() * bonePoseMtx
loc, rot, scale = boneLocMtx.decompose()
我的老问题:
您找到了解决方案了吗? 我正在处理完全相同的问题。
对象空间矩阵应该是相对于父对象空间矩阵表示的骨骼局部空间矩阵,所以:
boneOS = parentOS * boneLS
但正如您所注意到的那样 - 它没有提供正确的解决方案。骨骼仍然偏移。 我想到的一件事是,它被其余的姿势变换所抵消,所以我尝试将它回滚,但这也不起作用,但也许我使用的方程是错误的。
以下是我尝试计算姿势骨骼的局部空间变换的方法(让我们假设骨骼1是我感兴趣的骨骼,骨骼0是其父骨骼,而0则没有父骨骼):
boneOS = C.object.pose.bones[2].matrix
parentBoneOS = C.object.pose.bones[2].parent.matrix
boneRP = C.object.pose.bones[2].bone.matrix_local # rest pose matrix in bone local space
parentBoneRP = C.object.pose.bones[1].bone.matrix_local # parent bone's rest pose matrix in bone local space
boneLS = ( parentBoneRP * boneRP ).inverted() * parentOS.inverted() * boneOS
答案 1 :(得分:0)
矩阵位于对象空间中,它的行为应该与您对代码的期望相同。发生的事情是在更改矩阵后骨骼的矩阵没有立即更新。到目前为止,我已经找到了一个黑客解决方案,用
更新每个骨骼之后的整个场景bpy.context.scene.update()