5

在 Blender 2.6 API 中,PoseBone 用于动画骨骼。PoseBone.matrix 是一种方法。API 说 PoseBone.matrix 在“对象空间”中。

http://www.blender.org/documentation/blender_python_api_2_63_5/bpy.types.PoseBone.html#bpy.types.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 
4

2 回答 2

2

编辑:我找到了将这些对象空间变换转换为骨骼局部空间的解决方案。

长话短说 - 这是完成该任务的代码片段:

    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
于 2013-05-28T21:30:53.077 回答
0

该矩阵位于对象空间中,它的行为应该与您对代码的期望一样。发生的事情是骨骼的矩阵在更改矩阵后没有立即更新。到目前为止,我已经找到了一个 hack 解决方案,可以在每块骨头之后更新整个场景

bpy.context.scene.update()
于 2013-04-13T11:51:59.547 回答