Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/animation3d.cc @ 3859

Last change on this file since 3859 was 3858, checked in by bensch, 20 years ago

orxonox/trunk: moved the infinity-handling into animation.cc

File size: 8.2 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
19
20#include "animation3d.h"
21
22#include "p_node.h"
23
24using namespace std;
25
[3855]26/**
27   \brief standard constructor
28*/
[3852]29Animation3D::Animation3D(PNode* object)
[3851]30{
[3852]31  this->object = object;
32
[3851]33  // create a new List
34  this->keyFrameList = new tList<KeyFrame3D>();
35  KeyFrame3D* tmpKeyFrame = new KeyFrame3D;
36  tmpKeyFrame->position = Vector();
37  tmpKeyFrame->direction = Quaternion();
38  keyFrameList->add(tmpKeyFrame);
39
40  this->currentKeyFrame = tmpKeyFrame;
41  this->nextKeyFrame = tmpKeyFrame;
42
43  this->animFunc = &Animation3D::linear;
44}
45
[3855]46/**
47   \brief standard deconstructor
48   
49   deletes all the Keyframes
50*/
[3851]51Animation3D::~Animation3D(void)
52{
53  // delete all the KeyFrames
54  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
55  KeyFrame3D*  enumKF = itKF->nextElement();
56  while (enumKF)
57    {
58      delete enumKF;
59      enumKF = itKF->nextElement();
60    }
61  delete itKF;
62  delete this->keyFrameList;
63}
64
[3855]65/**
66   \brief rewinds the Animation to the beginning (first KeyFrame and time == 0)
67*/
[3851]68void Animation3D::rewind(void)
69{
70  this->currentKeyFrame = keyFrameList->firstElement();
71  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
72  this->localTime = 0.0;
73}
74
[3855]75/**
76   \brief Appends a new Keyframe
77   \param position The position of the new Keyframe
78   \param direction The direction of the new Keyframe.
79   \param duration The duration from the new KeyFrame to the next one
80   \param animFunc The function to animate between this keyFrame and the next one
81*/
82void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration, ANIM_FUNCTION animFunc)
[3851]83{
84  // some small check
85  if (duration <= 0.0)
86    duration = 1.0;
87
88  KeyFrame3D* tmpKeyFrame;
89   
90  if (bHasKeys)
91    {
92      tmpKeyFrame = new KeyFrame3D;
93      if (this->currentKeyFrame == this->nextKeyFrame)
94        this->nextKeyFrame = tmpKeyFrame;
95      this->keyFrameList->add(tmpKeyFrame);
96
97    }
98  else
99    {
100      tmpKeyFrame = this->keyFrameList->firstElement();
101      bHasKeys = true;
102      this->setAnimFunc(animFunc);
103    }
104
105  tmpKeyFrame->position = position;
106  tmpKeyFrame->direction = direction;
107  tmpKeyFrame->duration = duration;
108  tmpKeyFrame->animFunc = animFunc;
109
110}
111
[3855]112/**
113   \brief ticks the Animation
114   \param dt how much time to tick
115*/
[3852]116void Animation3D::tick(float dt)
[3851]117{
118  if (this->bRunning)
119    { 
[3852]120      this->localTime += dt;
[3851]121      if (localTime >= this->currentKeyFrame->duration)
122        {
123          // switching to the next Key-Frame
124          this->localTime -= this->currentKeyFrame->duration;
125          this->currentKeyFrame = this->nextKeyFrame;
126          // checking, if we should still Play the animation
127          if (this->currentKeyFrame == this->keyFrameList->lastElement())
[3858]128            this->handleInfinity();
[3857]129          this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
[3851]130          this->setAnimFunc(this->currentKeyFrame->animFunc);     
131         
132          if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP)
133            {
134              this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
135              this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len());
136            }
137        }
138
139      /* now animate it */
140      (this->*animFunc)(this->localTime);
141      /*
142      switch( this->movMode)
143        {
144        case LINEAR:
145          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
146          *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
147          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
148          *this->lastPosition = *this->tmpVect;
149          break;
150        case EXP:
151             
152          break;
153        case NEG_EXP:
154          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
155          *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT));     
156          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
157          *this->lastPosition = *this->tmpVect;
158          break;
159        case SIN:
160          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
161          *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
162          this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
163          *this->lastPosition = *this->tmpVect;
164          break;
165        case COS:
166             
167          break;
168        case QUADRATIC:
169          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
170          *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
171          break;
172        default:
173          break;
174        }
175      */
176    }
177}
178
179
[3855]180/**
181   \brief Sets The kind of Animation between this keyframe and the next one
182   \param animFunc The Type of Animation to set
183*/
[3851]184void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
185{
186  switch (animFunc)
187    {
188    default:
189    case ANIM_CONSTANT:
190      this->animFunc = &Animation3D::constant;
191      break;
192    case ANIM_LINEAR:
193      this->animFunc = &Animation3D::linear;
194      break;
195    case ANIM_SINE:
196      this->animFunc = &Animation3D::sine;
197      break;
198    case ANIM_COSINE:
199      this->animFunc = &Animation3D::cosine;
200      break;
201    case ANIM_EXP:
202      this->animFunc = &Animation3D::exp;
203      break;
204    case ANIM_NEG_EXP:
205      this->animFunc = &Animation3D::negExp;
206      break;
207    case ANIM_QUADRATIC:
208      this->animFunc = &Animation3D::quadratic;
209      break;
210    case ANIM_RANDOM:
211      this->animFunc = &Animation3D::random;
212      break;
213    }
214}
215
[3855]216/**
217   \brief stays at the value of the currentKeyFrame
218   \param timePassed The time passed since this Keyframe began
219*/
[3852]220void Animation3D::constant(float timePassed) const
[3851]221{
[3852]222  this->object->setRelCoor(this->currentKeyFrame->position);
[3851]223
[3852]224  /*
225    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
226    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
227    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
228    this->lastPosition = this->tmpVect;
229  */
[3851]230}
231
[3855]232/**
233   \brief linear interpolation between this keyframe and the next one
234   \param timePassed The time passed since this Keyframe began
[3856]235
236   \todo implement also do this for direction
[3855]237*/
[3852]238void Animation3D::linear(float timePassed) const
[3851]239{
[3852]240  this->object->setRelCoor(this->currentKeyFrame->position +
241                          (this->nextKeyFrame->position - this->currentKeyFrame->position) * 
242                          (timePassed/this->currentKeyFrame->duration));
[3851]243}
244
[3855]245/**
246   \brief a Sinusodial Interpolation between this keyframe and the next one
247   \param timePassed The time passed since this Keyframe began
[3856]248
249   \todo implement
[3855]250*/
[3852]251void Animation3D::sine(float timePassed) const
[3851]252{
[3856]253  this->linear(timePassed);
[3851]254}
255
[3855]256/**
257   \brief a cosine interpolation between this keyframe and the next one
258   \param timePassed The time passed since this Keyframe began
[3856]259
260   \todo implement
[3855]261*/
[3852]262void Animation3D::cosine(float timePassed) const
[3851]263{
[3856]264  this->linear(timePassed);
[3851]265}
266
[3855]267/**
268   \brief an exponential interpolation between this keyframe and the next one
269   \param timePassed The time passed since this Keyframe began
270*/
[3852]271void Animation3D::exp(float timePassed) const
[3851]272{
[3856]273  this->linear(timePassed);
[3851]274}
275
[3855]276/**
277   \brief a negative exponential interpolation between this keyframe and the next one
278   \param timePassed The time passed since this Keyframe began
[3856]279
280   \todo implement
[3855]281*/
[3852]282void Animation3D::negExp(float timePassed) const
[3851]283{
[3855]284  this->linear(timePassed);
[3851]285}
286
[3855]287/**
288   \brief a quadratic interpolation between this keyframe and the next one
289   \param timePassed The time passed since this Keyframe began
[3856]290
291   \todo implement
[3855]292*/
[3852]293void Animation3D::quadratic(float timePassed) const
[3851]294{
[3856]295  this->linear(timePassed);
[3851]296}
297
[3855]298/**
299   \brief some random animation (fluctuating)
300   \param timePassed The time passed since this Keyframe began
301*/
[3852]302void Animation3D::random(float timePassed) const
[3851]303{
[3856]304  this->object->setRelCoor(this->currentKeyFrame->position * (float)rand()/(float)RAND_MAX);
305  this->object->setRelDir(this->currentKeyFrame->direction * (float)rand()/(float)RAND_MAX);
[3851]306}
Note: See TracBrowser for help on using the repository browser.