Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved the animation-stuff to src/util/animation

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
24#include "animation.h"
25
26#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
27
28//! A Struct for Keyframes that simply hold a float
29typedef struct KeyFrameF
30{
31  float duration;             //!< duration of this keyframe
32  float value;                //!< value of this keyframe
33  ANIM_FUNCTION animFunc;     //!< with whitch function to iterate to the next KeyFrameF
34};
35
36
37//! A Class to handle some animation for single floated values.
38template<class T> class tAnimation : public Animation
39{
40 public:
41  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
42  virtual ~tAnimation();
43
44  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
45
46  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_LINEAR);
47
48  virtual void rewind();
49  virtual void tick(float dt);
50
51 private:
52  // animation functions
53  void setAnimFunc(ANIM_FUNCTION animFunc);
54  float constant(float timePassed) const;
55  float linear(float timePassed) const;
56  float sine(float timePassed) const;
57  float cosine(float timePassed) const;
58  float exp(float timePassed) const;
59  float negExp(float timePassed) const;
60  float quadratic(float timePassed) const;
61  float random(float timePassed) const;
62
63
64  //  ANIM_FUNCTION animFunc;
65  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
66
67  KeyFrameF* currentKeyFrame;                     //!< The current KeyFrame
68  KeyFrameF* nextKeyFrame;                        //!< The KeyFrame we iterate to
69  tList<KeyFrameF>* keyFrameList;                 //!< The KeyFrameList
70
71  T* object;                                      //!< The Object from which to Animate something
72  void (T::*funcToAnim)(float);                   //!< The function to Animate
73
74  float expFactor;                                //!< some factors
75};
76
77
78
79/**
80   \brief standard constructor
81*/
82template<class T>
83tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float)) 
84{
85  // create a new List
86  this->keyFrameList = new tList<KeyFrameF>();
87  KeyFrameF* tmpKeyFrame = new KeyFrameF;
88  tmpKeyFrame->value = 0.0;
89  tmpKeyFrame->duration = 1.0;
90  keyFrameList->add(tmpKeyFrame);
91
92  this->currentKeyFrame = tmpKeyFrame;
93  this->nextKeyFrame = tmpKeyFrame;
94
95  this->animFunc = &tAnimation<T>::linear;
96
97  this->setFuncToAnim(object, funcToAnim);
98}
99
100
101/**
102   \brief standard deconstructor
103   
104   deletes all the Keyframes
105*/
106template<class T>
107tAnimation<T>::~tAnimation () 
108{
109  // delete all the KeyFrames
110  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
111  KeyFrameF*  enumKF = itKF->nextElement();
112  while (enumKF)
113    {
114      delete enumKF;
115      enumKF = itKF->nextElement();
116    }
117  delete itKF;
118  delete this->keyFrameList;
119}
120
121/**
122   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
123*/
124template<class T>
125void tAnimation<T>::rewind(void)
126{
127  this->currentKeyFrame = keyFrameList->firstElement();
128  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
129  this->localTime = 0.0;
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      if (this->currentKeyFrame == this->nextKeyFrame)
163        this->nextKeyFrame = tmpKeyFrame;
164      this->keyFrameList->add(tmpKeyFrame);
165
166    }
167  else
168    {
169      tmpKeyFrame = this->keyFrameList->firstElement();
170      bHasKeys = true;
171      this->setAnimFunc(animFunc);
172    }
173  tmpKeyFrame->value = value;
174  tmpKeyFrame->duration = duration;
175  tmpKeyFrame->animFunc = animFunc;
176}
177
178/**
179   \brief ticks the Animation
180   \param dt how much time to tick
181*/
182template<class T>
183void tAnimation<T>::tick(float dt)
184{
185  if (this->bRunning)
186    {
187      this->localTime += dt;
188      if (localTime >= this->currentKeyFrame->duration)
189        {
190          // switching to the next Key-Frame
191          this->localTime -= this->currentKeyFrame->duration;
192
193          this->currentKeyFrame = this->nextKeyFrame;
194          // checking, if we should still Play the animation
195          if (this->currentKeyFrame == this->keyFrameList->lastElement())
196            this->handleInfinity();
197          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
198          printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
199          this->setAnimFunc(this->currentKeyFrame->animFunc);     
200        }
201     
202      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
203    }
204}
205
206/**
207   \brief Sets The kind of Animation between this keyframe and the next one
208   \param animFunc The Type of Animation to set
209*/
210template<class T>
211void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
212{
213  switch (animFunc)
214    {
215    default:
216    case ANIM_CONSTANT:
217      this->animFunc = &tAnimation<T>::constant;
218      break;
219    case ANIM_LINEAR:
220      this->animFunc = &tAnimation<T>::linear;
221      break;
222    case ANIM_SINE:
223      this->animFunc = &tAnimation<T>::sine;
224      break;
225    case ANIM_COSINE:
226      this->animFunc = &tAnimation<T>::cosine;
227      break;
228    case ANIM_EXP:
229      this->animFunc = &tAnimation<T>::exp;
230      break;
231    case ANIM_NEG_EXP:
232      {
233        this->animFunc = &tAnimation<T>::negExp;
234        float d = fabs(this->currentKeyFrame->value - this->nextKeyFrame->value);
235        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
236        break;
237      }
238    case ANIM_QUADRATIC:
239      this->animFunc = &tAnimation<T>::quadratic;
240      break;
241    case ANIM_RANDOM:
242      this->animFunc = &tAnimation<T>::random;
243      break;
244    }
245}
246
247
248// animation functions
249/**
250   \brief stays at the value of the currentKeyFrame
251   \param timePassed The time passed since this Keyframe began
252*/
253template<class T>
254float tAnimation<T>::constant(float timePassed) const
255{
256  return this->currentKeyFrame->value;
257}
258
259/**
260   \brief linear interpolation between this keyframe and the next one
261   \param timePassed The time passed since this Keyframe began
262*/
263template<class T>
264float tAnimation<T>::linear(float timePassed) const 
265{
266  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value) 
267    * (timePassed / this->currentKeyFrame->duration);
268  //  PRINTF(0)("value is %f, %p %p\n", val, this->currentKeyFrame, this->nextKeyFrame);
269  //  return val;
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  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
280  float e = 0.5 * d * (1 - cos(M_PI * timePassed / this->currentKeyFrame->duration));
281  return this->currentKeyFrame->value - e;
282  /*
283  return his->currentKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
284    * sin(timePassed / this->currentKeyFrame->duration * M_PI);
285  */
286}
287
288/**
289   \brief a cosine interpolation between this keyframe and the next one
290   \param timePassed The time passed since this Keyframe began
291*/
292template<class T>
293float tAnimation<T>::cosine(float timePassed) const
294{
295  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
296  float e = 0.5 * d * (sin(M_PI * timePassed / this->currentKeyFrame->duration));
297  if( timePassed > 0.5*this->currentKeyFrame->duration) e = (d - e);
298  return this->currentKeyFrame->value - e;
299  /*
300  return this->currentKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
301    * cos(timePassed / this->currentKeyFrame->duration * M_PI);
302  */
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}
313
314/**
315   \brief a negative exponential interpolation between this keyframe and the next one
316   \param timePassed The time passed since this Keyframe began
317*/
318template<class T>
319float tAnimation<T>::negExp(float timePassed) const
320{
321  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
322  float e = d * (1.0 - expf(- timePassed * expFactor));
323  return  this->currentKeyFrame->value - e;
324}
325
326/**
327   \brief a quadratic interpolation between this keyframe and the next one
328   \param timePassed The time passed since this Keyframe began
329*/
330template<class T>
331float tAnimation<T>::quadratic(float timePassed) const
332{
333  this->linear(timePassed);
334}
335
336/**
337   \brief some random animation (fluctuating)
338   \param timePassed The time passed since this Keyframe began
339*/
340template<class T>
341float tAnimation<T>::random(float timePassed) const
342{
343  return this->currentKeyFrame->value * (float)rand()/(float)RAND_MAX;
344}
345
346#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.