Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/animation/t_animation.h @ 10618

Last change on this file since 10618 was 10618, checked in by bknecht, 17 years ago

merged cleanup into trunk (only improvements)

File size: 9.4 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{
39public:
40  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
41
42  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
43
44  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
45
46  virtual void rewind();
47  virtual void tick(float dt);
48
49private:
50  // animation functions
51  void setAnimFunc(ANIM_FUNCTION animFunc);
52  float constant(float timePassed) const;
53  float linear(float timePassed) const;
54  float sine(float timePassed) const;
55  float cosine(float timePassed) const;
56  float exp(float timePassed) const;
57  float negExp(float timePassed) const;
58  float quadratic(float timePassed) const;
59  float random(float timePassed) const;
60
61
62private:
63  typedef std::list<KeyFrameF> KeyFrameList;
64  typedef typename KeyFrameList::iterator KeyFrameIterator;
65
66  //  ANIM_FUNCTION animFunc
67  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
68
69  KeyFrameIterator   currentKeyFrame;                     //!< The current KeyFrame
70  KeyFrameIterator   nextKeyFrame;                        //!< The KeyFrame we iterate to
71  KeyFrameList       keyFrameList;                 //!< The KeyFrameList
72
73  T* object;                                      //!< The Object from which to Animate something
74  void (T::*funcToAnim)(float);                   //!< The function to Animate
75
76  float expFactor;                                //!< some factors
77};
78
79
80
81/**
82 *  standard constructor
83*/
84template<class T>
85tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
86{
87  // create a new List
88  KeyFrameF tmpKeyFrame;
89  tmpKeyFrame.value = 0.0;
90  tmpKeyFrame.duration = 1.0;
91  keyFrameList.push_back(tmpKeyFrame);
92
93  this->currentKeyFrame = keyFrameList.begin();
94  this->nextKeyFrame = keyFrameList.begin();
95
96  this->animFunc = &tAnimation<T>::linear;
97
98  this->setFuncToAnim(object, funcToAnim);
99}
100
101
102/**
103 *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
104*/
105template<class T>
106void tAnimation<T>::rewind()
107{
108  this->currentKeyFrame = keyFrameList.begin();
109  this->nextKeyFrame = ++keyFrameList.begin();
110  this->localTime = 0.0;
111  this->setAnimFunc((*this->currentKeyFrame).animFunc);
112}
113
114/**
115 *  sets the Function we want to animate
116 * @param object from what object do we want to animate
117 * @param funcToAnim which function
118*/
119template<class T>
120void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
121{
122  this->baseObject = this->object = object;
123  this->funcToAnim = funcToAnim;
124}
125
126/**
127 *  Appends a new Keyframe
128 * @param value the value of the new KeyFrame
129 * @param duration The duration from the new KeyFrame to the next one
130 * @param animFunc The function to animate between this keyFrame and the next one
131*/
132template<class T>
133void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
134{
135  // some small check
136  if (duration <= 0.0)
137    duration = 1.0;
138  if (animFunc == ANIM_NULL)
139    animFunc = ANIM_DEFAULT_FUNCTION;
140
141  KeyFrameF& tmpKeyFrame = keyFrameList.front();
142
143  // when adding the first frame
144  if (this->keyFrameCount == 0)
145  {
146    this->setAnimFunc(animFunc);
147  }
148  else
149  {
150    this->keyFrameList.push_back(KeyFrameF());
151    tmpKeyFrame = keyFrameList.back();
152    // when adding the second frame
153    if (this->currentKeyFrame == this->nextKeyFrame)
154      this->nextKeyFrame = --keyFrameList.end();
155  }
156
157  tmpKeyFrame.value = value;
158  tmpKeyFrame.duration = duration;
159  tmpKeyFrame.animFunc = animFunc;
160  this->keyFrameCount++;
161}
162
163/**
164 *  ticks the Animation
165 * @param dt how much time to tick
166*/
167template<class T>
168void tAnimation<T>::tick(float dt)
169{
170  if (this->bRunning)
171  {
172    this->localTime += dt;
173    if (localTime >= this->currentKeyFrame->duration)
174    {
175      if (likely(this->keyFramesToPlay != 0))
176      {
177        if (unlikely(this->keyFramesToPlay > 0))
178          --this->keyFramesToPlay;
179        // switching to the next Key-Frame
180        this->localTime -= this->currentKeyFrame->duration;
181
182        this->currentKeyFrame = this->nextKeyFrame;
183        // checking, if we should still Play the animation
184        if (this->currentKeyFrame == --this->keyFrameList.end())
185          this->handleInfinity();
186        this->nextKeyFrame = this->currentKeyFrame;
187        this->nextKeyFrame++;
188
189        //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
190        this->setAnimFunc(this->currentKeyFrame->animFunc);
191      }
192      else
193        this->pause();
194    }
195
196    (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
197  }
198}
199
200/**
201 *  Sets The kind of Animation between this keyframe and the next one
202 * @param animFunc The Type of Animation to set
203*/
204template<class T>
205void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
206{
207  switch (animFunc)
208  {
209  default:
210  case ANIM_CONSTANT:
211    this->animFunc = &tAnimation<T>::constant;
212    break;
213  case ANIM_LINEAR:
214    this->animFunc = &tAnimation<T>::linear;
215    break;
216  case ANIM_SINE:
217    this->animFunc = &tAnimation<T>::sine;
218    break;
219  case ANIM_COSINE:
220    this->animFunc = &tAnimation<T>::cosine;
221    break;
222  case ANIM_EXP:
223    this->animFunc = &tAnimation<T>::exp;
224    break;
225  case ANIM_NEG_EXP:
226    this->animFunc = &tAnimation<T>::negExp;
227    expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
228    break;
229  case ANIM_QUADRATIC:
230    this->animFunc = &tAnimation<T>::quadratic;
231    break;
232  case ANIM_RANDOM:
233    this->animFunc = &tAnimation<T>::random;
234    break;
235  }
236}
237
238
239// animation functions
240/**
241 *  stays at the value of the currentKeyFrame
242 * @param timePassed The time passed since this Keyframe began
243*/
244template<class T>
245float tAnimation<T>::constant(float timePassed) const
246{
247  return this->currentKeyFrame->value;
248}
249
250/**
251 *  linear interpolation between this keyframe and the next one
252 * @param timePassed The time passed since this Keyframe began
253*/
254template<class T>
255float tAnimation<T>::linear(float timePassed) const
256{
257  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
258         * (timePassed / this->currentKeyFrame->duration);
259}
260
261/**
262 *  a Sinusodial Interpolation between this keyframe and the next one
263 * @param timePassed The time passed since this Keyframe began
264*/
265template<class T>
266float tAnimation<T>::sine(float timePassed) const
267{
268  if (timePassed * 2.0 < this->currentKeyFrame->duration)
269    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
270           * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
271  else
272    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
273           * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
274  /*
275  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
276  return retVal;
277  */
278}
279
280/**
281 *  a cosine interpolation between this keyframe and the next one
282 * @param timePassed The time passed since this Keyframe began
283*/
284template<class T>
285float tAnimation<T>::cosine(float timePassed) const
286{
287  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
288          (this->currentKeyFrame->value - this->nextKeyFrame->value) *
289          cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
290}
291
292/**
293 *  an exponential interpolation between this keyframe and the next one
294 * @param timePassed The time passed since this Keyframe began
295*/
296template<class T>
297float tAnimation<T>::exp(float timePassed) const
298{
299  return this->linear(timePassed);
300}
301
302/**
303 *  a negative exponential interpolation between this keyframe and the next one
304 * @param timePassed The time passed since this Keyframe began
305*/
306template<class T>
307float tAnimation<T>::negExp(float timePassed) const
308{
309  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
310  float e = d * (1.0 - expf(- timePassed * expFactor));
311  return  this->currentKeyFrame->value - e;
312}
313
314/**
315 *  a quadratic interpolation between this keyframe and the next one
316 * @param timePassed The time passed since this Keyframe began
317*/
318template<class T>
319float tAnimation<T>::quadratic(float timePassed) const
320{
321  return this->linear(timePassed);
322}
323
324/**
325 *  some random animation (fluctuating)
326 * @param timePassed The time passed since this Keyframe began
327*/
328template<class T>
329float tAnimation<T>::random(float timePassed) const
330{
331  return this->currentKeyFrame->value +
332         (this->nextKeyFrame->value - this->currentKeyFrame->value) *
333         (float)rand()/(float)RAND_MAX;
334}
335
336#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.