SO3Engine
ALConverterNodeAnim.cpp
Go to the documentation of this file.
1
2#include <boost/format.hpp>
7
10
11#include <set>
12#include <numeric>
13
14namespace SO3
15{
16 ALConverterNodeAnim::ALConverterNodeAnim(ALScene* scene, aiAnimation* animation, aiNodeAnim* nodeAnim, aiNode* node, double tickPerSec)
17 {
18 mAnim = animation;
19 mNodeAnim = nodeAnim;
20 mNode = node;
21 mScene = scene;
22 mTickPerSec = tickPerSec;
23 }
24
29
30 bool ALConverterNodeAnim::isAffected(aiString nodeName)
31 {
32 return (mNode->mName == nodeName);
33 }
34
35 double ALConverterNodeAnim::getTime()
36 {
37 return mAnim->mDuration/mTickPerSec;
38 }
39
40 unsigned int ALConverterNodeAnim::getBiggest(unsigned int* data, unsigned int size)
41 {
42 unsigned int res = data[0];
43 for(unsigned int n=1; n<size; ++n)
44 {
45 if(data[n]>res)
46 res = data[n];
47 }
48 return res;
49 }
50
51 template<typename T> T ALConverterNodeAnim::getBiggerValue(T* data, unsigned int size)
52 {
53 T res = data[0];
54 for(unsigned int n=1; n<size; ++n)
55 {
56 if(data[n]>res)
57 res = data[n];
58 }
59 return res;
60 }
61
62 void ALConverterNodeAnim::convert(tinyxml2::XMLElement* xmlAnimations, bool first)
63 {
64 tinyxml2::XMLDocument* doc = xmlAnimations->GetDocument();
65 tinyxml2::XMLElement* animations = doc->NewElement("animations");
66 tinyxml2::XMLElement* anim = doc->NewElement("animation");
67
68 std::string animName(mNodeAnim->mNodeName.C_Str());
69 animName += "Anim";
70
71 anim->SetAttribute("name", ALStringCleaner::cleanString(animName).c_str());
72 anim->SetAttribute("enable", first ? "true" : "false");
73 anim->SetAttribute("loop", first ? "true" : "false");
74 anim->SetAttribute("interpolationMode", "linear");
75 anim->SetAttribute("rotationInterpolationMode", "linear");
76 anim->SetAttribute("length", ConversionTools::formatFloatToString(getTime()).c_str());
77
78 aiVectorKey* posKey = mNodeAnim->mPositionKeys;
79 aiQuatKey* rotKey = mNodeAnim->mRotationKeys;
80 aiVectorKey* scaleKey = mNodeAnim->mScalingKeys;
81 unsigned int nbKey[3] = {mNodeAnim->mNumPositionKeys, mNodeAnim->mNumRotationKeys, mNodeAnim->mNumScalingKeys};
82 unsigned int keySize = getBiggerValue(nbKey, 3);
83
84 std::set<float> times;
85 for(unsigned int n=0; n<keySize; ++n)
86 {
87 if(mNodeAnim->mNumPositionKeys > n)
88 {
89 times.insert(static_cast<float>(posKey[n].mTime));
90 }
91
92 if(mNodeAnim->mNumScalingKeys > n)
93 {
94 times.insert(static_cast<float>(scaleKey[n].mTime));
95 }
96
97 if(mNodeAnim->mNumRotationKeys > n)
98 {
99 times.insert(static_cast<float>(rotKey[n].mTime));
100 }
101 }
102
103 std::vector<ALKeyFrame> keyframes;
104 for(std::set<float>::iterator it=times.begin(); it!=times.end(); ++it)
105 {
106 ALKeyFrame key(*it);
107 for(unsigned int n=0; n<keySize; ++n)
108 {
109 if(mNodeAnim->mNumPositionKeys > n)
110 {
111 if(posKey[n].mTime == *it)
112 {
113 key.setPosition(posKey[n]);
114 }
115 }
116
117 if(mNodeAnim->mNumScalingKeys > n)
118 {
119 if(scaleKey[n].mTime == *it)
120 {
121 key.setScale(scaleKey[n]);
122 }
123 }
124
125 if(mNodeAnim->mNumRotationKeys > n)
126 {
127 if(rotKey[n].mTime == *it)
128 {
129 key.setRotation(rotKey[n]);
130 }
131 }
132 }
133 keyframes.push_back(key);
134 }
135
136 for(unsigned int n=0; n<keyframes.size(); ++n)
137 {
138 keyframes[n].createInterpolation(keyframes, mNode);
139
140 aiVector3D keypos = keyframes[n].getPosition().mValue;
141 aiVector3D keyscale = keyframes[n].getScale().mValue;
142 aiQuaternion keyquat = keyframes[n].getRotation().mValue;
143
144 tinyxml2::XMLElement* XMLkeyframe = doc->NewElement("keyframe");
145 XMLkeyframe->SetAttribute("time", ConversionTools::formatFloatToString(keyframes[n].getTime()/mTickPerSec).c_str());
146
147 tinyxml2::XMLElement* translation = doc->NewElement("translation");
148 translation->SetAttribute("x", ConversionTools::formatFloatToString(keypos.x).c_str());
149 translation->SetAttribute("y", ConversionTools::formatFloatToString(keypos.y).c_str());
150 translation->SetAttribute("z", ConversionTools::formatFloatToString(keypos.z).c_str());
151 XMLkeyframe->InsertEndChild(translation);
152
153 tinyxml2::XMLElement* scaling = doc->NewElement("scale");
154 scaling->SetAttribute("x", ConversionTools::formatFloatToString(keyscale.x).c_str());
155 scaling->SetAttribute("y", ConversionTools::formatFloatToString(keyscale.y).c_str());
156 scaling->SetAttribute("z", ConversionTools::formatFloatToString(keyscale.z).c_str());
157 XMLkeyframe->InsertEndChild(scaling);
158
159 tinyxml2::XMLElement* rot = doc->NewElement("rotation");
160 rot->SetAttribute("qx", ConversionTools::formatFloatToString(keyquat.x).c_str());
161 rot->SetAttribute("qy", ConversionTools::formatFloatToString(keyquat.y).c_str());
162 rot->SetAttribute("qz", ConversionTools::formatFloatToString(keyquat.z).c_str());
163 rot->SetAttribute("qw", ConversionTools::formatFloatToString(keyquat.w).c_str());
164 XMLkeyframe->InsertEndChild(rot);
165
166 anim->InsertEndChild(XMLkeyframe);
167 }
168
169 animations->InsertEndChild(anim);
170 xmlAnimations->InsertEndChild(animations);
171 }
172
174 {
175 std::string animName(mNodeAnim->mNodeName.C_Str());
176 animName += "Anim";
177 SNodeAnimation* animation = ogNode->CreateNodeAnimation(ALStringCleaner::cleanString(animName), static_cast<float>(ConversionTools::formatFloat(getTime())));
178 SAnimTrack* animationTrack = animation->CreateAnimationTrack(boost::str(boost::format("%1%") %animation->GetNumAnimationsTracks()));
179
180 aiVectorKey* posKey = mNodeAnim->mPositionKeys;
181 aiQuatKey* rotKey = mNodeAnim->mRotationKeys;
182 aiVectorKey* scaleKey = mNodeAnim->mScalingKeys;
183 unsigned int nbKey[3] = {mNodeAnim->mNumPositionKeys, mNodeAnim->mNumRotationKeys, mNodeAnim->mNumScalingKeys};
184 unsigned int keySize = getBiggerValue(nbKey, 3);
185
186 std::set<float> times;
187 for(unsigned int n=0; n<keySize; ++n)
188 {
189 if(mNodeAnim->mNumPositionKeys > n)
190 {
191 times.insert(static_cast<float>(posKey[n].mTime));
192 }
193
194 if(mNodeAnim->mNumScalingKeys > n)
195 {
196 times.insert(static_cast<float>(scaleKey[n].mTime));
197 }
198
199 if(mNodeAnim->mNumRotationKeys > n)
200 {
201 times.insert(static_cast<float>(rotKey[n].mTime));
202 }
203 }
204
205 std::vector<ALKeyFrame> keyframes;
206 for(std::set<float>::iterator it=times.begin(); it!=times.end(); ++it)
207 {
208 ALKeyFrame key(*it);
209 for(unsigned int n=0; n<keySize; ++n)
210 {
211 if(mNodeAnim->mNumPositionKeys > n)
212 {
213 if(posKey[n].mTime == *it)
214 {
215 key.setPosition(posKey[n]);
216 }
217 }
218
219 if(mNodeAnim->mNumScalingKeys > n)
220 {
221 if(scaleKey[n].mTime == *it)
222 {
223 key.setScale(scaleKey[n]);
224 }
225 }
226
227 if(mNodeAnim->mNumRotationKeys > n)
228 {
229 if(rotKey[n].mTime == *it)
230 {
231 key.setRotation(rotKey[n]);
232 }
233 }
234 }
235 keyframes.push_back(key);
236 }
237
238 for(unsigned int n=0; n<keyframes.size(); ++n)
239 {
240 keyframes[n].createInterpolation(keyframes, mNode);
241
242 aiVector3D keypos = keyframes[n].getPosition().mValue;
243 aiVector3D keyscale = keyframes[n].getScale().mValue;
244 aiQuaternion keyquat = keyframes[n].getRotation().mValue;
245
246 animationTrack->CreateKey(static_cast<float>(ConversionTools::formatFloat(keyframes[n].getTime()/mTickPerSec)), Ogre::Vector3(keypos.x, keypos.y, keypos.z), Ogre::Quaternion(keyquat.w, keyquat.x, keyquat.y, keyquat.z), Ogre::Vector3(keyscale.x, keyscale.y, keyscale.z));
247 }
248 }
249}
static std::string cleanString(std::string str, bool toLower=true, bool clASCII=true, bool clSpaces=true, bool bUID=true)
Clean a string.
ALConverterNodeAnim(ALScene *scene, aiAnimation *animation, aiNodeAnim *nodeAnim, aiNode *node, double tickPerSec)
bool isAffected(aiString nodeName)
void convert(tinyxml2::XMLElement *xmlAnimations, bool first=false)
void setRotation(aiQuatKey rotationKey)
void setPosition(aiVectorKey positionkey)
void setScale(aiVectorKey scaleKey)
static float formatFloat(float val)
static std::string formatFloatToString(double val)
SAnimTrack * CreateAnimationTrack(const std::string &newAnimationTrackName)
Definition SO3Anim.cpp:145
unsigned short GetNumAnimationsTracks()
Definition SO3Anim.cpp:169
virtual void CreateKey(const float &timepos, const Ogre::Vector3 &pos, const Ogre::Quaternion &quat, const Ogre::Vector3 &scale)
SNodeAnimation * CreateNodeAnimation(const std::string &animationName, const float &animationLength)
XMLElement * NewElement(const char *name)
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition tinyxml2.h:1303
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition tinyxml2.h:592
XMLNode * InsertEndChild(XMLNode *addThis)