Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: sine/cosine reimplemented in t_animation

File size: 9.5 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}
130
131/**
132   \brief sets the Function we want to animate
133   \param object from what object do we want to animate
134   \param funcToAnim which function
135*/
136template<class T>
137void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
138{
139  this->baseObject = this->object = object;
140  this->funcToAnim = funcToAnim;
141}
142
143/**
144   \brief Appends a new Keyframe
145   \param value the value of the new KeyFrame
146   \param duration The duration from the new KeyFrame to the next one
147   \param animFunc The function to animate between this keyFrame and the next one
148*/
149template<class T>
150void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
151{
152  // some small check
153  if (duration <= 0.0)
154    duration = 1.0;
155
156  KeyFrameF* tmpKeyFrame;
157   
158  if (bHasKeys)
159    {
160      tmpKeyFrame = new KeyFrameF;
161      // when adding the second frame
162      if (this->currentKeyFrame == this->nextKeyFrame)
163        this->nextKeyFrame = tmpKeyFrame;
164      this->keyFrameList->add(tmpKeyFrame);
165    }
166  // when adding the first frame
167  else
168    {
169      tmpKeyFrame = this->keyFrameList->firstElement();
170      this->bHasKeys = true;
171      this->setAnimFunc(animFunc);
172    }
173
174  tmpKeyFrame->value = value;
175  tmpKeyFrame->duration = duration;
176  tmpKeyFrame->animFunc = animFunc;
177}
178
179/**
180   \brief ticks the Animation
181   \param dt how much time to tick
182*/
183template<class T>
184void tAnimation<T>::tick(float dt)
185{
186  if (this->bRunning)
187    {
188      this->localTime += dt;
189      if (localTime >= this->currentKeyFrame->duration)
190        {
191          // switching to the next Key-Frame
192          this->localTime -= this->currentKeyFrame->duration;
193
194          this->currentKeyFrame = this->nextKeyFrame;
195          // checking, if we should still Play the animation
196          if (this->currentKeyFrame == this->keyFrameList->lastElement())
197            this->handleInfinity();
198          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
199
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
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*/
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
251/**
252   \brief stays at the value of the currentKeyFrame
253   \param timePassed The time passed since this Keyframe began
254*/
255template<class T>
256float tAnimation<T>::constant(float timePassed) const
257{
258  return this->currentKeyFrame->value;
259}
260
261/**
262   \brief linear 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>::linear(float timePassed) const 
267{
268  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
269    * (timePassed / this->currentKeyFrame->duration);
270}
271
272/**
273   \brief a Sinusodial Interpolation between this keyframe and the next one
274   \param timePassed The time passed since this Keyframe began
275*/
276template<class T>
277float tAnimation<T>::sine(float timePassed) const
278{
279  if (timePassed * 2.0 < this->currentKeyFrame->duration)
280    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value) 
281      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
282  else 
283    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
284      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
285  /*
286  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
287  return retVal;
288  */
289}
290
291/**
292   \brief a cosine interpolation between this keyframe and the next one
293   \param timePassed The time passed since this Keyframe began
294*/
295template<class T>
296float tAnimation<T>::cosine(float timePassed) const
297{
298  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
299    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
300    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
301}
302
303/**
304   \brief an exponential interpolation between this keyframe and the next one
305   \param timePassed The time passed since this Keyframe began
306*/
307template<class T>
308float tAnimation<T>::exp(float timePassed) const
309{
310}
311
312/**
313   \brief a negative 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>::negExp(float timePassed) const
318{
319  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
320  float e = d * (1.0 - expf(- timePassed * expFactor));
321  return  this->currentKeyFrame->value - e;
322}
323
324/**
325   \brief a quadratic interpolation between this keyframe and the next one
326   \param timePassed The time passed since this Keyframe began
327*/
328template<class T>
329float tAnimation<T>::quadratic(float timePassed) const
330{
331  this->linear(timePassed);
332}
333
334/**
335   \brief some random animation (fluctuating)
336   \param timePassed The time passed since this Keyframe began
337*/
338template<class T>
339float tAnimation<T>::random(float timePassed) const
340{
341  return this->currentKeyFrame->value * (float)rand()/(float)RAND_MAX;
342}
343
344#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.