Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: animation3d cleaned up some code, deleted some old not used one

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