Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/resources/src/util/animation/t_animation.h @ 7917

Last change on this file since 7917 was 5115, checked in by bensch, 19 years ago

orxonox/trunk: reimplemented the list functions, as i did before in revision 5110.
This time, i looked out for the bugs, and i think i found one

@patrick: i know, that you do not want to code at the moment… :/ → see mail

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      {
245        this->animFunc = &tAnimation<T>::negExp;
246        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
247        break;
248      }
249    case ANIM_QUADRATIC:
250      this->animFunc = &tAnimation<T>::quadratic;
251      break;
252    case ANIM_RANDOM:
253      this->animFunc = &tAnimation<T>::random;
254      break;
255    }
256}
257
258
259// animation functions
260/**
261 *  stays at the value of the currentKeyFrame
262 * @param timePassed The time passed since this Keyframe began
263*/
264template<class T>
265float tAnimation<T>::constant(float timePassed) const
266{
267  return this->currentKeyFrame->value;
268}
269
270/**
271 *  linear interpolation between this keyframe and the next one
272 * @param timePassed The time passed since this Keyframe began
273*/
274template<class T>
275float tAnimation<T>::linear(float timePassed) const
276{
277  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
278    * (timePassed / this->currentKeyFrame->duration);
279}
280
281/**
282 *  a Sinusodial Interpolation between this keyframe and the next one
283 * @param timePassed The time passed since this Keyframe began
284*/
285template<class T>
286float tAnimation<T>::sine(float timePassed) const
287{
288  if (timePassed * 2.0 < this->currentKeyFrame->duration)
289    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
290      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
291  else
292    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
293      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
294  /*
295  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
296  return retVal;
297  */
298}
299
300/**
301 *  a cosine interpolation between this keyframe and the next one
302 * @param timePassed The time passed since this Keyframe began
303*/
304template<class T>
305float tAnimation<T>::cosine(float timePassed) const
306{
307  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
308    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
309    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
310}
311
312/**
313 *  an exponential interpolation between this keyframe and the next one
314 * @param timePassed The time passed since this Keyframe began
315*/
316template<class T>
317float tAnimation<T>::exp(float timePassed) const
318{
319  return this->linear(timePassed);
320
321}
322
323/**
324 *  a negative exponential interpolation between this keyframe and the next one
325 * @param timePassed The time passed since this Keyframe began
326*/
327template<class T>
328float tAnimation<T>::negExp(float timePassed) const
329{
330  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
331  float e = d * (1.0 - expf(- timePassed * expFactor));
332  return  this->currentKeyFrame->value - e;
333}
334
335/**
336 *  a quadratic interpolation between this keyframe and the next one
337 * @param timePassed The time passed since this Keyframe began
338*/
339template<class T>
340float tAnimation<T>::quadratic(float timePassed) const
341{
342  this->linear(timePassed);
343}
344
345/**
346 *  some random animation (fluctuating)
347 * @param timePassed The time passed since this Keyframe began
348*/
349template<class T>
350float tAnimation<T>::random(float timePassed) const
351{
352  return this->currentKeyFrame->value +
353    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
354    (float)rand()/(float)RAND_MAX;
355}
356
357#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.