1// tSkeleton.h 
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#pragma once 
16#include "Scene/tObject.h" 
17namespace tScene 
18
19 
20 
21class tJoint : public tObject 
22
23public
24 tJoint() { } 
25 tJoint(const tChunk& chunk) { Load(chunk); } 
26 virtual ~tJoint() { Clear(); } 
27 
28 void Clear(); 
29 void AddChildID(uint32 id); 
30 void Scale(float scale) { Translation *= scale; } 
31 
32 void Save(tChunkWriter&) const
33 void Load(const tChunk&); 
34 
35 static const int MaxChildJoints = 16
36 tMath::tVector4 Translation
37 tMath::tQuaternion Orientation
38 tMath::tVector4 JointScale
39 
40 uint32 ParentID = tObject::InvalidID; // InvalidID means no parent. 
41 int NumChildren = 0
42 uint32* Children = nullptr
43}; 
44 
45 
46class tPose 
47
48public
49 tPose() { } 
50 tPose(const tChunk& chunk) { Load(chunk); } 
51 virtual ~tPose() { delete[] Quaternions; delete[] Scales; } 
52 
53 void Load(const tChunk&); 
54 void Save(tChunkWriter&) const
55 
56 int FrameNumber = -1
57 int NumJoints = 0
58 
59 // Order of quaternions and the scales matches the order of the joints using a normal depth first traversal. 
60 tMath::tQuaternion* Quaternions = nullptr
61 tMath::tVector4* Scales = nullptr
62}; 
63 
64 
65class tSkeleton : public tObject 
66
67public
68 tSkeleton() { } 
69 tSkeleton(const tChunk& chunk) { Load(chunk); } 
70 virtual ~tSkeleton() { } 
71 
72 void Clear(); 
73 void Pose(int poseNum); 
74 void Scale(float scale) { for (tItList<tJoint>::Iter joint = Joints.First(); joint; ++joint) joint->Scale(scale); } 
75 
76 tJoint* GetJoint(uint32 jointID); 
77 tJoint* GetRootJoint() { return GetJoint(0); } 
78 
79 void Save(tChunkWriter&) const
80 void Load(const tChunk&); 
81 
82public
83 int NumJoints = 0
84 int NumPoses = 0
85 float FrameFrequency = 30.0f
86 tItList<tJoint> Joints
87 tItList<tPose> Poses
88}; 
89 
90 
91// Implementation below this line. 
92 
93 
94inline void tJoint::Clear() 
95
96 tObject::Clear(); 
97 Translation.Zero(); 
98 Orientation = tMath::tQuaternion::unit
99 JointScale.Set(1.0f, 1.0f, 1.0f, 1.0f); 
100 ParentID = tObject::InvalidID
101 NumChildren = 0
102 delete Children
103 Children = nullptr
104
105 
106 
107inline void tSkeleton::Clear() 
108
109 tObject::Clear(); 
110 NumJoints = 0
111 NumPoses = 0
112 FrameFrequency = 30.0f
113 Joints.Empty(); 
114 Poses.Empty(); 
115
116 
117 
118inline tJoint* tSkeleton::GetJoint(uint32 jointID
119
120 for (tItList<tJoint>::Iter joint = Joints.First(); joint; joint.Next()) 
121 if (joint->ID == jointID
122 return joint
123 
124 return 0
125
126 
127 
128
129