| 686 | } |
| 687 | |
| 688 | static void UpdatePoseTransforms(const dmRigDDF::Skeleton* skeleton, dmArray<BonePose>& pose) |
| 689 | { |
| 690 | uint32_t bone_count = pose.Size(); |
| 691 | for (uint32_t bi = 0; bi < bone_count; ++bi) |
| 692 | { |
| 693 | BonePose& bp = pose[bi]; |
| 694 | |
| 695 | if (bp.m_ParentIndex != INVALID_BONE_INDEX) |
| 696 | { |
| 697 | bp.m_World = dmTransform::Mul(pose[bp.m_ParentIndex].m_World, bp.m_Local); |
| 698 | } |
| 699 | else |
| 700 | { |
| 701 | // Apply the skeleton bone transform when the there is no parent. |
| 702 | const dmRigDDF::Bone* sk_bone = &skeleton->m_Bones[bi]; |
| 703 | // Separate the anscestor (everything "above" this joint hierarchy-wise) from the local transform of this joint. |
| 704 | const Matrix4 world_bind = dmTransform::ToMatrix4(sk_bone->m_World); |
| 705 | const Matrix4 local_bind = dmTransform::ToMatrix4(sk_bone->m_Local); |
| 706 | const Matrix4 ancestor = world_bind * dmVMath::Inverse(local_bind); |
| 707 | bp.m_World = dmTransform::ToTransform(ancestor * dmTransform::ToMatrix4(bp.m_Local)); |
| 708 | } |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | static void PoseToMatrix(const dmArray<BonePose>& pose, Matrix4* out_matrices) |
| 713 | { |