Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: rotation sine function implemented, looks very fancy

File size: 12.1 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->expFactor = -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 return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
256    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
257    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
258*/
259
260/**
261   \brief an exponential interpolation between this keyframe and the next one
262   \param timePassed The time passed since this Keyframe began
263*/
264void Animation3D::mExp(float timePassed) const
265{
266  PRINTF(0)("no exp animation3d defined\n");
267  this->mLinear(timePassed);
268}
269
270/**
271   \brief a negative exponential interpolation between this keyframe and the next one
272   \param timePassed The time passed since this Keyframe began
273*/
274void Animation3D::mNegExp(float timePassed) const
275{
276  this->object->setRelCoor( this->currentKeyFrame->position +
277                            (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
278                            (1.0 - expf(- timePassed * expFactor)) );
279}
280
281
282/**
283   \brief a quadratic interpolation between this keyframe and the next one
284   \param timePassed The time passed since this Keyframe began
285
286   \todo implement
287*/
288void Animation3D::mQuadratic(float timePassed) const
289{
290  PRINTF(0)("no quadratic animation3d defined\n");
291  this->mLinear(timePassed);
292}
293
294/**
295   \brief some random animation (fluctuating)
296   \param timePassed The time passed since this Keyframe began
297*/
298void Animation3D::mRandom(float timePassed) const
299{
300  this->object->setRelCoor(this->currentKeyFrame->position + 
301                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
302  this->object->setRelDir(this->currentKeyFrame->direction +
303                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
304}
305
306
307/*==Rotation Section==========================================================*/
308
309
310/**
311   \brief Sets The kind of rotation Animation between this keyframe and the next one
312   \param animFunc The Type of Animation to set
313*/
314void Animation3D::setAnimFuncRot(ANIM_FUNCTION animFuncRot)
315{
316  switch (animFuncRot)
317    {
318   default:
319    case ANIM_CONSTANT:
320      this->animFuncRot = &Animation3D::rConstant;
321      break;
322    case ANIM_LINEAR:
323      this->animFuncRot = &Animation3D::rLinear;
324      break;
325    case ANIM_SINE:
326      this->animFuncRot = &Animation3D::rSine;
327      break;
328    case ANIM_COSINE:
329      this->animFuncRot = &Animation3D::rCosine;
330      break;
331    case ANIM_EXP:
332      this->animFuncRot = &Animation3D::rExp;
333      break;
334    case ANIM_NEG_EXP:
335      this->animFuncRot = &Animation3D::rNegExp;
336      break;
337    case ANIM_QUADRATIC:
338      this->animFuncRot = &Animation3D::rQuadratic;
339      break;
340    case ANIM_RANDOM:
341      this->animFuncRot = &Animation3D::rRandom;
342      break;
343    }
344}
345
346
347/**
348   \brief stays at the value of the currentKeyFrame
349   \param timePassed The time passed since this Keyframe began
350*/
351void Animation3D::rConstant(float timePassed) const
352{
353}
354
355/**
356   \brief linear interpolation between this keyframe and the next one
357   \param timePassed The time passed since this Keyframe began
358
359   \todo implement also do this for direction
360*/
361void Animation3D::rLinear(float timePassed) const
362{
363  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
364                                     this->currentKeyFrame->direction, 
365                                     timePassed/this->currentKeyFrame->duration) );
366}
367
368/**
369   \brief a Sinusodial Interpolation between this keyframe and the next one
370   \param timePassed The time passed since this Keyframe began
371
372   \todo implement
373*/
374void Animation3D::rSine(float timePassed) const
375{
376  float scale;
377  if( timePassed < this->currentKeyFrame->duration / 2.0)
378    scale = sin( M_PI * timePassed / this->currentKeyFrame->duration);
379  else
380    scale = 1.0 - sin( M_PI * timePassed / this->currentKeyFrame->duration);
381
382  this->object->setRelDir(quatSlerp( this->nextKeyFrame->direction, 
383                                     this->currentKeyFrame->direction, 
384                                     scale) );
385}
386
387
388/**
389   \brief a cosine interpolation between this keyframe and the next one
390   \param timePassed The time passed since this Keyframe began
391
392   \todo implement
393*/
394void Animation3D::rCosine(float timePassed) const
395{
396}
397
398
399/*
400 return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
401    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
402    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
403*/
404
405/**
406   \brief an exponential interpolation between this keyframe and the next one
407   \param timePassed The time passed since this Keyframe began
408*/
409void Animation3D::rExp(float timePassed) const
410{
411
412}
413
414/**
415   \brief a negative exponential interpolation between this keyframe and the next one
416   \param timePassed The time passed since this Keyframe began
417*/
418void Animation3D::rNegExp(float timePassed) const
419{
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.