首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将非层次化的转换应用于层次化框架?

将非层次化的转换应用于层次化框架?
EN

Stack Overflow用户
提问于 2012-07-30 13:17:02
回答 1查看 1.6K关注 0票数 3

我使用Blender3D,但答案可能不是API-专属的。

我有一些矩阵需要分配给PoseBones。当没有骨层次结构(育儿)时,所产生的姿势看起来很好;如果有,则看起来很糟糕。

我在这里上传了一个存档,其中包含了被操纵的模型、文本动画导入程序和一个测试动画文件的混合示例:files.html

通过选择一个电枢并在"sba“文件上运行导入程序来导入动画。两种电枢都要这样做。

这就是我如何在真实的(复杂的)进口商中分配姿势:

代码语言:javascript
复制
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矩阵(对象空间)

我试着做这样的事:

代码语言:javascript
复制
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.4API中,这起作用就像一种魅力:

代码语言:javascript
复制
matrix_basis = ... # matrix from file
animation_matrix = armature.bones['mybone'].matrix['ARMATURESPACE'].copy() * matrix_basis
pose.bones[bonename].poseMatrix = animation_matrix

pose.update()

链接到搅拌机API参考:

17/bpy.types.BlendData.html#bpy.types.BlendData

17/bpy.types.PoseBone.html#bpy.types.PoseBone

EN

回答 1

Stack Overflow用户

发布于 2012-08-22 06:23:02

“目标空间”可能意味着相对于父母的骨骼。您可以通过乘以父转换矩阵的逆来将全局转换为局部。您还可能会发现,您希望通过所有父逆转换的级联来乘以:乘B1 *逆(B0)和B2 *(逆(B1)*逆(B0))。

下面是一些执行类似操作的示例代码(在Panda3D中,不是Blender,而是相同的一般想法)。我们从具有全局位置和旋转值的3根骨头开始,将它们放在一起,并将全局坐标转换为正确的局部矩阵。

代码语言:javascript
复制
    # 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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11722391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档