通用结构
float4是一个float[4]的数组,主要对应simd的数据类型,存储的可以是vector4或者quaternion,可以代表平移,旋转或者缩放。
xform里面有 float4的t,q,s,就是simd版的transform信息。
AvatarConstant
1 | std::string AvatarBuilder::BuildAvatar(Avatar& avatar, const Unity::GameObject& go, bool doOptimizeTransformHierarchy, const HumanDescription& humanDescription, Options options) |
会创建AvatarConstant
,会用到下面这些结构体
1 | enum Bones |
mecanim::skeleton::Skeleton
是所有骨骼的父子关系信息,Axes目前不知道是什么,Axes中的Min、Max是绕着某个轴转的角度范围(角度制)
mecanim::skeleton::SkeletonPose
是对应于某个Skeleton的某一个动作的快照,存的是所有骨骼的transform信息(t,r,s)
AnimationClip是对应fbx中定义的一个动画take。
void ModelImporter::ImportMuscleClip(GameObject& rootGameObject, AnimationClip** clips, size_t size)把fbx中的一个AnimationClip中的所有的动画曲线,转换成Muscle Space中的动画曲线。
std::string GenerateMecanimClipsCurves(AnimationClip** clips, size_t size, ModelImporter::ClipAnimations const& clipsInfo, mecanim::animation::AvatarConstant const& avatarConstant, bool isHuman, HumanDescription const& humanDescription, Unity::GameObject& rootGameObject, AvatarBuilder::NamedTransforms const& namedTransform)这个函数是执行曲线转换的核心
人物的动画数据都是存在AnimationClip::m_FloatCurves
中,骨骼的动画信息只包含每个骨骼的旋转信息(x,y,z),而且不是每个骨骼都包含xyz,有的只有两项或者一项。这些旋转信息都被拆分成独立的float曲线存放。除了骨骼动画信息外,还保存了RootMotion的信息(T.xyz, Q.xyzw)和双手双脚的动画信息(T.xyz, Q.xyzw)。最后才是用户在动画中定义的曲线。
这些曲线的顺序是这样的,这个就是attribute的名字1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104"RootT.x"
"RootT.y"
"RootT.z"
"RootQ.x"
"RootQ.y"
"RootQ.z"
"RootQ.w"
"LeftFootT.x"
"LeftFootT.y"
"LeftFootT.z"
"LeftFootQ.x"
"LeftFootQ.y"
"LeftFootQ.z"
"LeftFootQ.w"
"RightFootT.x"
"RightFootT.y"
"RightFootT.z"
"RightFootQ.x"
"RightFootQ.y"
"RightFootQ.z"
"RightFootQ.w"
"LeftHandT.x"
"LeftHandT.y"
"LeftHandT.z"
"LeftHandQ.x"
"LeftHandQ.y"
"LeftHandQ.z"
"LeftHandQ.w"
"RightHandT.x"
"RightHandT.y"
"RightHandT.z"
"RightHandQ.x"
"RightHandQ.y"
"RightHandQ.z"
"RightHandQ.w"
"Spine Front-Back",
"Spine Left-Right",
"Spine Twist Left-Right",
"Chest Front-Back",
"Chest Left-Right",
"Chest Twist Left-Right",
"Neck Nod Down-Up",
"Neck Tilt Left-Right",
"Neck Turn Left-Right",
"Head Nod Down-Up",
"Head Tilt Left-Right",
"Head Turn Left-Right",
"Left Eye Down-Up",
"Left Eye In-Out",
"Right Eye Down-Up",
"Right Eye In-Out",
"Jaw Close",
"Jaw Left-Right",
"Left Upper Leg Front-Back",
"Left Upper Leg In-Out",
"Left Upper Leg Twist In-Out",
"Left Lower Leg Stretch",
"Left Lower Leg Twist In-Out",
"Left Foot Up-Down",
"Left Foot Twist In-Out",
"Left Toes Up-Down",
"Right Upper Leg Front-Back",
"Right Upper Leg In-Out",
"Right Upper Leg Twist In-Out",
"Right Lower Leg Stretch",
"Right Lower Leg Twist In-Out",
"Right Foot Up-Down",
"Right Foot Twist In-Out",
"Right Toes Up-Down",
"Left Shoulder Down-Up",
"Left Shoulder Front-Back",
"Left Arm Down-Up",
"Left Arm Front-Back",
"Left Arm Twist In-Out",
"Left Forearm Stretch",
"Left Forearm Twist In-Out",
"Left Hand Down-Up",
"Left Hand In-Out",
"Right Shoulder Down-Up",
"Right Shoulder Front-Back",
"Right Arm Down-Up",
"Right Arm Front-Back",
"Right Arm Twist In-Out",
"Right Forearm Stretch",
"Right Forearm Twist In-Out",
"Right Hand Down-Up",
"Right Hand In-Out"
// 左手的5 * 4 = 20个自由度
// 右手的5 * 4 = 20个自由度
// 最后是用户自己定义的float曲线
这些muscle曲线都经过Skeleton中定义的Axes转换到muscle space的(RegartFrom),然后运行的时候再从msucle space转换回来(RetargetTo)。转换的算法目前没有看懂。
优化措施,这个曲线会被分成三类StreamedClip (hermite曲线),DenseClip (线性的折线),ConstantClip (常数)。
AnimationClip
1 | struct GenericBinding |