适用于非分层变换,以分层骨架? [英] apply non-hierarchial transforms to hierarchial skeleton?

查看:273
本文介绍了适用于非分层变换,以分层骨架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Blender3D,但答案可能并不API独占。

I use Blender3D, but the answer might not API-exclusive.

我有一些矩阵我需要分配到PoseBones。由此产生的姿势看起来不错时,有没有骨骼层次(养育)和搞砸了的时候有。

I have some matrices I need to assign to PoseBones. The resulting pose looks fine when there is no bone hierarchy (parenting) and messed up when there is.

我已经上传样本混合的被操纵模型,文字动画进口商这里测试动画文件存档: http://www.2shared.com/file/5qUjmnIs/sample_files.html
通过选择电枢和运行SBA文件中的进口商导入动画。 执行此操作为电枢。

I've uploaded an archive with sample blend of the rigged models, text animation importer and a test animation file here: http://www.2shared.com/file/5qUjmnIs/sample_files.html
Import the animation by selecting an Armature and running the importer on "sba" file. Do this for both Armatures.

这是我在现实(复)进口商指定的姿势:

This is how I assign the poses in the real (complex) importer:

matrix_bases = ... # matrix from file
animation_matrix = matrix_basis * pose.bones['mybone'].matrix.copy()
pose.bones[bonename].matrix = animation_matrix

如果我去到编辑模式,选择所有的骨骼和preSS Alt键+ P撤消育儿,姿势又看起来很好。

If I go to edit mode, select all bones and press Alt+P to undo parenting, the Pose looks fine again.

API文档说,PoseBone.matrix在对象空间,但它似乎很清楚,我从这些测试,它们是相对于父骨骼。

The API documentation says the PoseBone.matrix is in "object space", but it seems clear to me from these tests that they are relative to parent bones.

最后4x4矩阵约束和驱动程序应用后(对象   空间)

Final 4x4 matrix after constraints and drivers are applied (object space)

我试图做这样的事情:

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

但它看起来更糟。尝试了操作顺序,没有运气了所有。

But it looks worse. Experimented with order of operations, no luck with all.

有关的记录,在旧的2.4 API这个工作就像一个魅力:

For the record, in the old 2.4 API this worked like a charm:

matrix_basis = ... # matrix from file
animation_matrix = armature.bones['mybone'].matrix['ARMATURESPACE'].copy() * matrix_basis
pose.bones[bonename].poseMatrix = animation_matrix

pose.update()

链接到搅拌机API参考:

Link to Blender API ref:

<一个href="http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.BlendData.html#bpy.types.BlendData" rel="nofollow">http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.BlendData.html#bpy.types.BlendData

<一个href="http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.PoseBone.html#bpy.types.PoseBone" rel="nofollow">http://www.blender.org/documentation/blender_python_api_2_63_17/bpy.types.PoseBone.html#bpy.types.PoseBone

推荐答案

对象空间可能并不意味着相对于父骨骼。你可以乘倍母公司的倒数全球转换为本地变换的矩阵。您还可能会发现,你会希望所有家长逆的串联繁殖转变:乘B1 *逆(B0)和B2 *(逆(B1)*逆(B0))

'object space' probably does mean relative to the parent bone. You can convert from global to local by multiplying times the inverse of the parent transform's matrix. You may also find that you'll want to multiply by the concatenation of all parent inverse transforms: multiply B1 * inverse(B0), and B2 * (inverse(B1) * inverse(B0)).

下面是一些例子code,做类似的东西(在Panda3D中,没有搅拌机,但同样的总体思路)。我们有3个骨头全球位置和旋转值,父他们开始在一起,并将其转换全球坐标到正确的地方的矩阵。

Here's some example code that does something similar (in Panda3D, not Blender, but same general idea). We start off with 3 bones with global position and rotation values, parent them together, and convert the global coordinates into the correct local matrices.

    # 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)

这篇关于适用于非分层变换,以分层骨架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆