Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: nicer implementation, also fool-proof now

File size: 9.7 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   \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  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   \brief 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          // switching to the next Key-Frame
195          this->localTime -= this->currentKeyFrame->duration;
196
197          this->currentKeyFrame = this->nextKeyFrame;
198          // checking, if we should still Play the animation
199          if (this->currentKeyFrame == this->keyFrameList->lastElement())
200            this->handleInfinity();
201          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
202
203          printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
204          this->setAnimFunc(this->currentKeyFrame->animFunc);     
205        }
206     
207      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
208    }
209}
210
211/**
212   \brief Sets The kind of Animation between this keyframe and the next one
213   \param animFunc The Type of Animation to set
214*/
215template<class T>
216void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
217{
218  switch (animFunc)
219    {
220    default:
221    case ANIM_CONSTANT:
222      this->animFunc = &tAnimation<T>::constant;
223      break;
224    case ANIM_LINEAR:
225      this->animFunc = &tAnimation<T>::linear;
226      break;
227    case ANIM_SINE:
228      this->animFunc = &tAnimation<T>::sine;
229      break;
230    case ANIM_COSINE:
231      this->animFunc = &tAnimation<T>::cosine;
232      break;
233    case ANIM_EXP:
234      this->animFunc = &tAnimation<T>::exp;
235      break;
236    case ANIM_NEG_EXP:
237      {
238        this->animFunc = &tAnimation<T>::negExp;
239        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
240        break;
241      }
242    case ANIM_QUADRATIC:
243      this->animFunc = &tAnimation<T>::quadratic;
244      break;
245    case ANIM_RANDOM:
246      this->animFunc = &tAnimation<T>::random;
247      break;
248    }
249}
250
251
252// animation functions
253/**
254   \brief stays at the value of the currentKeyFrame
255   \param timePassed The time passed since this Keyframe began
256*/
257template<class T>
258float tAnimation<T>::constant(float timePassed) const
259{
260  return this->currentKeyFrame->value;
261}
262
263/**
264   \brief linear interpolation between this keyframe and the next one
265   \param timePassed The time passed since this Keyframe began
266*/
267template<class T>
268float tAnimation<T>::linear(float timePassed) const 
269{
270  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
271    * (timePassed / this->currentKeyFrame->duration);
272}
273
274/**
275   \brief a Sinusodial Interpolation between this keyframe and the next one
276   \param timePassed The time passed since this Keyframe began
277*/
278template<class T>
279float tAnimation<T>::sine(float timePassed) const
280{
281  if (timePassed * 2.0 < this->currentKeyFrame->duration)
282    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value) 
283      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
284  else 
285    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
286      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
287  /*
288  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
289  return retVal;
290  */
291}
292
293/**
294   \brief a cosine interpolation between this keyframe and the next one
295   \param timePassed The time passed since this Keyframe began
296*/
297template<class T>
298float tAnimation<T>::cosine(float timePassed) const
299{
300  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
301    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
302    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
303}
304
305/**
306   \brief an exponential interpolation between this keyframe and the next one
307   \param timePassed The time passed since this Keyframe began
308*/
309template<class T>
310float tAnimation<T>::exp(float timePassed) const
311{
312  return this->linear(timePassed);
313
314}
315
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*/
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
328/**
329   \brief a quadratic interpolation between this keyframe and the next one
330   \param timePassed The time passed since this Keyframe began
331*/
332template<class T>
333float tAnimation<T>::quadratic(float timePassed) const
334{
335  this->linear(timePassed);
336}
337
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 + 
346    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
347    (float)rand()/(float)RAND_MAX;
348}
349
350#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.