Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved the animation-stuff to src/util/animation

File size: 8.3 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}
75
76/**
77   \brief Appends a new Keyframe
78   \param position The position of the new Keyframe
79   \param direction The direction of the new Keyframe.
80   \param duration The duration from the new KeyFrame to the next one
81   \param animFunc The function to animate between this keyFrame and the next one
82*/
83void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration, ANIM_FUNCTION animFunc)
84{
85  // some small check
86  if (duration <= 0.0)
87    duration = 1.0;
88
89  KeyFrame3D* tmpKeyFrame;
90   
91  if (bHasKeys)
92    {
93      tmpKeyFrame = new KeyFrame3D;
94      if (this->currentKeyFrame == this->nextKeyFrame)
95        this->nextKeyFrame = tmpKeyFrame;
96      this->keyFrameList->add(tmpKeyFrame);
97
98    }
99  else
100    {
101      tmpKeyFrame = this->keyFrameList->firstElement();
102      bHasKeys = true;
103      this->setAnimFunc(animFunc);
104    }
105
106  tmpKeyFrame->position = position;
107  tmpKeyFrame->direction = direction;
108  tmpKeyFrame->duration = duration;
109  tmpKeyFrame->animFunc = animFunc;
110
111}
112
113/**
114   \brief ticks the Animation
115   \param dt how much time to tick
116*/
117void Animation3D::tick(float dt)
118{
119  if (this->bRunning)
120    { 
121      this->localTime += dt;
122      if (localTime >= this->currentKeyFrame->duration)
123        {
124          // switching to the next Key-Frame
125          this->localTime -= this->currentKeyFrame->duration;
126          this->currentKeyFrame = this->nextKeyFrame;
127          // checking, if we should still Play the animation
128          if (this->currentKeyFrame == this->keyFrameList->lastElement())
129            this->handleInfinity();
130          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
131          this->setAnimFunc(this->currentKeyFrame->animFunc);     
132         
133          if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP)
134            {
135              this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
136              this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
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      break;
208    case ANIM_QUADRATIC:
209      this->animFunc = &Animation3D::quadratic;
210      break;
211    case ANIM_RANDOM:
212      this->animFunc = &Animation3D::random;
213      break;
214    }
215}
216
217/**
218   \brief stays at the value of the currentKeyFrame
219   \param timePassed The time passed since this Keyframe began
220*/
221void Animation3D::constant(float timePassed) const
222{
223  this->object->setRelCoor(this->currentKeyFrame->position);
224
225  /*
226    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
227    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
228    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
229    this->lastPosition = this->tmpVect;
230  */
231}
232
233/**
234   \brief linear interpolation between this keyframe and the next one
235   \param timePassed The time passed since this Keyframe began
236
237   \todo implement also do this for direction
238*/
239void Animation3D::linear(float timePassed) const
240{
241  this->object->setRelCoor(this->currentKeyFrame->position +
242                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
243                          (timePassed/this->currentKeyFrame->duration));
244}
245
246/**
247   \brief a Sinusodial Interpolation between this keyframe and the next one
248   \param timePassed The time passed since this Keyframe began
249
250   \todo implement
251*/
252void Animation3D::sine(float timePassed) const
253{
254  this->linear(timePassed);
255}
256
257/**
258   \brief a cosine interpolation between this keyframe and the next one
259   \param timePassed The time passed since this Keyframe began
260
261   \todo implement
262*/
263void Animation3D::cosine(float timePassed) const
264{
265  this->linear(timePassed);
266}
267
268/**
269   \brief an exponential interpolation between this keyframe and the next one
270   \param timePassed The time passed since this Keyframe began
271*/
272void Animation3D::exp(float timePassed) const
273{
274  this->linear(timePassed);
275}
276
277/**
278   \brief a negative exponential interpolation between this keyframe and the next one
279   \param timePassed The time passed since this Keyframe began
280
281   \todo implement
282*/
283void Animation3D::negExp(float timePassed) const
284{
285  this->linear(timePassed);
286}
287
288/**
289   \brief a quadratic interpolation between this keyframe and the next one
290   \param timePassed The time passed since this Keyframe began
291
292   \todo implement
293*/
294void Animation3D::quadratic(float timePassed) const
295{
296  this->linear(timePassed);
297}
298
299/**
300   \brief some random animation (fluctuating)
301   \param timePassed The time passed since this Keyframe began
302*/
303void Animation3D::random(float timePassed) const
304{
305  this->object->setRelCoor(this->currentKeyFrame->position * (float)rand()/(float)RAND_MAX);
306  this->object->setRelDir(this->currentKeyFrame->direction * (float)rand()/(float)RAND_MAX);
307}
Note: See TracBrowser for help on using the repository browser.