从Blender导出到OGL的正确骨骼数据是什么?
编辑(原帖如下):
我写了以下代码,可以导出网格、骨骼结构和动画。我能让一个简单的骨架动起来。但是,如果我尝试让多个骨头一起动,就会出现问题,手臂会在错误的方向上移动。
我的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://www.blender.org/development/release-logs/blender-240/how-armatures-work
非常感谢!
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上。
这个脚本可以在对象模式下运行。希望这对你有帮助。