Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3976 was 3968, checked in by patrick, 20 years ago

orxonox/trunk: animation3d cleaned up some code, deleted some old not used one

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  // when adding the first frame
160  if (this->keyFrameCount == 0)
161    {
162      tmpKeyFrame = this->keyFrameList->firstElement();
163      this->setAnimFunc(animFunc);
164    }
165  else
166    {
167      tmpKeyFrame = new KeyFrameF;
168      // when adding the second frame
169      if (this->currentKeyFrame == this->nextKeyFrame)
170        this->nextKeyFrame = tmpKeyFrame;
171      this->keyFrameList->add(tmpKeyFrame);
172    }
173
174  tmpKeyFrame->value = value;
175  tmpKeyFrame->duration = duration;
176  tmpKeyFrame->animFunc = animFunc;
177  this->keyFrameCount++;
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        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  return this->linear(timePassed);
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 + 
344    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
345    (float)rand()/(float)RAND_MAX;
346}
347
348#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.