Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/blink/src/util/animation/t_animation.h @ 10727

Last change on this file since 10727 was 8315, checked in by bensch, 19 years ago

trunk: fixed a nasty seg-fault, when unloading the WeaponManager

@chrigi: do not doulbe-delete :) no, you could not have known

File size: 9.9 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16/*!
17 * @file t_animation.h
18*/
19
20#ifndef _T_ANIMATION_H
21#define _T_ANIMATION_H
22
23#include "animation.h"
24
25#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
26
27//! A Struct for Keyframes that simply hold a float
28typedef struct KeyFrameF
29{
30  float duration;             //!< duration of this keyframe
31  float value;                //!< value of this keyframe
32  ANIM_FUNCTION animFunc;     //!< with whitch function to iterate to the next KeyFrameF
33};
34
35
36//! A Class to handle some animation for single floated values.
37template<class T> class tAnimation : public Animation
38{
39 public:
40  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
41  virtual ~tAnimation();
42
43  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
44
45  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
46
47  virtual void rewind();
48  virtual void tick(float dt);
49
50 private:
51  // animation functions
52  void setAnimFunc(ANIM_FUNCTION animFunc);
53  float constant(float timePassed) const;
54  float linear(float timePassed) const;
55  float sine(float timePassed) const;
56  float cosine(float timePassed) const;
57  float exp(float timePassed) const;
58  float negExp(float timePassed) const;
59  float quadratic(float timePassed) const;
60  float random(float timePassed) const;
61
62
63  //  ANIM_FUNCTION animFunc
64  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
65
66  KeyFrameF* currentKeyFrame;                     //!< The current KeyFrame
67  KeyFrameF* nextKeyFrame;                        //!< The KeyFrame we iterate to
68  tList<KeyFrameF>* keyFrameList;                 //!< The KeyFrameList
69
70  T* object;                                      //!< The Object from which to Animate something
71  void (T::*funcToAnim)(float);                   //!< The function to Animate
72
73  float expFactor;                                //!< some factors
74};
75
76
77
78/**
79 *  standard constructor
80*/
81template<class T>
82tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
83{
84  // create a new List
85  this->keyFrameList = new tList<KeyFrameF>();
86  KeyFrameF* tmpKeyFrame = new KeyFrameF;
87  tmpKeyFrame->value = 0.0;
88  tmpKeyFrame->duration = 1.0;
89  keyFrameList->add(tmpKeyFrame);
90
91  this->currentKeyFrame = tmpKeyFrame;
92  this->nextKeyFrame = tmpKeyFrame;
93
94  this->animFunc = &tAnimation<T>::linear;
95
96  this->setFuncToAnim(object, funcToAnim);
97}
98
99
100/**
101 *  standard deconstructor
102
103   deletes all the Keyframes
104*/
105template<class T>
106tAnimation<T>::~tAnimation ()
107{
108  // delete all the KeyFrames
109  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
110  KeyFrameF*  enumKF = itKF->firstElement();
111  while (enumKF)
112    {
113      delete enumKF;
114      enumKF = itKF->nextElement();
115    }
116  delete itKF;
117  delete this->keyFrameList;
118}
119
120/**
121 *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
122*/
123template<class T>
124void tAnimation<T>::rewind()
125{
126  this->currentKeyFrame = keyFrameList->firstElement();
127  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
128  this->localTime = 0.0;
129  this->setAnimFunc(this->currentKeyFrame->animFunc);
130}
131
132/**
133 *  sets the Function we want to animate
134 * @param object from what object do we want to animate
135 * @param funcToAnim which function
136*/
137template<class T>
138void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
139{
140  this->baseObject = this->object = object;
141  this->funcToAnim = funcToAnim;
142}
143
144/**
145 *  Appends a new Keyframe
146 * @param value the value of the new KeyFrame
147 * @param duration The duration from the new KeyFrame to the next one
148 * @param animFunc The function to animate between this keyFrame and the next one
149*/
150template<class T>
151void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
152{
153  // some small check
154  if (duration <= 0.0)
155    duration = 1.0;
156  if (animFunc == ANIM_NULL)
157    animFunc = ANIM_DEFAULT_FUNCTION;
158
159  KeyFrameF* tmpKeyFrame;
160
161  // when adding the first frame
162  if (this->keyFrameCount == 0)
163    {
164      tmpKeyFrame = this->keyFrameList->firstElement();
165      this->setAnimFunc(animFunc);
166    }
167  else
168    {
169      tmpKeyFrame = new KeyFrameF;
170      // when adding the second frame
171      if (this->currentKeyFrame == this->nextKeyFrame)
172        this->nextKeyFrame = tmpKeyFrame;
173      this->keyFrameList->add(tmpKeyFrame);
174    }
175
176  tmpKeyFrame->value = value;
177  tmpKeyFrame->duration = duration;
178  tmpKeyFrame->animFunc = animFunc;
179  this->keyFrameCount++;
180}
181
182/**
183 *  ticks the Animation
184 * @param dt how much time to tick
185*/
186template<class T>
187void tAnimation<T>::tick(float dt)
188{
189  if (this->bRunning)
190    {
191      this->localTime += dt;
192      if (localTime >= this->currentKeyFrame->duration)
193        {
194          if (likely(this->keyFramesToPlay != 0))
195            {
196              if (unlikely(this->keyFramesToPlay > 0))
197                --this->keyFramesToPlay;
198              // switching to the next Key-Frame
199              this->localTime -= this->currentKeyFrame->duration;
200
201              this->currentKeyFrame = this->nextKeyFrame;
202              // checking, if we should still Play the animation
203              if (this->currentKeyFrame == this->keyFrameList->lastElement())
204                this->handleInfinity();
205              this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
206
207              //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
208              this->setAnimFunc(this->currentKeyFrame->animFunc);
209            }
210          else
211            this->pause();
212        }
213
214      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
215    }
216}
217
218/**
219 *  Sets The kind of Animation between this keyframe and the next one
220 * @param animFunc The Type of Animation to set
221*/
222template<class T>
223void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
224{
225  switch (animFunc)
226    {
227    default:
228    case ANIM_CONSTANT:
229      this->animFunc = &tAnimation<T>::constant;
230      break;
231    case ANIM_LINEAR:
232      this->animFunc = &tAnimation<T>::linear;
233      break;
234    case ANIM_SINE:
235      this->animFunc = &tAnimation<T>::sine;
236      break;
237    case ANIM_COSINE:
238      this->animFunc = &tAnimation<T>::cosine;
239      break;
240    case ANIM_EXP:
241      this->animFunc = &tAnimation<T>::exp;
242      break;
243    case ANIM_NEG_EXP:
244        this->animFunc = &tAnimation<T>::negExp;
245        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
246        break;
247    case ANIM_QUADRATIC:
248      this->animFunc = &tAnimation<T>::quadratic;
249      break;
250    case ANIM_RANDOM:
251      this->animFunc = &tAnimation<T>::random;
252      break;
253    }
254}
255
256
257// animation functions
258/**
259 *  stays at the value of the currentKeyFrame
260 * @param timePassed The time passed since this Keyframe began
261*/
262template<class T>
263float tAnimation<T>::constant(float timePassed) const
264{
265  return this->currentKeyFrame->value;
266}
267
268/**
269 *  linear interpolation between this keyframe and the next one
270 * @param timePassed The time passed since this Keyframe began
271*/
272template<class T>
273float tAnimation<T>::linear(float timePassed) const
274{
275  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
276    * (timePassed / this->currentKeyFrame->duration);
277}
278
279/**
280 *  a Sinusodial Interpolation between this keyframe and the next one
281 * @param timePassed The time passed since this Keyframe began
282*/
283template<class T>
284float tAnimation<T>::sine(float timePassed) const
285{
286  if (timePassed * 2.0 < this->currentKeyFrame->duration)
287    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
288      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
289  else
290    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
291      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
292  /*
293  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
294  return retVal;
295  */
296}
297
298/**
299 *  a cosine interpolation between this keyframe and the next one
300 * @param timePassed The time passed since this Keyframe began
301*/
302template<class T>
303float tAnimation<T>::cosine(float timePassed) const
304{
305  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
306    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
307    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
308}
309
310/**
311 *  an exponential interpolation between this keyframe and the next one
312 * @param timePassed The time passed since this Keyframe began
313*/
314template<class T>
315float tAnimation<T>::exp(float timePassed) const
316{
317  return this->linear(timePassed);
318}
319
320/**
321 *  a negative exponential interpolation between this keyframe and the next one
322 * @param timePassed The time passed since this Keyframe began
323*/
324template<class T>
325float tAnimation<T>::negExp(float timePassed) const
326{
327  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
328  float e = d * (1.0 - expf(- timePassed * expFactor));
329  return  this->currentKeyFrame->value - e;
330}
331
332/**
333 *  a quadratic interpolation between this keyframe and the next one
334 * @param timePassed The time passed since this Keyframe began
335*/
336template<class T>
337float tAnimation<T>::quadratic(float timePassed) const
338{
339  return this->linear(timePassed);
340}
341
342/**
343 *  some random animation (fluctuating)
344 * @param timePassed The time passed since this Keyframe began
345*/
346template<class T>
347float tAnimation<T>::random(float timePassed) const
348{
349  return this->currentKeyFrame->value +
350    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
351    (float)rand()/(float)RAND_MAX;
352}
353
354#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.