Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: rearanged keyFrame-addition

File size: 8.5 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              this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
137              this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
138            }
139        }
140
141      /* now animate it */
142      (this->*animFunc)(this->localTime);
143      /*
144      switch( this->movMode)
145        {
146        case LINEAR:
147          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
148          *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
149          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
150          *this->lastPosition = *this->tmpVect;
151          break;
152        case EXP:
153             
154          break;
155        case NEG_EXP:
156          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
157          *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT));     
158          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
159          *this->lastPosition = *this->tmpVect;
160          break;
161        case SIN:
162          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
163          *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
164          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
165          *this->lastPosition = *this->tmpVect;
166          break;
167        case COS:
168             
169          break;
170        case QUADRATIC:
171          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
172          *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
173          break;
174        default:
175          break;
176        }
177      */
178    }
179}
180
181
182/**
183   \brief Sets The kind of Animation between this keyframe and the next one
184   \param animFunc The Type of Animation to set
185*/
186void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
187{
188  switch (animFunc)
189    {
190    default:
191    case ANIM_CONSTANT:
192      this->animFunc = &Animation3D::constant;
193      break;
194    case ANIM_LINEAR:
195      this->animFunc = &Animation3D::linear;
196      break;
197    case ANIM_SINE:
198      this->animFunc = &Animation3D::sine;
199      break;
200    case ANIM_COSINE:
201      this->animFunc = &Animation3D::cosine;
202      break;
203    case ANIM_EXP:
204      this->animFunc = &Animation3D::exp;
205      break;
206    case ANIM_NEG_EXP:
207      this->animFunc = &Animation3D::negExp;
208      break;
209    case ANIM_QUADRATIC:
210      this->animFunc = &Animation3D::quadratic;
211      break;
212    case ANIM_RANDOM:
213      this->animFunc = &Animation3D::random;
214      break;
215    }
216}
217
218/**
219   \brief stays at the value of the currentKeyFrame
220   \param timePassed The time passed since this Keyframe began
221*/
222void Animation3D::constant(float timePassed) const
223{
224  this->object->setRelCoor(this->currentKeyFrame->position);
225
226  /*
227    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
228    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
229    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
230    this->lastPosition = this->tmpVect;
231  */
232}
233
234/**
235   \brief linear interpolation between this keyframe and the next one
236   \param timePassed The time passed since this Keyframe began
237
238   \todo implement also do this for direction
239*/
240void Animation3D::linear(float timePassed) const
241{
242  this->object->setRelCoor(this->currentKeyFrame->position +
243                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
244                          (timePassed/this->currentKeyFrame->duration));
245}
246
247/**
248   \brief a Sinusodial Interpolation between this keyframe and the next one
249   \param timePassed The time passed since this Keyframe began
250
251   \todo implement
252*/
253void Animation3D::sine(float timePassed) const
254{
255  this->linear(timePassed);
256}
257
258/**
259   \brief a cosine interpolation between this keyframe and the next one
260   \param timePassed The time passed since this Keyframe began
261
262   \todo implement
263*/
264void Animation3D::cosine(float timePassed) const
265{
266  this->linear(timePassed);
267}
268
269/**
270   \brief an exponential interpolation between this keyframe and the next one
271   \param timePassed The time passed since this Keyframe began
272*/
273void Animation3D::exp(float timePassed) const
274{
275  this->linear(timePassed);
276}
277
278/**
279   \brief a negative exponential interpolation between this keyframe and the next one
280   \param timePassed The time passed since this Keyframe began
281
282   \todo implement
283*/
284void Animation3D::negExp(float timePassed) const
285{
286  this->linear(timePassed);
287}
288
289/**
290   \brief a quadratic interpolation between this keyframe and the next one
291   \param timePassed The time passed since this Keyframe began
292
293   \todo implement
294*/
295void Animation3D::quadratic(float timePassed) const
296{
297  this->linear(timePassed);
298}
299
300/**
301   \brief some random animation (fluctuating)
302   \param timePassed The time passed since this Keyframe began
303*/
304void Animation3D::random(float timePassed) const
305{
306  this->object->setRelCoor(this->currentKeyFrame->position + 
307                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
308  this->object->setRelDir(this->currentKeyFrame->direction +
309                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
310}
Note: See TracBrowser for help on using the repository browser.