Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: animation3d ANIM_SINE is now finaly working also. looks nice

File size: 9.8 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  if( timePassed  < this->currentKeyFrame->duration/2.0)
265    this->object->setRelCoor( this->currentKeyFrame->position + (this->nextKeyFrame->position - this->currentKeyFrame->position) *
266                              sin( M_PI * timePassed /this->currentKeyFrame->duration) / 2.0);
267  else
268    this->object->setRelCoor( this->nextKeyFrame->position - (this->nextKeyFrame->position - this->currentKeyFrame->position) *
269                              sin( M_PI * (1.0 - timePassed /this->currentKeyFrame->duration) )/2.0);
270}
271
272
273/*
274  if (timePassed * 2.0 < this->currentKeyFrame->duration)
275    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
276      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
277  else
278    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
279      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
280
281*/
282
283/**
284   \brief a cosine interpolation between this keyframe and the next one
285   \param timePassed The time passed since this Keyframe began
286
287   \todo implement
288*/
289void Animation3D::cosine(float timePassed) const
290{
291  this->linear(timePassed);
292}
293
294/**
295   \brief an exponential interpolation between this keyframe and the next one
296   \param timePassed The time passed since this Keyframe began
297*/
298void Animation3D::exp(float timePassed) const
299{
300  this->linear(timePassed);
301}
302
303/**
304   \brief a negative exponential interpolation between this keyframe and the next one
305   \param timePassed The time passed since this Keyframe began
306*/
307void Animation3D::negExp(float timePassed) const
308{
309  this->object->setRelCoor( this->currentKeyFrame->position +
310                            (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
311                            (1.0 - expf(- timePassed * expFactor)) );
312}
313
314
315/**
316   \brief a quadratic interpolation between this keyframe and the next one
317   \param timePassed The time passed since this Keyframe began
318
319   \todo implement
320*/
321void Animation3D::quadratic(float timePassed) const
322{
323  this->linear(timePassed);
324}
325
326/**
327   \brief some random animation (fluctuating)
328   \param timePassed The time passed since this Keyframe began
329*/
330void Animation3D::random(float timePassed) const
331{
332  this->object->setRelCoor(this->currentKeyFrame->position + 
333                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
334  this->object->setRelDir(this->currentKeyFrame->direction +
335                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
336}
Note: See TracBrowser for help on using the repository browser.