Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3832 was 3832, checked in by patrick, 19 years ago

orxonox/trunk: animation class functions implemented, list enhanced

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