【问题标题】:Calculating bind pose/skinning matrix from world space bone matrices从世界空间骨骼矩阵计算绑定姿势/蒙皮矩阵
【发布时间】:2015-04-03 22:54:36
【问题描述】:

目前我将所有骨骼存储在世界空间中并直接从二进制文件中加载它们。

我通过放置一个“箭头对象”来检查这个骨架,其中矩阵bone_mat 为“modelmatrix”。按预期工作。

Variable explanations:

 1. bone_mat        = world_space bone matrix (loaded from file)
 2. bind_pose_mat   = relative transformation from parent bone to current bone
 3. skinning_mat    = final joint transformation matrix

下一步是计算绑定姿势矩阵。与其父级的相对骨骼矩阵。

我是这样做的:

    /* bone mat * inverse(parent bone mat) */
    mesh->anim_data.skeleton[i].bind_pose_mat = 
urdMat4MulMat4( mesh->anim_data.skeleton[i].bone_mat, urdMat4Inverse(parent_bone->bone_mat) );

我通过再次进入世界空间来检查这个矩阵,如下所示:

    world_space_mat = 
urdMat4MulMat4( mesh->anim_data.skeleton[i].bind_pose_mat, parent_bone->bone_mat);

这会产生与 bone_mat 相同的矩阵。

根骨骼存储在世界空间中,因为它们与任何父级都不相关

root_bone.bind_pose_mat = bone_mat

所以现在我在本地空间,虽然我需要做的只是

/* interpolated vertex = base_vertex * bones[bone_index].bind_pose_mat */ 
mesh->interpolated[i].vertex = urdMat4MulVec3(skeleton[bone_index].bind_pose_mat , mesh->base[i].vertex);

这会导致网格变形。

编辑:经过一番思考,看起来我不在本地空间中,而是在相对空间中(bind_pose 当前是其父级的相对矩阵)。

但我坚持理论。

【问题讨论】:

    标签: c animation math vertex skinning


    【解决方案1】:

    好的,看来我已经成功了。

    数学方程是(简化的):

    v' = SUM { w * m * v }
    

    在哪里

    1. w 是权重(目前所有骨骼的权重为 1.0)
    2. m是世界空间骨骼矩阵(动画骨骼)
    3. v是绑定姿势的相对顶点位置
    inv_bone_mat = the inverted world space bone matrix
    bone_mat = world space bone matrix
    

    计算v:

    vec3 v_relative = bind_bones[bone_index].inv_bone_mat * vertex_object_space
    

    现在只需要:

    vec3 skinned_vertex = frame[current_frame].anim_bones[bone_index].bone_mat * v_relative
    

    ofc 这可以通过多个骨骼/重量影响进行扩展

    我希望这对未来的读者有所帮助。

    【讨论】:

      猜你喜欢
      • 2015-06-16
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 2019-08-12
      • 2019-05-21
      • 2011-02-28
      • 1970-01-01
      相关资源
      最近更新 更多