Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkeletonAnimDef.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2009 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * Raw description of a skeleton animation
20  */
21 
22 #include "precompiled.h"
23 
24 #include "SkeletonAnimDef.h"
25 #include "maths/MathUtil.h"
26 #include "ps/FileIo.h"
27 
28 
29 ///////////////////////////////////////////////////////////////////////////////////////////
30 // CSkeletonAnimDef constructor
31 CSkeletonAnimDef::CSkeletonAnimDef() : m_FrameTime(0), m_NumKeys(0), m_NumFrames(0), m_Keys(0)
32 {
33 }
34 
35 ///////////////////////////////////////////////////////////////////////////////////////////
36 // CSkeletonAnimDef destructor
38 {
39  delete[] m_Keys;
40 }
41 
42 ///////////////////////////////////////////////////////////////////////////////////////////
43 // BuildBoneMatrices: build matrices for all bones at the given time (in MS) in this
44 // animation
45 void CSkeletonAnimDef::BuildBoneMatrices(float time, CMatrix3D* matrices, bool loop) const
46 {
47  float fstartframe = time/m_FrameTime;
48  size_t startframe = (size_t)(int)(time/m_FrameTime);
49  float deltatime = fstartframe-startframe;
50 
51  startframe %= m_NumFrames;
52 
53  size_t endframe = startframe + 1;
54  endframe %= m_NumFrames;
55 
56  if (!loop && endframe == 0)
57  {
58  // This might be something like a death animation, and interpolating
59  // between the final frame and the initial frame is wrong, because they're
60  // totally different. So if we've looped around to endframe==0, just display
61  // the animation's final frame with no interpolation.
62  for (size_t i = 0; i < m_NumKeys; i++)
63  {
64  const Key& key = GetKey(startframe, i);
65  matrices[i].SetIdentity();
66  matrices[i].Rotate(key.m_Rotation);
67  matrices[i].Translate(key.m_Translation);
68  }
69  }
70  else
71  {
72  for (size_t i = 0; i < m_NumKeys; i++)
73  {
74  const Key& startkey = GetKey(startframe, i);
75  const Key& endkey = GetKey(endframe, i);
76 
77  CVector3D trans = Interpolate(startkey.m_Translation, endkey.m_Translation, deltatime);
78  // TODO: is slerp the best thing to use here?
79  CQuaternion rot;
80  rot.Slerp(startkey.m_Rotation, endkey.m_Rotation, deltatime);
81 
82  rot.ToMatrix(matrices[i]);
83  matrices[i].Translate(trans);
84  }
85  }
86 }
87 
88 ///////////////////////////////////////////////////////////////////////////////////////////
89 // Load: try to load the anim from given file; return a new anim if successful
91 {
92  CFileUnpacker unpacker;
93  unpacker.Read(filename,"PSSA");
94 
95  // check version
96  if (unpacker.GetVersion()<FILE_READ_VERSION) {
98  }
99 
100  // unpack the data
102  try {
103  CStr name; // unused - just here to maintain compatibility with the animation files
104  unpacker.UnpackString(name);
105  unpacker.UnpackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime));
106  anim->m_NumKeys = unpacker.UnpackSize();
107  anim->m_NumFrames = unpacker.UnpackSize();
108  anim->m_Keys=new Key[anim->m_NumKeys*anim->m_NumFrames];
109  unpacker.UnpackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key));
110  } catch (PSERROR_File&) {
111  delete anim;
112  throw;
113  }
114 
115  return anim;
116 }
117 
118 ///////////////////////////////////////////////////////////////////////////////////////////
119 // Save: try to save anim to file
120 void CSkeletonAnimDef::Save(const VfsPath& pathname,const CSkeletonAnimDef* anim)
121 {
122  CFilePacker packer(FILE_VERSION, "PSSA");
123 
124  // pack up all the data
125  packer.PackString("");
126  packer.PackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime));
127  const size_t numKeys = anim->m_NumKeys;
128  packer.PackSize(numKeys);
129  const size_t numFrames = anim->m_NumFrames;
130  packer.PackSize(numFrames);
131  packer.PackRaw(anim->m_Keys,numKeys*numFrames*sizeof(Key));
132 
133  // now write it
134  packer.Write(pathname);
135 }
Key & GetKey(size_t frame, size_t bone)
void Translate(float x, float y, float z)
Definition: Matrix3D.cpp:172
void UnpackRaw(void *rawData, size_t rawDataSize)
unpack given number of bytes from the input into the given array.
Definition: FileIo.cpp:150
T Interpolate(const T &a, const T &b, float l)
Definition: MathUtil.h:26
CVector3D m_Translation
void PackRaw(const void *rawData, size_t rawDataSize)
pack given number of bytes onto the end of the data stream
Definition: FileIo.cpp:78
helper class for reading binary files
Definition: FileIo.h:100
u32 GetVersion() const
Definition: FileIo.h:115
void Rotate(const CQuaternion &quat)
Definition: Matrix3D.cpp:354
helper class for writing binary files.
Definition: FileIo.h:52
static void Save(const VfsPath &pathname, const CSkeletonAnimDef *anim)
CMatrix3D ToMatrix() const
Definition: Quaternion.cpp:152
void BuildBoneMatrices(float time, CMatrix3D *matrices, bool loop) const
Definition: path.h:75
void Read(const VfsPath &filename, const char magic[4])
open and read in given file, check magic bits against those given; throw variety of exceptions if ope...
Definition: FileIo.cpp:111
pthread_key_t key
Definition: wpthread.cpp:140
size_t UnpackSize()
use UnpackRaw to retrieve 32-bits; returns their value as size_t after converting from little endian ...
Definition: FileIo.cpp:162
void SetIdentity()
Definition: Matrix3D.cpp:30
void UnpackString(CStr8 &result)
unpack a string from the raw data stream.
Definition: FileIo.cpp:170
CQuaternion m_Rotation
void Write(const VfsPath &filename)
write out to file all packed data added so far.
Definition: FileIo.cpp:62
void PackSize(size_t value)
convenience: convert a number (almost always a size type) to little-endian u32 and pack that...
Definition: FileIo.cpp:83
static CSkeletonAnimDef * Load(const VfsPath &filename)
void Slerp(const CQuaternion &from, const CQuaternion &to, float ratio)
Definition: Quaternion.cpp:198
void PackString(const CStr &str)
pack a string onto the end of the data stream (encoded as a 32-bit length followed by the characters)...
Definition: FileIo.cpp:89