SO3Engine
SO3SequenceAnimationTrack.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
27
28namespace SO3
29{
30
31SSequenceAnimationTrack::SSequenceAnimationTrack(const std::string& animationTrackName, SSequenceAnimation* animation, const unsigned short& trackAnimationId) : SAnimTrack(animationTrackName, animation, SAnimTrack::SO3_SEQUENCE_TRACK)
32{
33 mLength = 0.0f;
34}
35
37{
38 EnableTrackKeys(false);
39 const SAnimSequenceKeyList keylistCpy = keyList;
40 SAnimSequenceKeyList::const_iterator it = keylistCpy.begin();
41 while (it != keylistCpy.end())
42 {
43 RemoveKey(*it, false);
44 it++;
45 }
46}
47
48SSequenceAnimationTrack::SSequenceAnimationTrack() : SAnimTrack("", 0, SAnimTrack::SO3_NODE_TRACK)
49{
50}
51
52SSequenceAnimationKey* SSequenceAnimationTrack::AddKey(SAnim* anim, const float& length, const float& transtime, const float& decaltime)
53{
54 // do not add an SAnim from an another scene
55 if (anim->GetParentScene() != GetParentAnimation()->GetParentScene())
56 return 0;
57
58 SSequenceAnimationKey* key = new SSequenceAnimationKey(anim, GetLength() - transtime + decaltime, length, transtime, decaltime);
59 SetLength(GetLength() + length - transtime + decaltime);
60
61 //update animation length
62 static_cast<SSequenceAnimation*>(GetParentAnimation())->UpdateAnimationLength();
63
64 keyList.push_back(key);
65 return key;
66}
67
68void SSequenceAnimationTrack::UpdateTrackTime()
69{
70 float length = 0.0f;
71 SAnimSequenceKeyList::iterator it = keyList.begin();
72
73 while (it != keyList.end())
74 {
75 SAnim* anim = (*it)->GetAnim();
76 float klength = (*it)->GetLength();
77 float decaltime = (*it)->GetDecalTime();
78 float transtime = (*it)->GetTransitionTime();
79 (*it)->SetPosition(length - transtime + decaltime);
80 length = length + klength - transtime + decaltime;
81 it++;
82 }
83
84 //update track length
85 SetLength(length);
86
87 //update animation length
88 static_cast<SSequenceAnimation*>(GetParentAnimation())->UpdateAnimationLength();
89}
90
92{
93 //DO NOT CALL THIS ON key anim DESTRUCTION
94 if (reset && key->IsUsed())
95 {
96 SAnim* anim = key->GetAnim();
97 anim->SetSequenceUpdated(false);
98 key->SetUsed(false);
99
100 if (!anim->IsSequenceUpdated())
101 {
102 anim->SetEnable(false);
103 anim->SetLoop(anim->GetInitialLoop());
104 anim->SetTimePosition(0.0f);
105 anim->SetWeight(anim->GetInitialWeight());
106 }
107 }
108
109 SAnimSequenceKeyList::iterator it = std::find(keyList.begin(), keyList.end(), key);
110 if (it != keyList.end())
111 keyList.erase(it);
112
113 SO3_SAFE_DELETE(key);
114 UpdateTrackTime();
115}
116
117void SSequenceAnimationTrack::SetKey(const unsigned int& index, const float& length, const float& transition, const float& decaltime)
118{
120 if (key)
121 {
122 key->SetLength(length);
123 key->SetTransitionTime(transition);
124 key->SetDecalTime(decaltime);
125 UpdateTrackTime();
126 }
127}
128
130{
131 if (((int)(keyList.size()) - 1) < (int)index)
132 return 0;
133
134 return keyList.at(index);
135}
136
137bool SSequenceAnimationTrack::MoveKeyFromIndex(const unsigned int& index, const unsigned int& newindex)
138{
139 if (((keyList.size() - 1) < index) || ((keyList.size() - 1) < newindex) || (index == newindex))
140 return false;
141
142 SSequenceAnimationKey* mvkey = keyList[newindex];
143 keyList[newindex] = keyList.at(index);
144 keyList[index] = mvkey;
145
146 UpdateTrackTime();
147 return true;
148}
149
151{
153
154 SAnimSequenceKeyList::iterator it = keyList.begin();
155 while (it != keyList.end())
156 {
157 if ((*it)->GetAnim() == anim)
158 list.push_back(*it);
159 it++;
160 }
161
162 return list;
163}
164
166{
167 const SAnimSequenceKeyList keylistCpy = keyList;
168 SAnimSequenceKeyList::const_iterator it = keylistCpy.begin();
169 while (it != keylistCpy.end())
170 {
171 if ((*it)->GetAnim() == anim)
172 RemoveKey(*it, reset);
173 it++;
174 }
175}
176
177void SSequenceAnimationTrack::SetLength(const float& length)
178{
179 mLength = length;
180}
181
183{
184 return mLength;
185}
186
188{
189 SAnimSequenceKeyList::iterator ikey = keyList.begin();
190 while (ikey != keyList.end())
191 {
192 SAnim* anim = (*ikey)->GetAnim();
193 if (!enable && ((*ikey)->IsUsed() == true))
194 {
195 anim->SetSequenceUpdated(false);
196 (*ikey)->SetUsed(false);
197
198 if (!anim->IsSequenceUpdated())
199 {
200 anim->SetEnable(false);
201 anim->SetLoop(anim->GetInitialLoop());
202 anim->SetTimePosition(0.0f);
203 anim->SetWeight(anim->GetInitialWeight());
204 }
205 }
206
207 ikey++;
208 }
209}
210
212{
213 return (unsigned short)keyList.size();
214}
215
216float SSequenceAnimationTrack::GetKeyPositionTime(const unsigned int& keyIndex)
217{
218 float postime = 0.0f;
219 SSequenceAnimationKey* key = 0;
220 if(((int)GetNumKeyFrames() - 1) >= (int)keyIndex)
221 key = GetKeyFromIndex(keyIndex);
222
223 if (key)
224 postime = key->GetPosition();
225
226 return postime;
227}
228
229void SSequenceAnimationTrack::RemoveKey(const unsigned int& keyIndex)
230{
231 if(((int)GetNumKeyFrames() - 1) >= (int)keyIndex)
232 {
233 SSequenceAnimationKey* key = GetKeyFromIndex(keyIndex);
234 RemoveKey(key, true);
235 }
236}
237
239{
240 EnableTrackKeys(false);
241
242 const SAnimSequenceKeyList keylistCpy = keyList;
243 SAnimSequenceKeyList::const_iterator it = keylistCpy.begin();
244 while (it != keylistCpy.end())
245 {
246 RemoveKey(*it, true);
247 it++;
248 }
249}
250
252{
253 float lastPos = static_cast<SSequenceAnimation*>(GetParentAnimation())->GetLastPos();
254 bool stopIterate = false;
255
256 //Manage skipped keys
257 //reset missed animations next to the position before
258 if (pos < lastPos)
259 {
260 SAnimSequenceKeyList::reverse_iterator nextKeyIt = keyList.rbegin();
261 while ((nextKeyIt != keyList.rend()) && !stopIterate)
262 {
263 SAnim* anim = (*nextKeyIt)->GetAnim();
264 float spos = (*nextKeyIt)->GetPosition();
265 float klength = (*nextKeyIt)->GetLength();
266 if ((spos > pos) && (spos < lastPos))
267 {
268 anim->SetEnable(true);
269 anim->Apply(0.0f);
270
271 if (((*nextKeyIt)->IsUsed() == true) && anim->IsSequenceUpdated())
272 {
273 anim->SetSequenceUpdated(false);
274 (*nextKeyIt)->SetUsed(false);
275 }
276
277 if (!anim->IsSequenceUpdated())
278 {
279 anim->SetEnable(false);
280 anim->SetLoop(anim->GetInitialLoop());
281 //anim->SetTimePosition(0.0f);
282 anim->SetWeight(anim->GetInitialWeight());
283 }
284 }
285 else if (spos <= pos)
286 {
287 stopIterate = true;
288 }
289
290 if (((*nextKeyIt)->IsUsed() == true) && anim->IsSequenceUpdated())
291 {
292 anim->SetSequenceUpdated(false);
293 (*nextKeyIt)->SetUsed(false);
294
295 if (!anim->IsSequenceUpdated())
296 {
297 anim->SetEnable(false);
298 anim->SetLoop(anim->GetInitialLoop());
299 //anim->SetTimePosition(0.0f);
300 anim->SetWeight(anim->GetInitialWeight());
301 }
302 }
303
304 nextKeyIt++;
305 }
306
307 stopIterate = false;
308 }
309 //reset missed animations previous to the position to their end position
310 else if (pos > lastPos)
311 {
312 SAnimSequenceKeyList::iterator prevKeyIt = keyList.begin();
313 while ((prevKeyIt != keyList.end()) && !stopIterate)
314 {
315 SAnim* anim = (*prevKeyIt)->GetAnim();
316 float spos = (*prevKeyIt)->GetPosition();
317 float klength = (*prevKeyIt)->GetLength();
318 if (((spos + klength) > lastPos) && ((spos + klength) < pos))
319 {
320 anim->SetEnable(true);
321
322 // anim fade out
323 if ((prevKeyIt + 1) != keyList.end())
324 {
325 prevKeyIt++;
326 SSequenceAnimationKey* nextkey = (*prevKeyIt);
327 if (nextkey->GetTransitionTime() != 0.0f)
328 anim->SetWeight(0.0);
329 prevKeyIt--;
330 }
331
332 if (anim->GetLength() <= klength)
333 anim->SetLoop(false);
334
335 anim->Apply(klength);
336
337 if (((*prevKeyIt)->IsUsed() == true) && anim->IsSequenceUpdated())
338 {
339 anim->SetSequenceUpdated(false);
340 (*prevKeyIt)->SetUsed(false);
341 }
342
343 if (!anim->IsSequenceUpdated())
344 {
345 anim->SetEnable(false);
346 anim->SetLoop(anim->GetInitialLoop());
347 //anim->SetTimePosition(0.0f);
348 anim->SetWeight(anim->GetInitialWeight());
349 }
350 }
351 else if ((spos + klength) >= pos)
352 {
353 stopIterate = true;
354 }
355
356 if (((*prevKeyIt)->IsUsed() == true) && anim->IsSequenceUpdated())
357 {
358 anim->SetSequenceUpdated(false);
359 (*prevKeyIt)->SetUsed(false);
360
361 if (!anim->IsSequenceUpdated())
362 {
363 anim->SetEnable(false);
364 anim->SetLoop(anim->GetInitialLoop());
365 //anim->SetTimePosition(0.0f);
366 anim->SetWeight(anim->GetInitialWeight());
367 }
368 }
369
370 prevKeyIt++;
371 }
372
373 stopIterate = false;
374 }
375
376 //update current animations
377 SAnimSequenceKeyList::iterator keyIt = keyList.begin();
378 while ((keyIt != keyList.end()) && !stopIterate)
379 {
380 SAnim* anim = (*keyIt)->GetAnim();
381 float spos = (*keyIt)->GetPosition();
382 float klength = (*keyIt)->GetLength();
383 float transtime = (*keyIt)->GetTransitionTime();
384 float endpos = spos + klength;
385 float updpos = pos - spos;
386 float transStep = 1.0f;
387
388 if ((pos >= spos) && (pos <= endpos))
389 {
390 if ((*keyIt)->IsUsed() == false)
391 {
392 anim->SetSequenceUpdated(true);
393 (*keyIt)->SetUsed(true);
394 }
395
396 anim->SetEnable(true);
397 anim->SetLoop(true);
398
399 // anim fade in
400 if (((pos - spos) < transtime) && (transtime != 0.0f))
401 {
402 transStep = (pos - spos) / transtime;
403
404 // anim fade out
405 if (keyIt != keyList.begin())
406 {
407 keyIt--;
408 SSequenceAnimationKey* prevkey = (*keyIt);
409 if ((pos >= prevkey->GetPosition()) && (pos < (prevkey->GetPosition() + prevkey->GetLength())))
410 {
411 prevkey->GetAnim()->SetWeight(GetParentAnimation()->GetWeight() * prevkey->GetAnim()->GetInitialWeight() * (1.0f - transStep));
412 // force update by setting the time position (for sequence animation key type)
413 prevkey->GetAnim()->SetTimePosition(prevkey->GetAnim()->GetTimePosition());
414 }
415 keyIt++;
416 }
417 }
418
419 anim->SetWeight(GetParentAnimation()->GetWeight() * anim->GetInitialWeight() * transStep);
420 anim->SetTimePosition(updpos);
421 }
422 else if (spos + klength > pos)
423 {
424 stopIterate = true;
425 }
426
427 keyIt++;
428 }
429}
430
431}
SScene * GetParentScene()
Definition SO3Anim.cpp:110
virtual void SetTimePosition(const float &timePosition)
Definition SO3Anim.cpp:214
bool GetInitialLoop()
Definition SO3Anim.cpp:270
bool IsSequenceUpdated()
Definition SO3Anim.cpp:392
virtual void SetWeight(const float &weight)
Definition SO3Anim.cpp:237
void Apply(const float &timePosition)
Definition SO3Anim.cpp:220
float GetInitialWeight()
Definition SO3Anim.cpp:258
void SetLoop(const bool &loop)
Definition SO3Anim.cpp:311
virtual void SetEnable(const bool &enable)
Definition SO3Anim.cpp:295
virtual float GetWeight()
Definition SO3Anim.cpp:243
float GetLength()
Definition SO3Anim.cpp:205
float GetTimePosition()
Definition SO3Anim.cpp:228
void SetSequenceUpdated(const bool &value)
Definition SO3Anim.cpp:397
SAnim * GetParentAnimation()
void SetLength(const float &length)
void SetTransitionTime(const float &transtime)
void SetDecalTime(const float &decaltime)
virtual float GetKeyPositionTime(const unsigned int &keyIndex)
SSequenceAnimationKey * GetKeyFromIndex(const unsigned int &index)
void RemoveKey(SSequenceAnimationKey *key, const bool &reset)
SAnimSequenceKeyList GetKeysFromAnim(SAnim *anim)
SSequenceAnimationKey * AddKey(SAnim *anim, const float &length, const float &transition, const float &decaltime)
virtual void Update(const float &pos)
void RemoveKeysWithAnim(SAnim *anim, const bool &reset)
bool MoveKeyFromIndex(const unsigned int &index, const unsigned int &newindex)
void SetKey(const unsigned int &index, const float &length, const float &transition, const float &decaltime)
std::vector< SSequenceAnimationKey * > SAnimSequenceKeyList