Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/animation3d.cc @ 3857

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

orxonox/trunk: ANIM_INF_REWIND mode works

File size: 8.4 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
20#include "animation3d.h"
21
22#include "p_node.h"
23
24using namespace std;
25
26/**
27   \brief standard constructor
28*/
29Animation3D::Animation3D(PNode* object)
30{
31  this->object = object;
32
33  // create a new List
34  this->keyFrameList = new tList<KeyFrame3D>();
35  KeyFrame3D* tmpKeyFrame = new KeyFrame3D;
36  tmpKeyFrame->position = Vector();
37  tmpKeyFrame->direction = Quaternion();
38  keyFrameList->add(tmpKeyFrame);
39
40  this->currentKeyFrame = tmpKeyFrame;
41  this->nextKeyFrame = tmpKeyFrame;
42
43  this->animFunc = &Animation3D::linear;
44}
45
46/**
47   \brief standard deconstructor
48   
49   deletes all the Keyframes
50*/
51Animation3D::~Animation3D(void)
52{
53  // delete all the KeyFrames
54  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
55  KeyFrame3D*  enumKF = itKF->nextElement();
56  while (enumKF)
57    {
58      delete enumKF;
59      enumKF = itKF->nextElement();
60    }
61  delete itKF;
62  delete this->keyFrameList;
63}
64
65/**
66   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
67*/
68void Animation3D::rewind(void)
69{
70  this->currentKeyFrame = keyFrameList->firstElement();
71  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
72  this->localTime = 0.0;
73}
74
75/**
76   \brief Appends a new Keyframe
77   \param position The position of the new Keyframe
78   \param direction The direction of the new Keyframe.
79   \param duration The duration from the new KeyFrame to the next one
80   \param animFunc The function to animate between this keyFrame and the next one
81*/
82void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration, ANIM_FUNCTION animFunc)
83{
84  // some small check
85  if (duration <= 0.0)
86    duration = 1.0;
87
88  KeyFrame3D* tmpKeyFrame;
89   
90  if (bHasKeys)
91    {
92      tmpKeyFrame = new KeyFrame3D;
93      if (this->currentKeyFrame == this->nextKeyFrame)
94        this->nextKeyFrame = tmpKeyFrame;
95      this->keyFrameList->add(tmpKeyFrame);
96
97    }
98  else
99    {
100      tmpKeyFrame = this->keyFrameList->firstElement();
101      bHasKeys = true;
102      this->setAnimFunc(animFunc);
103    }
104
105  tmpKeyFrame->position = position;
106  tmpKeyFrame->direction = direction;
107  tmpKeyFrame->duration = duration;
108  tmpKeyFrame->animFunc = animFunc;
109
110}
111
112/**
113   \brief ticks the Animation
114   \param dt how much time to tick
115*/
116void Animation3D::tick(float dt)
117{
118  if (this->bRunning)
119    { 
120      this->localTime += dt;
121      if (localTime >= this->currentKeyFrame->duration)
122        {
123          // switching to the next Key-Frame
124          this->localTime -= this->currentKeyFrame->duration;
125          this->currentKeyFrame = this->nextKeyFrame;
126          // checking, if we should still Play the animation
127          if (this->currentKeyFrame == this->keyFrameList->lastElement())
128            {
129              switch (this->postInfinity)
130                {
131                case ANIM_INF_CONSTANT:
132                  this->localTime = 0.0;
133                  this->bRunning = false;
134                  break;
135                case ANIM_INF_REWIND:
136                  this->replay();
137                  break;
138                }
139            }
140          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
141          this->setAnimFunc(this->currentKeyFrame->animFunc);     
142         
143          if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP)
144            {
145              this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
146              this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
147            }
148        }
149
150      /* now animate it */
151      (this->*animFunc)(this->localTime);
152      /*
153      switch( this->movMode)
154        {
155        case LINEAR:
156          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
157          *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
158          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
159          *this->lastPosition = *this->tmpVect;
160          break;
161        case EXP:
162             
163          break;
164        case NEG_EXP:
165          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
166          *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT));     
167          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
168          *this->lastPosition = *this->tmpVect;
169          break;
170        case SIN:
171          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
172          *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
173          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
174          *this->lastPosition = *this->tmpVect;
175          break;
176        case COS:
177             
178          break;
179        case QUADRATIC:
180          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
181          *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
182          break;
183        default:
184          break;
185        }
186      */
187    }
188}
189
190
191/**
192   \brief Sets The kind of Animation between this keyframe and the next one
193   \param animFunc The Type of Animation to set
194*/
195void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
196{
197  switch (animFunc)
198    {
199    default:
200    case ANIM_CONSTANT:
201      this->animFunc = &Animation3D::constant;
202      break;
203    case ANIM_LINEAR:
204      this->animFunc = &Animation3D::linear;
205      break;
206    case ANIM_SINE:
207      this->animFunc = &Animation3D::sine;
208      break;
209    case ANIM_COSINE:
210      this->animFunc = &Animation3D::cosine;
211      break;
212    case ANIM_EXP:
213      this->animFunc = &Animation3D::exp;
214      break;
215    case ANIM_NEG_EXP:
216      this->animFunc = &Animation3D::negExp;
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->linear(timePassed);
296}
297
298/**
299   \brief a quadratic interpolation between this keyframe and the next one
300   \param timePassed The time passed since this Keyframe began
301
302   \todo implement
303*/
304void Animation3D::quadratic(float timePassed) const
305{
306  this->linear(timePassed);
307}
308
309/**
310   \brief some random animation (fluctuating)
311   \param timePassed The time passed since this Keyframe began
312*/
313void Animation3D::random(float timePassed) const
314{
315  this->object->setRelCoor(this->currentKeyFrame->position * (float)rand()/(float)RAND_MAX);
316  this->object->setRelDir(this->currentKeyFrame->direction * (float)rand()/(float)RAND_MAX);
317}
Note: See TracBrowser for help on using the repository browser.