Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3920 was 3876, checked in by bensch, 20 years ago

orxonox/trunk: rearanged keyFrame-addition

File size: 8.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
44  this->animFunc = &Animation3D::linear;
45}
46
[3855]47/**
48   \brief standard deconstructor
49   
50   deletes all the Keyframes
51*/
[3851]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
[3855]66/**
67   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
68*/
[3851]69void Animation3D::rewind(void)
70{
71  this->currentKeyFrame = keyFrameList->firstElement();
72  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
73  this->localTime = 0.0;
[3872]74  this->setAnimFunc(this->currentKeyFrame->animFunc);
[3851]75}
76
[3855]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)
[3851]85{
86  // some small check
87  if (duration <= 0.0)
88    duration = 1.0;
89
90  KeyFrame3D* tmpKeyFrame;
91   
[3876]92  // when adding the first frame
93  if (this->keyFrameCount == 0)
[3851]94    {
[3876]95      tmpKeyFrame = this->keyFrameList->firstElement();
96      this->setAnimFunc(animFunc);
97    }
98  else
99    {
[3851]100      tmpKeyFrame = new KeyFrame3D;
[3876]101      // when adding the second frame
[3851]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;
[3876]111  this->keyFrameCount++;
[3851]112}
113
[3855]114/**
115   \brief ticks the Animation
116   \param dt how much time to tick
117*/
[3852]118void Animation3D::tick(float dt)
[3851]119{
120  if (this->bRunning)
121    { 
[3852]122      this->localTime += dt;
[3851]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())
[3858]130            this->handleInfinity();
[3857]131          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
[3851]132          this->setAnimFunc(this->currentKeyFrame->animFunc);     
133         
134          if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP)
135            {
136              this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
137              this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
138            }
139        }
140
141      /* now animate it */
142      (this->*animFunc)(this->localTime);
143      /*
144      switch( this->movMode)
145        {
146        case LINEAR:
147          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
148          *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
149          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
150          *this->lastPosition = *this->tmpVect;
151          break;
152        case EXP:
153             
154          break;
155        case NEG_EXP:
156          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
157          *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT));     
158          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
159          *this->lastPosition = *this->tmpVect;
160          break;
161        case SIN:
162          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
163          *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
164          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
165          *this->lastPosition = *this->tmpVect;
166          break;
167        case COS:
168             
169          break;
170        case QUADRATIC:
171          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
172          *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
173          break;
174        default:
175          break;
176        }
177      */
178    }
179}
180
181
[3855]182/**
183   \brief Sets The kind of Animation between this keyframe and the next one
184   \param animFunc The Type of Animation to set
185*/
[3851]186void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
187{
188  switch (animFunc)
189    {
190    default:
191    case ANIM_CONSTANT:
192      this->animFunc = &Animation3D::constant;
193      break;
194    case ANIM_LINEAR:
195      this->animFunc = &Animation3D::linear;
196      break;
197    case ANIM_SINE:
198      this->animFunc = &Animation3D::sine;
199      break;
200    case ANIM_COSINE:
201      this->animFunc = &Animation3D::cosine;
202      break;
203    case ANIM_EXP:
204      this->animFunc = &Animation3D::exp;
205      break;
206    case ANIM_NEG_EXP:
207      this->animFunc = &Animation3D::negExp;
208      break;
209    case ANIM_QUADRATIC:
210      this->animFunc = &Animation3D::quadratic;
211      break;
212    case ANIM_RANDOM:
213      this->animFunc = &Animation3D::random;
214      break;
215    }
216}
217
[3855]218/**
219   \brief stays at the value of the currentKeyFrame
220   \param timePassed The time passed since this Keyframe began
221*/
[3852]222void Animation3D::constant(float timePassed) const
[3851]223{
[3852]224  this->object->setRelCoor(this->currentKeyFrame->position);
[3851]225
[3852]226  /*
227    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
228    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
229    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
230    this->lastPosition = this->tmpVect;
231  */
[3851]232}
233
[3855]234/**
235   \brief linear interpolation between this keyframe and the next one
236   \param timePassed The time passed since this Keyframe began
[3856]237
238   \todo implement also do this for direction
[3855]239*/
[3852]240void Animation3D::linear(float timePassed) const
[3851]241{
[3852]242  this->object->setRelCoor(this->currentKeyFrame->position +
243                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
244                          (timePassed/this->currentKeyFrame->duration));
[3851]245}
246
[3855]247/**
248   \brief a Sinusodial Interpolation between this keyframe and the next one
249   \param timePassed The time passed since this Keyframe began
[3856]250
251   \todo implement
[3855]252*/
[3852]253void Animation3D::sine(float timePassed) const
[3851]254{
[3856]255  this->linear(timePassed);
[3851]256}
257
[3855]258/**
259   \brief a cosine interpolation between this keyframe and the next one
260   \param timePassed The time passed since this Keyframe began
[3856]261
262   \todo implement
[3855]263*/
[3852]264void Animation3D::cosine(float timePassed) const
[3851]265{
[3856]266  this->linear(timePassed);
[3851]267}
268
[3855]269/**
270   \brief an exponential interpolation between this keyframe and the next one
271   \param timePassed The time passed since this Keyframe began
272*/
[3852]273void Animation3D::exp(float timePassed) const
[3851]274{
[3856]275  this->linear(timePassed);
[3851]276}
277
[3855]278/**
279   \brief a negative exponential interpolation between this keyframe and the next one
280   \param timePassed The time passed since this Keyframe began
[3856]281
282   \todo implement
[3855]283*/
[3852]284void Animation3D::negExp(float timePassed) const
[3851]285{
[3855]286  this->linear(timePassed);
[3851]287}
288
[3855]289/**
290   \brief a quadratic interpolation between this keyframe and the next one
291   \param timePassed The time passed since this Keyframe began
[3856]292
293   \todo implement
[3855]294*/
[3852]295void Animation3D::quadratic(float timePassed) const
[3851]296{
[3856]297  this->linear(timePassed);
[3851]298}
299
[3855]300/**
301   \brief some random animation (fluctuating)
302   \param timePassed The time passed since this Keyframe began
303*/
[3852]304void Animation3D::random(float timePassed) const
[3851]305{
[3874]306  this->object->setRelCoor(this->currentKeyFrame->position + 
307                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
308  this->object->setRelDir(this->currentKeyFrame->direction +
309                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
[3851]310}
Note: See TracBrowser for help on using the repository browser.