Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/animation.h @ 3848

Last change on this file since 3848 was 3848, checked in by bensch, 20 years ago

orxonox/trunk: names of keyframes:
KeyFrame → KeyFrame3D
AnimKeyFrame → KeyFrameF (F for float)

also changed some stuff in the Animation3D-class.

File size: 9.3 KB
RevLine 
[3781]1/*
2   orxonox - the future of 3D-vertical-scrollers
[3329]3
[3781]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: ...
[3245]14*/
[1853]15
16
[3781]17/*!
18    \file animation.h
19    A Set of functions to animate some floats inside of an Object
[3784]20
21    We apologize, that most part of the Function-Definitions are located
22    inside this h-file, but this must be like this because it is a template
23    function.
[3781]24*/
25
26#ifndef _ANIMATION_H
27#define _ANIMATION_H
28
[3795]29#include "list.h"
[3833]30#include "base_object.h"
31
[3782]32// FORWARD DEFINITION
33
[3832]34#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
35
[3784]36typedef enum ANIM_FUNCTION {ANIM_CONSTANT,
37                            ANIM_LINEAR,
38                            ANIM_SINE,
[3825]39                            ANIM_COSINE,
40                            ANIM_EXP,
41                            ANIM_NEG_EXP,
42                            ANIM_QUADRATIC,
[3784]43                            ANIM_RANDOM};
[3787]44
[3784]45typedef enum ANIM_INFINITY {ANIM_INF_CONSTANT,
46                            ANIM_INF_LINEAR,
47                            ANIM_INF_PINGPONG,
48                            ANIM_INF_REWIND};//, ANIM_DELETE}
[3543]49
[3848]50typedef struct KeyFrameF
[3784]51{
52  float duration;
53  float value;
54  ANIM_FUNCTION animFunc;
55};
56
[3847]57class Animation
[3782]58{
[3785]59 public:
[3847]60  virtual ~Animation(void);
[3820]61  void doNotHandle(void);
[3794]62
63  void setInfinity(ANIM_INFINITY postInfinity = ANIM_INF_CONSTANT);
64
65  void play(); // equals resume();
66  void stop();
67  void pause();
68  void replay();
[3797]69  virtual void rewind() = 0;
[3794]70
71  virtual void tick(float time) = 0;
72
[3795]73  /* implement in subclasses:
74   *
75   * De-/Constructor
76   * Animation Functions
77   * virtual tick
78   * List of keyFrames
79   * currentKeyFrame/nextKeyFrame
80   * virtual rewind, to go to the first Keyframe. (other functions will call this one)
81   */
[3833]82
83  /**
84     \returns the BaseObject, this animation operates on
85  */
86  BaseObject* getBaseObject(void) const { return baseObject;}
87
[3782]88 protected:
[3847]89  Animation(void);
[3782]90
[3784]91  // variables
[3794]92
[3795]93  float localTime;
[3784]94  ANIM_INFINITY postInfinity;
95
[3833]96  BaseObject* baseObject;         //!< The same as object in the derived classes, but with reference to BaseObject
[3784]97  bool bHasKeys;
[3820]98  bool bHandled;                  //!< If this Animation is handled by the AnimationPlayer.
[3787]99  bool bRunning;
[3782]100};
101
102
[3781]103//! A Class to handle some animation for single floated values.
[3847]104template<class T> class tAnimation : public Animation
[3781]105{
106 public:
[3847]107  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
108  virtual ~tAnimation();
[3543]109
[3797]110  virtual void rewind();
111
[3783]112  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
[3795]113  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_LINEAR);
[2036]114
[3797]115  virtual void tick(float time);
[3795]116
117  // animation functions
118  void setAnimFunc(ANIM_FUNCTION animFunc);
119
120  float constant(float timePassed) const;
121  float linear(float timePassed) const;
122  float sine(float timePassed) const;
[3825]123  float cosine(float timePassed) const;
124  float exp(float timePassed) const;
125  float negExp(float timePassed) const;
126  float quadratic(float timePassed) const;
127  float random(float timePassed) const;
[3795]128  //  ANIM_FUNCTION animFunc;
[3847]129  float (tAnimation<T>::*animFunc)(float) const;
[3848]130  KeyFrameF* currentKeyFrame;
131  KeyFrameF* nextKeyFrame;
132  tList<KeyFrameF>* keyFrameList;
[3795]133
134
135
136
[3781]137 private:
[3832]138  float expFactor;
[3784]139  T* object;
[3783]140  void (T::*funcToAnim)(float);
[3781]141};
142
143
144
[3329]145/**
[3781]146   \brief standard constructor
147
[3329]148*/
[3781]149template<class T>
[3847]150tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float)) 
[3781]151{
[3795]152  // create a new List
[3848]153  this->keyFrameList = new tList<KeyFrameF>();
154  KeyFrameF* tmpKeyFrame = new KeyFrameF;
[3795]155  tmpKeyFrame->value = 0.0;
156  tmpKeyFrame->duration = 1.0;
157  keyFrameList->add(tmpKeyFrame);
158
159  this->currentKeyFrame = tmpKeyFrame;
160  this->nextKeyFrame = tmpKeyFrame;
161
[3847]162  this->animFunc = &tAnimation<T>::linear;
[3795]163
[3784]164  this->setFuncToAnim(object, funcToAnim);
[3781]165}
[1853]166
167
[3781]168/**
169   \brief standard deconstructor
[3245]170
[3781]171*/
172template<class T>
[3847]173tAnimation<T>::~tAnimation () 
[3781]174{
[3795]175  // delete all the KeyFrames
[3848]176  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
177  KeyFrameF*  enumKF = itKF->nextElement();
[3795]178  while (enumKF)
179    {
180      delete enumKF;
181      enumKF = itKF->nextElement();
182    }
183  delete itKF;
184  delete this->keyFrameList;
185
[3781]186}
[3245]187
[3797]188template<class T>
[3847]189void tAnimation<T>::rewind(void)
[3797]190{
191  this->currentKeyFrame = keyFrameList->firstElement();
192  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
[3798]193  this->localTime = 0.0;
[3797]194}
[1853]195
[3781]196template<class T>
[3847]197void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
[3781]198{
[3833]199  this->baseObject = this->object = object;
[3783]200  this->funcToAnim = funcToAnim;
[3781]201}
202
[3795]203template<class T>
[3847]204void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
[3795]205{
206  // some small check
207  if (duration <= 0.0)
208    duration = 1.0;
209 
[3781]210
[3848]211  KeyFrameF* tmpKeyFrame;
[3795]212   
213  if (bHasKeys)
214    {
[3848]215      tmpKeyFrame = new KeyFrameF;
[3795]216      if (this->currentKeyFrame == this->nextKeyFrame)
217        this->nextKeyFrame = tmpKeyFrame;
218      this->keyFrameList->add(tmpKeyFrame);
219
220    }
221  else
222    {
223      tmpKeyFrame = this->keyFrameList->firstElement();
224      bHasKeys = true;
[3830]225      this->setAnimFunc(animFunc);
[3795]226    }
227  tmpKeyFrame->value = value;
228  tmpKeyFrame->duration = duration;
229  tmpKeyFrame->animFunc = animFunc;
230}
231
232
[3781]233template<class T>
[3847]234void tAnimation<T>::tick(float time)
[3781]235{
[3787]236  if (this->bRunning)
[3786]237    {
[3787]238      this->localTime += time;
239      if (localTime >= this->currentKeyFrame->duration)
240        {
[3846]241          // switching to the next Key-Frame
242          this->currentKeyFrame = this->nextKeyFrame;
[3787]243          this->localTime = 0;
[3846]244          // checking, if we should still Play the animation
[3787]245          if (this->currentKeyFrame == this->keyFrameList->lastElement())
[3846]246            {
247              switch (this->postInfinity)
248                {
249                case ANIM_INF_CONSTANT:
250                  this->bRunning = false;
251                  break;
252                case ANIM_INF_REWIND:
253                  break;
254                }
255            }
[3787]256          this->nextKeyFrame = this->keyFrameList->nextElement(this->nextKeyFrame);
257          printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
[3829]258          this->setAnimFunc(this->currentKeyFrame->animFunc);     
[3787]259        }
260     
261      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
[3786]262    }
[3781]263}
264
[3795]265
266template<class T>
[3847]267void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
[3795]268{
269  switch (animFunc)
270    {
271    default:
272    case ANIM_CONSTANT:
[3847]273      this->animFunc = &tAnimation<T>::constant;
[3795]274      break;
275    case ANIM_LINEAR:
[3847]276      this->animFunc = &tAnimation<T>::linear;
[3795]277      break;
[3825]278    case ANIM_SINE:
[3847]279      this->animFunc = &tAnimation<T>::sine;
[3825]280      break;
281    case ANIM_COSINE:
[3847]282      this->animFunc = &tAnimation<T>::cosine;
[3825]283      break;
284    case ANIM_EXP:
[3847]285      this->animFunc = &tAnimation<T>::exp;
[3825]286      break;
287    case ANIM_NEG_EXP:
[3832]288      {
[3847]289        this->animFunc = &tAnimation<T>::negExp;
[3832]290        float d = fabs(this->currentKeyFrame->value - this->nextKeyFrame->value);
291        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
292        break;
293      }
[3829]294    case ANIM_QUADRATIC:
[3847]295      this->animFunc = &tAnimation<T>::quadratic;
[3825]296      break;
[3795]297    case ANIM_RANDOM:
[3847]298      this->animFunc = &tAnimation<T>::random;
[3795]299      break;
300    }
301}
302
303
304// animation functions
305template<class T>
[3847]306float tAnimation<T>::random(float timePassed) const
[3795]307{
308  return (float)rand()/(float)RAND_MAX;
309}
310
311template<class T>
[3847]312float tAnimation<T>::constant(float timePassed) const
[3795]313{
314  return this->currentKeyFrame->value;
315}
316
317template<class T>
[3847]318float tAnimation<T>::linear(float timePassed) const 
[3795]319{
[3832]320  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value) 
[3795]321    * (timePassed / this->currentKeyFrame->duration);
322  //  PRINTF(0)("value is %f, %p %p\n", val, this->currentKeyFrame, this->nextKeyFrame);
323  //  return val;
324}
325
326template<class T>
[3847]327float tAnimation<T>::sine(float timePassed) const
[3795]328{
[3831]329  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
330  float e = 0.5 * d * (1 - cos(M_PI * timePassed / this->currentKeyFrame->duration));
331  return this->currentKeyFrame->value - e;
332  /*
[3832]333  return his->currentKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
[3825]334    * sin(timePassed / this->currentKeyFrame->duration * M_PI);
[3831]335  */
[3795]336}
337
[3825]338template<class T>
[3847]339float tAnimation<T>::cosine(float timePassed) const
[3825]340{
[3832]341  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
342  float e = 0.5 * d * (sin(M_PI * timePassed / this->currentKeyFrame->duration));
343  if( timePassed > 0.5*this->currentKeyFrame->duration) e = (d - e);
344  return this->currentKeyFrame->value - e;
345  /*
[3829]346  return this->currentKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
[3825]347    * cos(timePassed / this->currentKeyFrame->duration * M_PI);
[3832]348  */
[3825]349}
350
351template<class T>
[3847]352float tAnimation<T>::exp(float timePassed) const
[3825]353{
354}
355
356template<class T>
[3847]357float tAnimation<T>::negExp(float timePassed) const
[3825]358{
[3832]359  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
360  float e = d * (1.0 - expf(- timePassed * expFactor));
361  return  this->currentKeyFrame->value - e;
[3825]362}
363
364template<class T>
[3847]365float tAnimation<T>::quadratic(float timePassed) const
[3825]366{
367
368}
369
370
[3826]371
372
[3833]373
374/**********************TEST*******************************/
375class aTest
376{
377 public:
378  aTest() { last = 0.0;}
379  ~aTest() {}
380  void littleDebug(float f) {  diff = f - last; printf("f=%f, diff=%f\n", f,diff); last = f;}
381 private:
382  float diff;
383  float last;
384};
385
386//aTest::aTest() {}
387//aTest::~aTest() {}
388
389//void aTest::littleDebug(float f)
390
391/**********************TEST*******************************/
392
393
[3781]394#endif /* _ANIMATION_H */
Note: See TracBrowser for help on using the repository browser.