1. 骨骼(skeleton)由关节(joint)构成,是一种树结构,但在内存中是以数组形式存储。
1)关节:
struct Joint
{
Matrix4x3 m_invBindPose; // 该关节点绑定的蒙皮网格顶点时对应的绑定姿势的逆矩阵
const char* m_name; //关节名称
U8 m_iParent; //父索引,或0xFF代表根节点
};
2)骨骼:
struct Skeleton
{
U32 m_jointCount; //关节数目
Joint* m_aJoint; //关节数组
}
2. 姿势(描述相对的姿态位置)
动画中一般以T-pose为绑定姿势(即初始姿态形式,也可以理解为初始姿态空间)。
1)局部姿势:子节点相对于父节点的姿态位置,存储为SQT格式(scale、quaternion、translation)。一般认为同步缩放。
struct JointPose // 4+4 满足内存对齐
{
Quaternion m_rot; // Q
Vector3 m_trans; // T
F32 m_scale; // S(统一缩放)
};
struct JointPose // 4+4+4 满足内存对齐
{
Quaternion m_rot; // Q
Vector4 m_trans; // T
Vector4 m_scale; // S(非统一缩放)
};
struct SkeletonPose
{
Skeleton* m_pSkeleton; // 骨骼+关节数量
JointPose* m_aLocalPose; // 多个局部关节姿势,数组大小与关节数量保持一致
};
2)全局姿势:由于每个子节点的SQT矩阵都是相对于父节点空间的,因此要将子节点的SQT矩阵转换为模型空间或者世界空间矩阵,需要逐层递归计算至根节点。
例如:第j层子节点递归至根节点(定义p(j)代表j节点的父节点),有P(j->M)=P(j->p(j))*P(p(j)->p(p(j))) ....
struct SkeletonPose
{
Skeleton* m_pSkeleton; // 骨骼+关节数量
JointPose* m_aLocalPose; // 多个局部关节姿势,数组大小与关节数量保持一致
Matrix44* m_aGlobalPose; // 多个全局关节姿势
}
原文:https://www.cnblogs.com/mocki/p/14496312.html