Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3978 was 3978, checked in by bensch, 21 years ago

orxonox/trunk: a Hack that enables setup of animation without giving both animation3D-addkeyframe-function attributes

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