Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: animation can now return the BaseObject it operates on

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