Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9869 was 8315, checked in by bensch, 18 years ago

trunk: fixed a nasty seg-fault, when unloading the WeaponManager

@chrigi: do not doulbe-delete :) no, you could not have known

File size: 9.9 KB
RevLine 
[3851]1/*
2   orxonox - the future of 3D-vertical-scrollers
[3849]3
[3851]4   Copyright (C) 2004 orx
[3849]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.
[3849]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{
39 public:
40  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
41  virtual ~tAnimation();
42
[3859]43  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
[3849]44
[3979]45  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
[3849]46
[3859]47  virtual void rewind();
[3852]48  virtual void tick(float dt);
[3849]49
[3859]50 private:
[3849]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;
[3851]61
62
[4837]63  //  ANIM_FUNCTION animFunc
[3854]64  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
[3855]65
[3854]66  KeyFrameF* currentKeyFrame;                     //!< The current KeyFrame
67  KeyFrameF* nextKeyFrame;                        //!< The KeyFrame we iterate to
68  tList<KeyFrameF>* keyFrameList;                 //!< The KeyFrameList
[3849]69
[3854]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
[3849]74};
75
76
77
78/**
[4836]79 *  standard constructor
[3849]80*/
81template<class T>
[4597]82tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
[3849]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/**
[4836]101 *  standard deconstructor
[4597]102
[3854]103   deletes all the Keyframes
[3849]104*/
105template<class T>
[4597]106tAnimation<T>::~tAnimation ()
[3849]107{
108  // delete all the KeyFrames
109  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
[5115]110  KeyFrameF*  enumKF = itKF->firstElement();
[3849]111  while (enumKF)
112    {
113      delete enumKF;
114      enumKF = itKF->nextElement();
115    }
116  delete itKF;
117  delete this->keyFrameList;
118}
119
[3854]120/**
[4836]121 *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
[3854]122*/
[3849]123template<class T>
[4746]124void tAnimation<T>::rewind()
[3849]125{
126  this->currentKeyFrame = keyFrameList->firstElement();
127  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
128  this->localTime = 0.0;
[3872]129  this->setAnimFunc(this->currentKeyFrame->animFunc);
[3849]130}
131
[3854]132/**
[4836]133 *  sets the Function we want to animate
134 * @param object from what object do we want to animate
135 * @param funcToAnim which function
[3854]136*/
[3849]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
[3854]144/**
[4836]145 *  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
[3854]149*/
[3849]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;
[3979]156  if (animFunc == ANIM_NULL)
157    animFunc = ANIM_DEFAULT_FUNCTION;
[3849]158
159  KeyFrameF* tmpKeyFrame;
[4597]160
[3876]161  // when adding the first frame
162  if (this->keyFrameCount == 0)
[3849]163    {
[3876]164      tmpKeyFrame = this->keyFrameList->firstElement();
165      this->setAnimFunc(animFunc);
166    }
167  else
168    {
[3849]169      tmpKeyFrame = new KeyFrameF;
[3871]170      // when adding the second frame
[3849]171      if (this->currentKeyFrame == this->nextKeyFrame)
[4597]172        this->nextKeyFrame = tmpKeyFrame;
[3849]173      this->keyFrameList->add(tmpKeyFrame);
174    }
[3871]175
[3849]176  tmpKeyFrame->value = value;
177  tmpKeyFrame->duration = duration;
178  tmpKeyFrame->animFunc = animFunc;
[3876]179  this->keyFrameCount++;
[3849]180}
181
[3854]182/**
[4836]183 *  ticks the Animation
184 * @param dt how much time to tick
[3854]185*/
[3849]186template<class T>
[3852]187void tAnimation<T>::tick(float dt)
[3849]188{
189  if (this->bRunning)
190    {
[3852]191      this->localTime += dt;
[3849]192      if (localTime >= this->currentKeyFrame->duration)
[4597]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
[4885]207              //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
[4597]208              this->setAnimFunc(this->currentKeyFrame->animFunc);
209            }
210          else
211            this->pause();
212        }
213
[3849]214      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
215    }
216}
217
[3854]218/**
[4836]219 *  Sets The kind of Animation between this keyframe and the next one
220 * @param animFunc The Type of Animation to set
[3854]221*/
[3849]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:
[4597]244        this->animFunc = &tAnimation<T>::negExp;
245        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
246        break;
[3849]247    case ANIM_QUADRATIC:
248      this->animFunc = &tAnimation<T>::quadratic;
249      break;
250    case ANIM_RANDOM:
251      this->animFunc = &tAnimation<T>::random;
252      break;
253    }
254}
255
256
257// animation functions
[3854]258/**
[4836]259 *  stays at the value of the currentKeyFrame
260 * @param timePassed The time passed since this Keyframe began
[3854]261*/
[3849]262template<class T>
263float tAnimation<T>::constant(float timePassed) const
264{
265  return this->currentKeyFrame->value;
266}
267
[3854]268/**
[4836]269 *  linear interpolation between this keyframe and the next one
270 * @param timePassed The time passed since this Keyframe began
[3854]271*/
[3849]272template<class T>
[4597]273float tAnimation<T>::linear(float timePassed) const
[3849]274{
[3871]275  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
[3849]276    * (timePassed / this->currentKeyFrame->duration);
277}
278
[3854]279/**
[4836]280 *  a Sinusodial Interpolation between this keyframe and the next one
281 * @param timePassed The time passed since this Keyframe began
[3854]282*/
[3849]283template<class T>
284float tAnimation<T>::sine(float timePassed) const
285{
[3871]286  if (timePassed * 2.0 < this->currentKeyFrame->duration)
[4597]287    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
[3871]288      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
[4597]289  else
[3871]290    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
291      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
[3849]292  /*
[3871]293  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
294  return retVal;
[3849]295  */
296}
297
[3854]298/**
[4836]299 *  a cosine interpolation between this keyframe and the next one
300 * @param timePassed The time passed since this Keyframe began
[3854]301*/
[3849]302template<class T>
303float tAnimation<T>::cosine(float timePassed) const
304{
[3871]305  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
306    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
307    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
[3849]308}
309
[3854]310/**
[4836]311 *  an exponential interpolation between this keyframe and the next one
312 * @param timePassed The time passed since this Keyframe began
[3854]313*/
[3849]314template<class T>
315float tAnimation<T>::exp(float timePassed) const
316{
[3872]317  return this->linear(timePassed);
[3849]318}
319
[3854]320/**
[4836]321 *  a negative exponential interpolation between this keyframe and the next one
322 * @param timePassed The time passed since this Keyframe began
[3854]323*/
[3849]324template<class T>
325float tAnimation<T>::negExp(float timePassed) const
326{
327  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
328  float e = d * (1.0 - expf(- timePassed * expFactor));
329  return  this->currentKeyFrame->value - e;
330}
331
[3854]332/**
[4836]333 *  a quadratic interpolation between this keyframe and the next one
334 * @param timePassed The time passed since this Keyframe began
[3854]335*/
[3849]336template<class T>
337float tAnimation<T>::quadratic(float timePassed) const
338{
[8315]339  return this->linear(timePassed);
[3849]340}
[3851]341
[3855]342/**
[4836]343 *  some random animation (fluctuating)
344 * @param timePassed The time passed since this Keyframe began
[3855]345*/
346template<class T>
347float tAnimation<T>::random(float timePassed) const
348{
[4597]349  return this->currentKeyFrame->value +
[3874]350    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
351    (float)rand()/(float)RAND_MAX;
[3855]352}
[3851]353
354#endif /* _T_ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.