1// tSkeleton.cpp 
2// 
3// This file implements scene skeletons as a hierarchy of joints and poses that, well, pose a skeleton. 
4// 
5// Copyright (c) 2006, 2017 Tristan Grimmer. 
6// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
7// granted, provided that the above copyright notice and this permission notice appear in all copies. 
8// 
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
10// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
11// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
12// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
13// PERFORMANCE OF THIS SOFTWARE. 
14 
15#include <Math/tVector3.h> 
16#include <Math/tQuaternion.h> 
17#include "Scene/tSkeleton.h" 
18using namespace tMath
19namespace tScene 
20
21 
22 
23void tJoint::Save(tChunkWriter& chunk) const 
24
25 chunk.Begin(tChunkID::Scene_Joint); 
26
27 tObject::Save(chunk); 
28 
29 chunk.Begin(tChunkID::Scene_JointTranslation); 
30 chunk.Write(Translation); 
31 chunk.End(); 
32 
33 chunk.Begin(tChunkID::Scene_JointOrientation); 
34 chunk.Write(Orientation); 
35 chunk.End(); 
36 
37 chunk.Begin(tChunkID::Scene_JointScale); 
38 chunk.Write(JointScale); 
39 chunk.End(); 
40 
41 chunk.Begin(tChunkID::Scene_JointParentID); 
42 chunk.Write(ParentID); 
43 chunk.End(); 
44 
45 chunk.Begin(tChunkID::Scene_JointNumChildren); 
46 chunk.Write(NumChildren); 
47 chunk.End(); 
48 
49 chunk.Begin(tChunkID::Scene_JointChildIDTable); 
50 chunk.Write(Children, NumChildren); 
51 chunk.End(); 
52
53 chunk.End(); 
54
55 
56 
57void tJoint::Load(const tChunk& jointChunk
58
59 tAssert(jointChunk.GetID() == tChunkID::Scene_Joint); 
60 Clear(); 
61 
62 for (tChunk chunk = jointChunk.First(); chunk.IsValid(); chunk = chunk.Next()) 
63
64 switch (chunk.GetID()) 
65
66 case tChunkID::Scene_Object
67 tObject::Load(chunk); 
68 break
69 
70 case tChunkID::Scene_JointTranslation
71 chunk.GetItem(Translation); 
72 break
73 
74 case tChunkID::Scene_JointOrientation
75 chunk.GetItem(Orientation); 
76 break
77 
78 case tChunkID::Scene_JointScale
79 chunk.GetItem(JointScale); 
80 break
81 
82 case tChunkID::Scene_JointParentID
83 chunk.GetItem(ParentID); 
84 break
85 
86 case tChunkID::Scene_JointNumChildren
87 chunk.GetItem(NumChildren); 
88 break
89 
90 case tChunkID::Scene_JointChildIDTable
91
92 tAssert(NumChildren > 0); 
93 Children = new uint32[NumChildren]; 
94 chunk.GetItems(Children, NumChildren); 
95 break
96
97
98
99
100 
101 
102void tJoint::AddChildID(uint32 id
103
104 tAssert(NumChildren < MaxChildJoints); 
105 if (!Children
106
107 Children = new uint32[MaxChildJoints]; 
108 for (int i = 0; i < MaxChildJoints; i++) 
109 Children[i] = 0
110
111 
112 Children[NumChildren++] = id
113
114 
115 
116void tPose::Save(tChunkWriter& chunk) const 
117
118 chunk.Begin(tChunkID::Scene_Pose); 
119
120 chunk.Begin(tChunkID::Scene_PoseInfo); 
121
122 chunk.Write(FrameNumber); 
123 chunk.Write(NumJoints); 
124
125 chunk.End(); 
126 
127 chunk.Begin(tChunkID::Scene_QuaternionTable); 
128
129 chunk.Write(Quaternions, NumJoints); 
130
131 chunk.End(); 
132 
133 chunk.Begin(tChunkID::Scene_ScaleTable); 
134
135 chunk.Write(Scales, NumJoints); 
136
137 chunk.End(); 
138
139 chunk.End(); 
140
141 
142 
143void tPose::Load(const tChunk& poseChunk
144
145 tAssert(poseChunk.GetID() == tChunkID::Scene_Pose); 
146 
147 for (tChunk chunk = poseChunk.First(); chunk.IsValid(); chunk = chunk.Next()) 
148
149 switch (chunk.GetID()) 
150
151 case tChunkID::Scene_PoseInfo
152 chunk.GetItem(FrameNumber); 
153 chunk.GetItem(NumJoints); 
154 break
155 
156 case tChunkID::Scene_QuaternionTable
157
158 tAssert((FrameNumber != -1) && (NumJoints > 0)); 
159 Quaternions = new tQuaternion[NumJoints]; 
160 chunk.GetItems(Quaternions, NumJoints); 
161 break
162
163 
164 case tChunkID::Scene_ScaleTable
165
166 tAssert((FrameNumber != -1) && (NumJoints > 0)); 
167 Scales = new tVector4[NumJoints]; 
168 chunk.GetItems(Scales, NumJoints); 
169 break
170
171
172 }  
173
174 
175 
176void tSkeleton::Save(tChunkWriter& chunk) const 
177
178 chunk.Begin(tChunkID::Scene_Skeleton); 
179
180 tObject::Save(chunk); 
181 
182 chunk.Begin(tChunkID::Scene_SkeletonInfo); 
183
184 chunk.Write(NumJoints); 
185 chunk.Write(NumPoses); 
186 chunk.Write(FrameFrequency); 
187
188 chunk.End(); 
189 
190 chunk.Begin(tChunkID::Scene_JointList); 
191
192 for (tItList<tJoint>::Iter joint = Joints.First(); joint; joint.Next()) 
193 joint->Save(chunk); 
194
195 chunk.End(); 
196 
197 chunk.Begin(tChunkID::Scene_PoseList); 
198
199 for (tItList<tPose>::Iter pose = Poses.First(); pose; ++pose
200 pose->Save(chunk); 
201
202 chunk.End(); 
203
204
205 
206 
207void tSkeleton::Load(const tChunk& skelChunk
208
209 tAssert(skelChunk.GetID() == tChunkID::Scene_Skeleton); 
210 Clear(); 
211 
212 for (tChunk chunk = skelChunk.First(); chunk.IsValid(); chunk = chunk.Next()) 
213
214 switch (chunk.GetID()) 
215
216 case tChunkID::Scene_Object
217 tObject::Load(chunk); 
218 break
219 
220 case tChunkID::Scene_SkeletonInfo
221 chunk.GetItem(NumJoints); 
222 chunk.GetItem(NumPoses); 
223 chunk.GetItem(FrameFrequency); 
224 break
225 
226 case tChunkID::Scene_JointList
227
228 tAssert((chunk.GetID() == tChunkID::Scene_JointList) && (Joints.IsEmpty())); 
229 for (tChunk c = chunk.First(); c.IsValid(); c = c.Next()) 
230
231 switch (c.GetID()) 
232
233 case tChunkID::Scene_Joint
234 Joints.Append(new tJoint(c)); 
235 break
236
237
238 break
239
240 
241 case tChunkID::Scene_PoseList
242
243 tAssert((chunk.GetID() == tChunkID::Scene_PoseList) && (Poses.IsEmpty())); 
244 for (tChunk c = chunk.First(); c.IsValid(); c = c.Next()) 
245
246 switch (c.GetID()) 
247
248 case tChunkID::Scene_Pose
249 Poses.Append(new tPose(c)); 
250 break
251
252
253 break
254
255
256
257
258 
259 
260void tSkeleton::Pose(int poseNum
261
262 if (poseNum >= NumPoses
263 poseNum = NumPoses - 1
264 
265 tItList<tPose>::Iter pose = Poses.First(); 
266 while (poseNum
267
268 ++pose
269 poseNum--; 
270
271 
272 int jointNum = 0
273 for (tItList<tJoint>::Iter joint = Joints.First(); joint; ++joint
274
275 joint->Orientation = pose->Quaternions[jointNum]; 
276 joint->JointScale = pose->Scales[jointNum]; 
277 jointNum++; 
278
279
280 
281 
282
283