Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/animation/animation3d.cc @ 3964

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

orxonox/trunk: implemented neg_exp function again. better than ever :)

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: Patrick Boenzli
13   co-programmer: Benjamin Grauer
14
15   2005-04-17: Benjamin Grauer
16          Rewritte all functions, so it will fit into the Animation-class
17*/
18
19#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
20
21#include "animation3d.h"
22
23#include "p_node.h"
24
25using namespace std;
26
27/**
28   \brief standard constructor
29*/
30Animation3D::Animation3D(PNode* object)
31{
32  this->object = object;
33
34  // create a new List
35  this->keyFrameList = new tList<KeyFrame3D>();
36  KeyFrame3D* tmpKeyFrame = new KeyFrame3D;
37  tmpKeyFrame->position = Vector();
38  tmpKeyFrame->direction = Quaternion();
39  keyFrameList->add(tmpKeyFrame);
40
41  this->currentKeyFrame = tmpKeyFrame;
42  this->nextKeyFrame = tmpKeyFrame;
43
44  this->animFunc = &Animation3D::linear;
45}
46
47/**
48   \brief standard deconstructor
49   
50   deletes all the Keyframes
51*/
52Animation3D::~Animation3D(void)
53{
54  // delete all the KeyFrames
55  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
56  KeyFrame3D*  enumKF = itKF->nextElement();
57  while (enumKF)
58    {
59      delete enumKF;
60      enumKF = itKF->nextElement();
61    }
62  delete itKF;
63  delete this->keyFrameList;
64}
65
66/**
67   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
68*/
69void Animation3D::rewind(void)
70{
71  this->currentKeyFrame = keyFrameList->firstElement();
72  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
73  this->localTime = 0.0;
74  this->setAnimFunc(this->currentKeyFrame->animFunc);
75}
76
77/**
78   \brief Appends a new Keyframe
79   \param position The position of the new Keyframe
80   \param direction The direction of the new Keyframe.
81   \param duration The duration from the new KeyFrame to the next one
82   \param animFunc The function to animate between this keyFrame and the next one
83*/
84void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration, ANIM_FUNCTION animFunc)
85{
86  // some small check
87  if (duration <= 0.0)
88    duration = 1.0;
89
90  KeyFrame3D* tmpKeyFrame;
91   
92  // when adding the first frame
93  if (this->keyFrameCount == 0)
94    {
95      tmpKeyFrame = this->keyFrameList->firstElement();
96      this->setAnimFunc(animFunc);
97    }
98  else
99    {
100      tmpKeyFrame = new KeyFrame3D;
101      // when adding the second frame
102      if (this->currentKeyFrame == this->nextKeyFrame)
103        this->nextKeyFrame = tmpKeyFrame;
104      this->keyFrameList->add(tmpKeyFrame);
105    }
106
107  tmpKeyFrame->position = position;
108  tmpKeyFrame->direction = direction;
109  tmpKeyFrame->duration = duration;
110  tmpKeyFrame->animFunc = animFunc;
111  this->keyFrameCount++;
112}
113
114/**
115   \brief ticks the Animation
116   \param dt how much time to tick
117*/
118void Animation3D::tick(float dt)
119{
120  if (this->bRunning)
121    { 
122      this->localTime += dt;
123      if (localTime >= this->currentKeyFrame->duration)
124        {
125          // switching to the next Key-Frame
126          this->localTime -= this->currentKeyFrame->duration;
127          this->currentKeyFrame = this->nextKeyFrame;
128          // checking, if we should still Play the animation
129          if (this->currentKeyFrame == this->keyFrameList->lastElement())
130            this->handleInfinity();
131          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
132          this->setAnimFunc(this->currentKeyFrame->animFunc);     
133         
134          if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP)
135            {
136
137            }
138        }
139
140      /* now animate it */
141      (this->*animFunc)(this->localTime);
142      /*
143      switch( this->movMode)
144        {
145        case LINEAR:
146          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
147          *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
148          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
149          *this->lastPosition = *this->tmpVect;
150          break;
151        case EXP:
152             
153          break;
154        case NEG_EXP:
155          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
156          *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT));     
157          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
158          *this->lastPosition = *this->tmpVect;
159          break;
160        case SIN:
161          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
162          *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
163          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
164          *this->lastPosition = *this->tmpVect;
165          break;
166        case COS:
167             
168          break;
169        case QUADRATIC:
170          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
171          *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
172          break;
173        default:
174          break;
175        }
176      */
177    }
178}
179
180
181/**
182   \brief Sets The kind of Animation between this keyframe and the next one
183   \param animFunc The Type of Animation to set
184*/
185void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
186{
187  switch (animFunc)
188    {
189    default:
190    case ANIM_CONSTANT:
191      this->animFunc = &Animation3D::constant;
192      break;
193    case ANIM_LINEAR:
194      this->animFunc = &Animation3D::linear;
195      break;
196    case ANIM_SINE:
197      this->animFunc = &Animation3D::sine;
198      break;
199    case ANIM_COSINE:
200      this->animFunc = &Animation3D::cosine;
201      break;
202    case ANIM_EXP:
203      this->animFunc = &Animation3D::exp;
204      break;
205    case ANIM_NEG_EXP:
206      this->animFunc = &Animation3D::negExp;
207      //this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
208      //this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
209      this->expFactor = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
210        //(this->currentKeyFrame->position - this->nextKeyFrame->position)
211
212      /*
213        float d = fabs(this->currentKeyFrame->value - this->nextKeyFrame->value);
214        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
215
216      */
217      break;
218    case ANIM_QUADRATIC:
219      this->animFunc = &Animation3D::quadratic;
220      break;
221    case ANIM_RANDOM:
222      this->animFunc = &Animation3D::random;
223      break;
224    }
225}
226
227/**
228   \brief stays at the value of the currentKeyFrame
229   \param timePassed The time passed since this Keyframe began
230*/
231void Animation3D::constant(float timePassed) const
232{
233  this->object->setRelCoor(this->currentKeyFrame->position);
234
235  /*
236    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
237    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
238    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
239    this->lastPosition = this->tmpVect;
240  */
241}
242
243/**
244   \brief linear interpolation between this keyframe and the next one
245   \param timePassed The time passed since this Keyframe began
246
247   \todo implement also do this for direction
248*/
249void Animation3D::linear(float timePassed) const
250{
251  this->object->setRelCoor(this->currentKeyFrame->position +
252                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
253                          (timePassed/this->currentKeyFrame->duration));
254}
255
256/**
257   \brief a Sinusodial Interpolation between this keyframe and the next one
258   \param timePassed The time passed since this Keyframe began
259
260   \todo implement
261*/
262void Animation3D::sine(float timePassed) const
263{
264  this->linear(timePassed);
265}
266
267/**
268   \brief a cosine interpolation between this keyframe and the next one
269   \param timePassed The time passed since this Keyframe began
270
271   \todo implement
272*/
273void Animation3D::cosine(float timePassed) const
274{
275  this->linear(timePassed);
276}
277
278/**
279   \brief an exponential interpolation between this keyframe and the next one
280   \param timePassed The time passed since this Keyframe began
281*/
282void Animation3D::exp(float timePassed) const
283{
284  this->linear(timePassed);
285}
286
287/**
288   \brief a negative exponential interpolation between this keyframe and the next one
289   \param timePassed The time passed since this Keyframe began
290
291   \todo implement
292*/
293void Animation3D::negExp(float timePassed) const
294{
295  this->object->setRelCoor( this->currentKeyFrame->position +
296                            (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
297                            (1.0 - expf(- timePassed * expFactor)) );
298}
299
300/*
301  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
302  float e = d * (1.0 - expf(- timePassed * expFactor));
303  return  this->currentKeyFrame->value - e;
304*/
305
306
307/**
308   \brief a quadratic interpolation between this keyframe and the next one
309   \param timePassed The time passed since this Keyframe began
310
311   \todo implement
312*/
313void Animation3D::quadratic(float timePassed) const
314{
315  this->linear(timePassed);
316}
317
318/**
319   \brief some random animation (fluctuating)
320   \param timePassed The time passed since this Keyframe began
321*/
322void Animation3D::random(float timePassed) const
323{
324  this->object->setRelCoor(this->currentKeyFrame->position + 
325                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
326  this->object->setRelDir(this->currentKeyFrame->direction +
327                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
328}
Note: See TracBrowser for help on using the repository browser.