Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: now there is a posibility to play only parts of the animation:
use anim→playNextKeyframes(count_of_keyframes_to_play); to make it work

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