Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: animation fix, the AnimationMode was not reset to the start-value when rewinding

File size: 9.6 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_LINEAR);
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   \brief 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   \brief 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->nextElement();
111  while (enumKF)
112    {
113      delete enumKF;
114      enumKF = itKF->nextElement();
115    }
116  delete itKF;
117  delete this->keyFrameList;
118}
119
120/**
121   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
122*/
123template<class T>
124void tAnimation<T>::rewind(void)
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   \brief 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   \brief 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
157  KeyFrameF* tmpKeyFrame;
158   
159  if (bHasKeys)
160    {
161      tmpKeyFrame = new KeyFrameF;
162      // when adding the second frame
163      if (this->currentKeyFrame == this->nextKeyFrame)
164        this->nextKeyFrame = tmpKeyFrame;
165      this->keyFrameList->add(tmpKeyFrame);
166    }
167  // when adding the first frame
168  else
169    {
170      tmpKeyFrame = this->keyFrameList->firstElement();
171      this->bHasKeys = true;
172      this->setAnimFunc(animFunc);
173    }
174
175  tmpKeyFrame->value = value;
176  tmpKeyFrame->duration = duration;
177  tmpKeyFrame->animFunc = animFunc;
178}
179
180/**
181   \brief ticks the Animation
182   \param dt how much time to tick
183*/
184template<class T>
185void tAnimation<T>::tick(float dt)
186{
187  if (this->bRunning)
188    {
189      this->localTime += dt;
190      if (localTime >= this->currentKeyFrame->duration)
191        {
192          // switching to the next Key-Frame
193          this->localTime -= this->currentKeyFrame->duration;
194
195          this->currentKeyFrame = this->nextKeyFrame;
196          // checking, if we should still Play the animation
197          if (this->currentKeyFrame == this->keyFrameList->lastElement())
198            this->handleInfinity();
199          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
200
201          printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
202          this->setAnimFunc(this->currentKeyFrame->animFunc);     
203        }
204     
205      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
206    }
207}
208
209/**
210   \brief Sets The kind of Animation between this keyframe and the next one
211   \param animFunc The Type of Animation to set
212*/
213template<class T>
214void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
215{
216  switch (animFunc)
217    {
218    default:
219    case ANIM_CONSTANT:
220      this->animFunc = &tAnimation<T>::constant;
221      break;
222    case ANIM_LINEAR:
223      this->animFunc = &tAnimation<T>::linear;
224      break;
225    case ANIM_SINE:
226      this->animFunc = &tAnimation<T>::sine;
227      break;
228    case ANIM_COSINE:
229      this->animFunc = &tAnimation<T>::cosine;
230      break;
231    case ANIM_EXP:
232      this->animFunc = &tAnimation<T>::exp;
233      break;
234    case ANIM_NEG_EXP:
235      {
236        this->animFunc = &tAnimation<T>::negExp;
237        float d = fabs(this->currentKeyFrame->value - this->nextKeyFrame->value);
238        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
239        break;
240      }
241    case ANIM_QUADRATIC:
242      this->animFunc = &tAnimation<T>::quadratic;
243      break;
244    case ANIM_RANDOM:
245      this->animFunc = &tAnimation<T>::random;
246      break;
247    }
248}
249
250
251// animation functions
252/**
253   \brief stays at the value of the currentKeyFrame
254   \param timePassed The time passed since this Keyframe began
255*/
256template<class T>
257float tAnimation<T>::constant(float timePassed) const
258{
259  return this->currentKeyFrame->value;
260}
261
262/**
263   \brief linear interpolation between this keyframe and the next one
264   \param timePassed The time passed since this Keyframe began
265*/
266template<class T>
267float tAnimation<T>::linear(float timePassed) const 
268{
269  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
270    * (timePassed / this->currentKeyFrame->duration);
271}
272
273/**
274   \brief a Sinusodial Interpolation between this keyframe and the next one
275   \param timePassed The time passed since this Keyframe began
276*/
277template<class T>
278float tAnimation<T>::sine(float timePassed) const
279{
280  if (timePassed * 2.0 < this->currentKeyFrame->duration)
281    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value) 
282      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
283  else 
284    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
285      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
286  /*
287  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
288  return retVal;
289  */
290}
291
292/**
293   \brief a cosine 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>::cosine(float timePassed) const
298{
299  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
300    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
301    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
302}
303
304/**
305   \brief an exponential interpolation between this keyframe and the next one
306   \param timePassed The time passed since this Keyframe began
307*/
308template<class T>
309float tAnimation<T>::exp(float timePassed) const
310{
311  return this->linear(timePassed);
312
313}
314
315/**
316   \brief a negative exponential interpolation between this keyframe and the next one
317   \param timePassed The time passed since this Keyframe began
318*/
319template<class T>
320float tAnimation<T>::negExp(float timePassed) const
321{
322  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
323  float e = d * (1.0 - expf(- timePassed * expFactor));
324  return  this->currentKeyFrame->value - e;
325}
326
327/**
328   \brief a quadratic interpolation between this keyframe and the next one
329   \param timePassed The time passed since this Keyframe began
330*/
331template<class T>
332float tAnimation<T>::quadratic(float timePassed) const
333{
334  this->linear(timePassed);
335}
336
337/**
338   \brief some random animation (fluctuating)
339   \param timePassed The time passed since this Keyframe began
340*/
341template<class T>
342float tAnimation<T>::random(float timePassed) const
343{
344  return this->currentKeyFrame->value * (float)rand()/(float)RAND_MAX;
345}
346
347#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.