Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10687 was 10618, checked in by bknecht, 18 years ago

merged cleanup into trunk (only improvements)

File size: 9.4 KB
RevLine 
[3851]1/*
2   orxonox - the future of 3D-vertical-scrollers
[10618]3 
[3851]4   Copyright (C) 2004 orx
[10618]5 
[3851]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.
[10618]10 
[3851]11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
[4597]16/*!
[5039]17 * @file t_animation.h
[3851]18*/
19
20#ifndef _T_ANIMATION_H
21#define _T_ANIMATION_H
22
[3849]23#include "animation.h"
24
[3860]25#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
26
[3863]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
[3849]36//! A Class to handle some animation for single floated values.
37template<class T> class tAnimation : public Animation
38{
[10618]39public:
[3849]40  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
41
[3859]42  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
[3849]43
[3979]44  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
[3849]45
[3859]46  virtual void rewind();
[3852]47  virtual void tick(float dt);
[3849]48
[10618]49private:
[3849]50  // animation functions
51  void setAnimFunc(ANIM_FUNCTION animFunc);
52  float constant(float timePassed) const;
53  float linear(float timePassed) const;
54  float sine(float timePassed) const;
55  float cosine(float timePassed) const;
56  float exp(float timePassed) const;
57  float negExp(float timePassed) const;
58  float quadratic(float timePassed) const;
59  float random(float timePassed) const;
[3851]60
61
[10618]62private:
63  typedef std::list<KeyFrameF> KeyFrameList;
64  typedef typename KeyFrameList::iterator KeyFrameIterator;
65
[4837]66  //  ANIM_FUNCTION animFunc
[3854]67  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
[3855]68
[10618]69  KeyFrameIterator   currentKeyFrame;                     //!< The current KeyFrame
70  KeyFrameIterator   nextKeyFrame;                        //!< The KeyFrame we iterate to
71  KeyFrameList       keyFrameList;                 //!< The KeyFrameList
[3849]72
[3854]73  T* object;                                      //!< The Object from which to Animate something
74  void (T::*funcToAnim)(float);                   //!< The function to Animate
75
76  float expFactor;                                //!< some factors
[3849]77};
78
79
80
81/**
[4836]82 *  standard constructor
[3849]83*/
84template<class T>
[4597]85tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
[3849]86{
87  // create a new List
[10618]88  KeyFrameF tmpKeyFrame;
89  tmpKeyFrame.value = 0.0;
90  tmpKeyFrame.duration = 1.0;
91  keyFrameList.push_back(tmpKeyFrame);
[3849]92
[10618]93  this->currentKeyFrame = keyFrameList.begin();
94  this->nextKeyFrame = keyFrameList.begin();
[3849]95
96  this->animFunc = &tAnimation<T>::linear;
97
98  this->setFuncToAnim(object, funcToAnim);
99}
100
101
102/**
[4836]103 *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
[3854]104*/
[3849]105template<class T>
[4746]106void tAnimation<T>::rewind()
[3849]107{
[10618]108  this->currentKeyFrame = keyFrameList.begin();
109  this->nextKeyFrame = ++keyFrameList.begin();
[3849]110  this->localTime = 0.0;
[10618]111  this->setAnimFunc((*this->currentKeyFrame).animFunc);
[3849]112}
113
[3854]114/**
[4836]115 *  sets the Function we want to animate
116 * @param object from what object do we want to animate
117 * @param funcToAnim which function
[3854]118*/
[3849]119template<class T>
120void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
121{
122  this->baseObject = this->object = object;
123  this->funcToAnim = funcToAnim;
124}
125
[3854]126/**
[4836]127 *  Appends a new Keyframe
128 * @param value the value of the new KeyFrame
129 * @param duration The duration from the new KeyFrame to the next one
130 * @param animFunc The function to animate between this keyFrame and the next one
[3854]131*/
[3849]132template<class T>
133void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
134{
135  // some small check
136  if (duration <= 0.0)
137    duration = 1.0;
[3979]138  if (animFunc == ANIM_NULL)
139    animFunc = ANIM_DEFAULT_FUNCTION;
[3849]140
[10618]141  KeyFrameF& tmpKeyFrame = keyFrameList.front();
[4597]142
[3876]143  // when adding the first frame
144  if (this->keyFrameCount == 0)
[10618]145  {
146    this->setAnimFunc(animFunc);
147  }
[3876]148  else
[10618]149  {
150    this->keyFrameList.push_back(KeyFrameF());
151    tmpKeyFrame = keyFrameList.back();
152    // when adding the second frame
153    if (this->currentKeyFrame == this->nextKeyFrame)
154      this->nextKeyFrame = --keyFrameList.end();
155  }
[3871]156
[10618]157  tmpKeyFrame.value = value;
158  tmpKeyFrame.duration = duration;
159  tmpKeyFrame.animFunc = animFunc;
[3876]160  this->keyFrameCount++;
[3849]161}
162
[3854]163/**
[4836]164 *  ticks the Animation
165 * @param dt how much time to tick
[3854]166*/
[3849]167template<class T>
[3852]168void tAnimation<T>::tick(float dt)
[3849]169{
170  if (this->bRunning)
[10618]171  {
172    this->localTime += dt;
173    if (localTime >= this->currentKeyFrame->duration)
[3849]174    {
[10618]175      if (likely(this->keyFramesToPlay != 0))
176      {
177        if (unlikely(this->keyFramesToPlay > 0))
178          --this->keyFramesToPlay;
179        // switching to the next Key-Frame
180        this->localTime -= this->currentKeyFrame->duration;
[4597]181
[10618]182        this->currentKeyFrame = this->nextKeyFrame;
183        // checking, if we should still Play the animation
184        if (this->currentKeyFrame == --this->keyFrameList.end())
185          this->handleInfinity();
186        this->nextKeyFrame = this->currentKeyFrame;
187        this->nextKeyFrame++;
[4597]188
[10618]189        //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
190        this->setAnimFunc(this->currentKeyFrame->animFunc);
191      }
192      else
193        this->pause();
194    }
[4597]195
[10618]196    (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
197  }
[3849]198}
199
[3854]200/**
[4836]201 *  Sets The kind of Animation between this keyframe and the next one
202 * @param animFunc The Type of Animation to set
[3854]203*/
[3849]204template<class T>
205void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
206{
207  switch (animFunc)
[10618]208  {
209  default:
210  case ANIM_CONSTANT:
211    this->animFunc = &tAnimation<T>::constant;
212    break;
213  case ANIM_LINEAR:
214    this->animFunc = &tAnimation<T>::linear;
215    break;
216  case ANIM_SINE:
217    this->animFunc = &tAnimation<T>::sine;
218    break;
219  case ANIM_COSINE:
220    this->animFunc = &tAnimation<T>::cosine;
221    break;
222  case ANIM_EXP:
223    this->animFunc = &tAnimation<T>::exp;
224    break;
225  case ANIM_NEG_EXP:
226    this->animFunc = &tAnimation<T>::negExp;
227    expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
228    break;
229  case ANIM_QUADRATIC:
230    this->animFunc = &tAnimation<T>::quadratic;
231    break;
232  case ANIM_RANDOM:
233    this->animFunc = &tAnimation<T>::random;
234    break;
235  }
[3849]236}
237
238
239// animation functions
[3854]240/**
[4836]241 *  stays at the value of the currentKeyFrame
242 * @param timePassed The time passed since this Keyframe began
[3854]243*/
[3849]244template<class T>
245float tAnimation<T>::constant(float timePassed) const
246{
247  return this->currentKeyFrame->value;
248}
249
[3854]250/**
[4836]251 *  linear interpolation between this keyframe and the next one
252 * @param timePassed The time passed since this Keyframe began
[3854]253*/
[3849]254template<class T>
[4597]255float tAnimation<T>::linear(float timePassed) const
[3849]256{
[3871]257  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
[10618]258         * (timePassed / this->currentKeyFrame->duration);
[3849]259}
260
[3854]261/**
[4836]262 *  a Sinusodial Interpolation between this keyframe and the next one
263 * @param timePassed The time passed since this Keyframe began
[3854]264*/
[3849]265template<class T>
266float tAnimation<T>::sine(float timePassed) const
267{
[3871]268  if (timePassed * 2.0 < this->currentKeyFrame->duration)
[4597]269    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
[10618]270           * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
[4597]271  else
[3871]272    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
[10618]273           * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
[3849]274  /*
[3871]275  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
276  return retVal;
[3849]277  */
278}
279
[3854]280/**
[4836]281 *  a cosine interpolation between this keyframe and the next one
282 * @param timePassed The time passed since this Keyframe began
[3854]283*/
[3849]284template<class T>
285float tAnimation<T>::cosine(float timePassed) const
286{
[3871]287  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
[10618]288          (this->currentKeyFrame->value - this->nextKeyFrame->value) *
289          cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
[3849]290}
291
[3854]292/**
[4836]293 *  an exponential interpolation between this keyframe and the next one
294 * @param timePassed The time passed since this Keyframe began
[3854]295*/
[3849]296template<class T>
297float tAnimation<T>::exp(float timePassed) const
298{
[3872]299  return this->linear(timePassed);
[3849]300}
301
[3854]302/**
[4836]303 *  a negative exponential interpolation between this keyframe and the next one
304 * @param timePassed The time passed since this Keyframe began
[3854]305*/
[3849]306template<class T>
307float tAnimation<T>::negExp(float timePassed) const
308{
309  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
310  float e = d * (1.0 - expf(- timePassed * expFactor));
311  return  this->currentKeyFrame->value - e;
312}
313
[3854]314/**
[4836]315 *  a quadratic interpolation between this keyframe and the next one
316 * @param timePassed The time passed since this Keyframe began
[3854]317*/
[3849]318template<class T>
319float tAnimation<T>::quadratic(float timePassed) const
320{
[8315]321  return this->linear(timePassed);
[3849]322}
[3851]323
[3855]324/**
[4836]325 *  some random animation (fluctuating)
326 * @param timePassed The time passed since this Keyframe began
[3855]327*/
328template<class T>
329float tAnimation<T>::random(float timePassed) const
330{
[4597]331  return this->currentKeyFrame->value +
[10618]332         (this->nextKeyFrame->value - this->currentKeyFrame->value) *
333         (float)rand()/(float)RAND_MAX;
[3855]334}
[3851]335
336#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.