从Blender导出到OGL的正确骨骼数据是什么?

28 投票
1 回答
2749 浏览
提问于 2025-04-16 18:20

编辑(原帖如下):

我写了以下代码,可以导出网格、骨骼结构和动画。我能让一个简单的骨架动起来。但是,如果我尝试让多个骨头一起动,就会出现问题,手臂会在错误的方向上移动。

我的C++代码在这里:http://kyuu.co.uk/so/main.cpp

我的Python导出代码在这里:http://kyuu.co.uk/so/test.py

有人能告诉我我哪里做错了吗?我觉得可能和Blender里的骨头旋转有关。我看到很多关于这个的帖子。

谢谢。

(原帖:)

我已经在这个问题上努力了一段时间,但还是搞不清楚我缺少了什么,所以希望有好心人能帮我 :3

好的,我在我的应用程序里有类似以下的代码:

class bone {
    bone * child;
    Eigen::Matrix4f local_bind_pose; // this i read from a file
    Eigen::Matrix4f final_skinning_matrix; // i then transform each vertex by this matrix

    // temporary variables
    Eigen::Matrix4f inv_bind_pose;
    Eigen::Matrix4f world_bind_pose;
}

也就是说,一个简单的骨骼层级。

我相信我可以通过以下方式计算出 inv_bind_pose

world_bind_pose = bone.parent.world_bind_pose * local_bind_pose
inv_bind_pose = world_bind_pose.inverse()

我知道 bind_pose 必须相对于父骨骼。

我知道Blender里是z轴向上,而我用的是y轴向上。

但是我无法从Blender导出这些信息。我使用的是2.56.3版本。

矩阵的旋转部分是 bone.matrix_local 吗?平移部分是 bone.tail() - bone.head() 吗?

那骨头的旋转又该怎么处理呢?这似乎会影响结果。

一些参考资料:

http://www.gamedev.net/topic/571044-skeletal-animation-bonespace

http://blenderartists.org/forum/showthread.php?209221-calculate-bone-location-rotation-from-fcurve-animation-data

http://www.blender.org/development/release-logs/blender-240/how-armatures-work

http://code.google.com/p/gamekit/source/browse/trunk/Engine/Loaders/Blender/gkSkeletonLoader.cpp?spec=svn482&r=482

非常感谢!

1 个回答

1

我们在使用Blender的骨骼功能时非常频繁。我觉得你可能会觉得这个代码片段很有用。

import gzip
import struct

import bpy

groups = [x.name for x in bpy.context.object.vertex_groups]
rig = bpy.context.object.parent

buf = bytearray()
buf.extend(struct.pack('ii', len(groups), 60))

for i in range(60):
    bpy.context.scene.frame_set(i)
    for name in groups:
        base = rig.pose.bones[name].bone.matrix_local.inverted()
        mat = rig.pose.bones[name].matrix @ base
        x, y, z = mat.to_translation()
        rw, rx, ry, rz = mat.to_quaternion()
        buf.extend(struct.pack('3f4x4f', x, y, z, rx, ry, rz, rw))

open('output.rig.gz', 'wb').write(gzip.compress(buf))

这个代码可以直接将Blender的骨骼导出到GPU上。

这里我们用到了它

这个脚本可以在对象模式下运行。希望这对你有帮助。

撰写回答