Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/t_animation.h @ 3857

Last change on this file since 3857 was 3857, checked in by bensch, 21 years ago

orxonox/trunk: ANIM_INF_REWIND mode works

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