Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: implemented neg_exp rotation also now

File size: 12.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->animFuncMov = &Animation3D::mLinear;
45  this->animFuncRot = &Animation3D::rLinear;
46}
47
48/**
49   \brief standard deconstructor
50   
51   deletes all the Keyframes
52*/
53Animation3D::~Animation3D(void)
54{
55  // delete all the KeyFrames
56  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
57  KeyFrame3D*  enumKF = itKF->nextElement();
58  while (enumKF)
59    {
60      delete enumKF;
61      enumKF = itKF->nextElement();
62    }
63  delete itKF;
64  delete this->keyFrameList;
65}
66
67/**
68   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
69*/
70void Animation3D::rewind(void)
71{
72  this->currentKeyFrame = keyFrameList->firstElement();
73  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
74  this->localTime = 0.0;
75  this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
76  this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
77}
78
79/**
80   \brief Appends a new Keyframe
81   \param position The position of the new Keyframe
82   \param direction The direction of the new Keyframe.
83   \param duration The duration from the new KeyFrame to the next one
84   \param animFunc The function to animate between this keyFrame and the next one
85*/
86void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration, ANIM_FUNCTION animFuncMov, ANIM_FUNCTION animFuncRot)
87{
88  // some small check
89  if (duration <= 0.0)
90    duration = 1.0;
91
92  KeyFrame3D* tmpKeyFrame;
93   
94  // when adding the first frame
95  if (this->keyFrameCount == 0)
96    {
97      tmpKeyFrame = this->keyFrameList->firstElement();
98      this->setAnimFuncMov(animFuncMov);
99      this->setAnimFuncRot(animFuncRot);
100    }
101  else
102    {
103      tmpKeyFrame = new KeyFrame3D;
104      // when adding the second frame
105      if (this->currentKeyFrame == this->nextKeyFrame)
106        this->nextKeyFrame = tmpKeyFrame;
107      this->keyFrameList->add(tmpKeyFrame);
108    }
109
110  tmpKeyFrame->position = position;
111  tmpKeyFrame->direction = direction;
112  tmpKeyFrame->duration = duration;
113  tmpKeyFrame->animFuncMov = animFuncMov;
114  tmpKeyFrame->animFuncRot = animFuncRot;
115  this->keyFrameCount++;
116}
117
118
119
120/**
121   \brief ticks the Animation
122   \param dt how much time to tick
123*/
124void Animation3D::tick(float dt)
125{
126  if (this->bRunning)
127    { 
128      this->localTime += dt;
129      if (localTime >= this->currentKeyFrame->duration)
130        {
131          // switching to the next Key-Frame
132          this->localTime -= this->currentKeyFrame->duration;
133          this->currentKeyFrame = this->nextKeyFrame;
134          // checking, if we should still Play the animation
135          if (this->currentKeyFrame == this->keyFrameList->lastElement())
136            this->handleInfinity();
137          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
138          this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
139          this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
140        }
141      /* now animate it */
142      (this->*animFuncMov)(this->localTime);
143      (this->*animFuncRot)(this->localTime);
144    }
145}
146
147
148/*==Movement Section==========================================================*/
149
150/**
151   \brief Sets The kind of movment Animation between this keyframe and the next one
152   \param animFunc The Type of Animation to set
153*/
154void Animation3D::setAnimFuncMov(ANIM_FUNCTION animFuncMov)
155{
156  switch (animFuncMov)
157    {
158    default:
159    case ANIM_CONSTANT:
160      this->animFuncMov = &Animation3D::mConstant;
161      break;
162    case ANIM_LINEAR:
163      this->animFuncMov = &Animation3D::mLinear;
164      break;
165    case ANIM_SINE:
166      this->animFuncMov = &Animation3D::mSine;
167      break;
168    case ANIM_COSINE:
169      this->animFuncMov = &Animation3D::mCosine;
170      break;
171    case ANIM_EXP:
172      this->animFuncMov = &Animation3D::mExp;
173      break;
174    case ANIM_NEG_EXP:
175      this->animFuncMov = &Animation3D::mNegExp;
176      this->expFactorMov = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
177      break;
178    case ANIM_QUADRATIC:
179      this->animFuncMov = &Animation3D::mQuadratic;
180      break;
181    case ANIM_RANDOM:
182      this->animFuncMov = &Animation3D::mRandom;
183      break;
184    }
185}
186
187
188
189/**
190   \brief stays at the value of the currentKeyFrame
191   \param timePassed The time passed since this Keyframe began
192*/
193void Animation3D::mConstant(float timePassed) const
194{
195  this->object->setRelCoor(this->currentKeyFrame->position);
196
197  /*
198    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
199    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
200    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
201    this->lastPosition = this->tmpVect;
202  */
203}
204
205/**
206   \brief linear interpolation between this keyframe and the next one
207   \param timePassed The time passed since this Keyframe began
208
209   \todo implement also do this for direction
210*/
211void Animation3D::mLinear(float timePassed) const
212{
213  this->object->setRelCoor(this->currentKeyFrame->position +
214                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
215                          (timePassed/this->currentKeyFrame->duration));
216
217  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
218                                     this->currentKeyFrame->direction, 
219                                     timePassed/this->currentKeyFrame->duration) );
220
221}
222
223/**
224   \brief a Sinusodial Interpolation between this keyframe and the next one
225   \param timePassed The time passed since this Keyframe began
226
227   \todo implement
228*/
229void Animation3D::mSine(float timePassed) const
230{
231  if( timePassed  < this->currentKeyFrame->duration/2.0)
232    this->object->setRelCoor( this->currentKeyFrame->position + (this->nextKeyFrame->position - this->currentKeyFrame->position) *
233                              sin( M_PI * timePassed /this->currentKeyFrame->duration) / 2.0);
234  else
235    this->object->setRelCoor( this->nextKeyFrame->position - (this->nextKeyFrame->position - this->currentKeyFrame->position) *
236                              sin( M_PI * (1.0 - timePassed /this->currentKeyFrame->duration) )/2.0);
237}
238
239
240/**
241   \brief a cosine interpolation between this keyframe and the next one
242   \param timePassed The time passed since this Keyframe began
243
244   \todo implement
245*/
246void Animation3D::mCosine(float timePassed) const
247{
248  this->object->setRelCoor( this->nextKeyFrame->position -
249                            (this->nextKeyFrame->position - this->currentKeyFrame->position) *
250                            (1.0 + cos( M_PI * timePassed / this->currentKeyFrame->duration))/2.0);
251}
252
253
254
255/**
256   \brief an exponential interpolation between this keyframe and the next one
257   \param timePassed The time passed since this Keyframe began
258*/
259void Animation3D::mExp(float timePassed) const
260{
261  PRINTF(0)("no exp animation3d defined\n");
262  this->mLinear(timePassed);
263}
264
265/**
266   \brief a negative exponential interpolation between this keyframe and the next one
267   \param timePassed The time passed since this Keyframe began
268*/
269void Animation3D::mNegExp(float timePassed) const
270{
271  this->object->setRelCoor( this->currentKeyFrame->position +
272                            (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
273                            (1.0 - expf(- timePassed * expFactorMov)) );
274}
275
276
277/**
278   \brief a quadratic 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::mQuadratic(float timePassed) const
284{
285  PRINTF(0)("no quadratic animation3d defined\n");
286  this->mLinear(timePassed);
287}
288
289/**
290   \brief some random animation (fluctuating)
291   \param timePassed The time passed since this Keyframe began
292*/
293void Animation3D::mRandom(float timePassed) const
294{
295  this->object->setRelCoor(this->currentKeyFrame->position + 
296                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
297  this->object->setRelDir(this->currentKeyFrame->direction +
298                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
299}
300
301
302/*==Rotation Section==========================================================*/
303
304
305/**
306   \brief Sets The kind of rotation Animation between this keyframe and the next one
307   \param animFunc The Type of Animation to set
308*/
309void Animation3D::setAnimFuncRot(ANIM_FUNCTION animFuncRot)
310{
311  switch (animFuncRot)
312    {
313   default:
314    case ANIM_CONSTANT:
315      this->animFuncRot = &Animation3D::rConstant;
316      break;
317    case ANIM_LINEAR:
318      this->animFuncRot = &Animation3D::rLinear;
319      break;
320    case ANIM_SINE:
321      this->animFuncRot = &Animation3D::rSine;
322      break;
323    case ANIM_COSINE:
324      this->animFuncRot = &Animation3D::rCosine;
325      break;
326    case ANIM_EXP:
327      this->animFuncRot = &Animation3D::rExp;
328      break;
329    case ANIM_NEG_EXP:
330      this->animFuncRot = &Animation3D::rNegExp;
331      this->expFactorRot = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
332      break;
333    case ANIM_QUADRATIC:
334      this->animFuncRot = &Animation3D::rQuadratic;
335      break;
336    case ANIM_RANDOM:
337      this->animFuncRot = &Animation3D::rRandom;
338      break;
339    }
340}
341
342
343/**
344   \brief stays at the value of the currentKeyFrame
345   \param timePassed The time passed since this Keyframe began
346*/
347void Animation3D::rConstant(float timePassed) const
348{
349  this->object->setRelDir(this->currentKeyFrame->direction);
350}
351
352/**
353   \brief linear interpolation between this keyframe and the next one
354   \param timePassed The time passed since this Keyframe began
355
356   \todo implement also do this for direction
357*/
358void Animation3D::rLinear(float timePassed) const
359{
360  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
361                                     this->currentKeyFrame->direction, 
362                                     timePassed/this->currentKeyFrame->duration) );
363}
364
365/**
366   \brief a Sinusodial Interpolation between this keyframe and the next one
367   \param timePassed The time passed since this Keyframe began
368
369   \todo implement
370*/
371void Animation3D::rSine(float timePassed) const
372{
373  float scale;
374  if( timePassed < this->currentKeyFrame->duration / 2.0)
375    scale = sin( M_PI * timePassed / this->currentKeyFrame->duration);
376  else
377    scale = 1.0 - sin( M_PI * timePassed / this->currentKeyFrame->duration);
378
379  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
380                                     this->currentKeyFrame->direction, 
381                                     scale) );
382}
383
384
385/**
386   \brief a cosine interpolation between this keyframe and the next one
387   \param timePassed The time passed since this Keyframe began
388
389   \todo implement
390*/
391void Animation3D::rCosine(float timePassed) const
392{
393  float scale = cos(M_PI * timePassed / this->currentKeyFrame->duration);
394  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
395                                     this->currentKeyFrame->direction, 
396                                     scale) );
397}
398
399
400
401/**
402   \brief an exponential interpolation between this keyframe and the next one
403   \param timePassed The time passed since this Keyframe began
404*/
405void Animation3D::rExp(float timePassed) const
406{
407
408}
409
410/**
411   \brief a negative exponential interpolation between this keyframe and the next one
412   \param timePassed The time passed since this Keyframe began
413*/
414void Animation3D::rNegExp(float timePassed) const
415{
416  float scale = (1.0 - expf(- timePassed * expFactorRot));
417  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
418                                     this->currentKeyFrame->direction, 
419                                     scale) );
420}
421
422
423/**
424   \brief a quadratic interpolation between this keyframe and the next one
425   \param timePassed The time passed since this Keyframe began
426
427   \todo implement
428*/
429void Animation3D::rQuadratic(float timePassed) const
430{
431}
432
433/**
434   \brief some random animation (fluctuating)
435   \param timePassed The time passed since this Keyframe began
436*/
437void Animation3D::rRandom(float timePassed) const
438{
439}
Note: See TracBrowser for help on using the repository browser.