Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/simple_animation.cc @ 3850

Last change on this file since 3850 was 3850, checked in by bensch, 19 years ago

orxonox/trunk: added some functions (for function pointers) to the Animation3D class

File size: 11.5 KB
Line 
1
2
3
4/*
5   orxonox - the future of 3D-vertical-scrollers
6
7   Copyright (C) 2004 orx
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2, or (at your option)
12   any later version.
13
14   ### File Specific:
15   main-programmer: Patrick Boenzli
16   co-programmer: ...
17*/
18
19
20#include "simple_animation.h"
21#include "stdincl.h"
22#include "vector.h"
23#include "world_entity.h"
24
25using namespace std;
26
27
28Animation3D::Animation3D(void)
29{
30
31}
32
33Animation3D::~Animation3D(void)
34{
35
36}
37
38
39void Animation3D::rewind(void)
40{
41
42}
43
44void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc)
45{
46  switch (animFunc)
47    {
48    default:
49    case ANIM_CONSTANT:
50      this->animFunc = &Animation3D::constant;
51      break;
52    case ANIM_LINEAR:
53      this->animFunc = &Animation3D::linear;
54      break;
55    case ANIM_SINE:
56      this->animFunc = &Animation3D::sine;
57      break;
58    case ANIM_COSINE:
59      this->animFunc = &Animation3D::cosine;
60      break;
61    case ANIM_EXP:
62      this->animFunc = &Animation3D::exp;
63      break;
64    case ANIM_NEG_EXP:
65      this->animFunc = &Animation3D::negExp;
66      break;
67    case ANIM_QUADRATIC:
68      this->animFunc = &Animation3D::quadratic;
69      break;
70    case ANIM_RANDOM:
71      this->animFunc = &Animation3D::random;
72      break;
73    }
74}
75
76
77void Animation3D::tick(float timePassed)
78{
79
80}
81
82
83float Animation3D::constant(float timePassed) const
84{
85
86}
87
88float Animation3D::linear(float timePassed) const
89{
90
91}
92
93float Animation3D::sine(float timePassed) const
94{
95
96}
97
98float Animation3D::cosine(float timePassed) const
99{
100
101}
102
103float Animation3D::exp(float timePassed) const
104{
105
106}
107
108float Animation3D::negExp(float timePassed) const
109{
110
111}
112
113float Animation3D::quadratic(float timePassed) const
114{
115
116}
117
118float Animation3D::random(float timePassed) const
119{
120
121}
122
123
124
125
126
127
128SimpleAnimation* SimpleAnimation::singletonRef = 0;
129/**
130   \brief gets the singleton instance
131   \returns singleton instance
132*/
133SimpleAnimation* SimpleAnimation::getInstance()
134{
135  if( singletonRef == NULL)
136    singletonRef = new SimpleAnimation();
137  return singletonRef;
138}
139
140/**
141   \brief standard constructor
142*/
143SimpleAnimation::SimpleAnimation () 
144{
145   this->setClassName ("SimpleAnimation");
146   this->frames = new tList<KeyFrame3D>();
147   this->animators = new tList<Animation3D>();
148   this->localTime = 0;
149   this->bRunning = false;
150   this->currentFrame = NULL;
151   this->lastFrame = NULL;
152
153   this->tmpVect = new Vector();
154   this->lastPosition = new Vector();
155   this->deltaT = 0.2;
156}
157
158
159/**
160   \brief standard deconstructor
161
162*/
163SimpleAnimation::~SimpleAnimation () 
164{
165  tIterator<KeyFrame3D>* iterator = this->frames->getIterator();
166  KeyFrame3D* frame = iterator->nextElement(); 
167  while( frame != NULL) 
168    { 
169      delete frame;
170      frame = iterator->nextElement();
171    }
172  delete iterator;
173  delete this->frames;
174  singletonRef = NULL;
175}
176
177
178/**
179   \brief this determines the start of an Animator Describtion
180
181   this can then be followed by different commands like addKeyFrame(..) etc. and
182   will be closed with AnimatiorEnd()
183*/
184void SimpleAnimation::animatorBegin()
185{
186  this->bDescriptive = true;
187}
188
189
190/**
191   \brief this determines the end of an Animator Describtion
192
193   this can then be followed by different commands like addKeyFrame(..) etc. and
194   will be closed with AnimatiorEnd()
195*/
196void SimpleAnimation::animatorEnd()
197{
198  this->workingObject = NULL;
199  this->workingAnimator = NULL;
200  this->bDescriptive = false;
201}
202
203
204/*
205  Vector* lastPosition;
206  Vector* tmpVect;
207  tList<KeyFrame3D>* frames;
208  animationMode animMode;
209  movementMode movMode;
210  bool bRunning;
211  float deltaT;
212*/
213
214/**
215   \brief select an object to work on by using this function
216   \param object wo work on
217*/
218void SimpleAnimation::selectObject(WorldEntity* entity)
219{
220  Animation3D* anim = getAnimationFromWorldEntity(entity);
221  if( anim == NULL)
222    {
223      anim = new Animation3D;
224      anim->object = entity;
225      anim->lastPosition = new Vector();
226      anim->tmpVect = new Vector();
227      anim->frames = new tList<KeyFrame3D>();
228      anim->animMode = LOOP;
229      anim->bRunning = false;
230      deltaT = 0.0;
231      this->animators->add(anim);
232    }
233  this->workingAnimator = anim;
234}
235
236
237
238/**
239   \brief adds a keyframe with properties
240   \param the point of the object
241   \param and the direction of it
242   \param at this time
243*/
244void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time)
245{
246  if( !this->bDescriptive || this->workingAnimator == NULL)
247    {
248      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
249      return;
250    }
251  KeyFrame3D* frame = new KeyFrame3D;
252  frame->position = point;
253  frame->direction = direction;
254  frame->time = time;
255  frame->mode = DEFAULT_ANIMATION_MODE;
256  frame->object = this->workingAnimator->object;
257  this->workingAnimator->frames->add(frame);
258}
259
260
261/**
262   \brief adds a keyframe with properties
263   \param the point of the object
264   \param and the direction of it
265   \param at this time
266   \param function of the velocity of the movement
267*/
268void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time, movementMode mode)
269{
270  if( !this->bDescriptive || this->workingAnimator == NULL)
271    {
272      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
273      return;
274    }
275  KeyFrame3D* frame = new KeyFrame3D;
276  frame->position = point;
277  frame->direction = direction;
278  frame->time = time;
279  frame->mode = mode;
280  frame->object = this->workingAnimator->object;
281  this->workingAnimator->frames->add(frame);
282}
283
284/**
285   \brief adds a already defined keyframe
286   \param the keyframe to add
287*/
288void SimpleAnimation::addKeyFrame(KeyFrame3D* frame)
289{
290  if( !this->bDescriptive || this->workingAnimator == NULL)
291    {
292      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
293      return;
294    }
295  frame->object = this->workingAnimator->object;
296  this->workingAnimator->frames->add(frame);
297}
298
299
300void SimpleAnimation::setAnimationMode(animationMode mode)
301{
302  if( !this->bDescriptive || this->workingAnimator == NULL)
303    {
304      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
305      return;
306    }
307  this->workingAnimator->animMode = mode;
308}
309
310/**
311   \brief clear the list of keyframes, deleting all keyframes included
312*/
313void SimpleAnimation::reset()
314{
315  /*
316  tIterator<KeyFrame3D>* iterator = this->frames->getIterator();
317  KeyFrame3D* frame = iterator->nextElement();
318  while( frame != NULL)
319    {
320      delete frame;
321      frame = iterator->nextElement();
322    }
323  delete iterator;
324  delete this->frames;
325
326  this->frames = new tList<KeyFrame3D>();
327  this->localTime = 0;
328  this->bRunning = false;
329
330  this->currentFrame = NULL;
331  this->lastFrame = NULL;
332  */
333}
334
335/**
336   \brief starts the animation, therefore listens to tick signals
337*/
338void SimpleAnimation::start()
339{
340  if( this->bRunning)
341    {
342      PRINTF(2)("SimpleAnimatin is already running. You are trying to start it again.\n");
343    return;
344    }
345 
346  if( this->workingAnimator == NULL)
347    {
348      PRINTF(1)("You have no target selected to start: either do this with start(target) or by prev selecting it\n");
349      return;
350    }
351  this->workingAnimator->localTime = 0.0;
352  this->workingAnimator->bRunning = true;
353  this->workingAnimator->currentFrame = this->workingAnimator->frames->firstElement();
354  this->workingAnimator->lastFrame = this->workingAnimator->frames->nextElement(this->workingAnimator->currentFrame);
355
356  /*
357  tIterator<Animation>* iterator = this->animators->getIterator();
358  Animation* anim = iterator->nextElement();
359  while( anim != NULL)
360    {
361      printf("SimpleAnimation::start() - initializing an animaion\n");
362      anim->currentFrame = anim->frames->firstElement();
363      anim->lastFrame = anim->frames->nextElement(anim->currentFrame);
364      anim = iterator->nextElement();
365    }
366  */
367}
368
369
370/**
371   \brief stops the animation, immune to tick signals
372*/
373void SimpleAnimation::stop()
374{
375  this->bRunning = false;
376}
377
378/**
379   \brief stops and then starts the animation from begining
380*/
381void SimpleAnimation::restart()
382{
383  this->localTime = 0;
384  //this->lastFrame = this->frames->firstElement();
385  //this->currentFrame = this->frames->nextElement(this->currentFrame);
386  this->bRunning = true;
387}
388
389/**
390   \brief pauses the animation until resumed
391*/
392void SimpleAnimation::pause()
393{
394  this->bRunning = false;
395}
396
397/**
398   \brief resumes a pause, if not paused, no effect
399*/
400void SimpleAnimation::resume()
401{
402  this->bRunning = true;
403}
404
405
406/**
407   \brief heart beat, next animation step
408*/
409void SimpleAnimation::tick(float time)
410{
411  tIterator<Animation3D>* iterator = this->animators->getIterator();
412  Animation3D* anim = iterator->nextElement();
413  while( anim != NULL)
414    {
415      if( anim->bRunning)
416        { 
417          anim->localTime += time;
418          /* first get the current frame via time-stamps */ 
419          while( anim->localTime > anim->currentFrame->time)
420            {
421              PRINTF(4)("SimpleAnimation::tick(...) - changing Frame\n");
422             
423              anim->localTime -= anim->currentFrame->time;
424              //this->currentFrame->object->setRelCoor(*this->currentFrame->position);
425              *anim->lastPosition = *anim->currentFrame->position;
426             
427              anim->lastFrame = anim->currentFrame;
428              anim->currentFrame = anim->frames->nextElement(anim->currentFrame);
429              if( anim->currentFrame == anim->frames->firstElement() && anim->animMode == SINGLE)
430                {
431                  anim->bRunning = false;
432                  return;
433                }
434              anim->movMode = anim->currentFrame->mode;
435              if( anim->movMode == NEG_EXP)
436                {
437                  *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
438                  anim->deltaT = 1/anim->currentFrame->time * logf(1.0 + 600.0/anim->tmpVect->len());
439                }
440            }
441         
442          /* now animate it */
443          switch( anim->movMode)
444            {
445            case LINEAR:
446              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
447              *anim->tmpVect = *anim->tmpVect * anim->localTime / anim->currentFrame->time;
448              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
449              *anim->lastPosition = *anim->tmpVect;
450              break;
451            case EXP:
452             
453              break;
454            case NEG_EXP:
455              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
456              *anim->tmpVect = *anim->tmpVect * (1 - expf(- anim->localTime * anim->deltaT));     
457              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
458              *anim->lastPosition = *anim->tmpVect;
459              break;
460            case SIN:
461              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
462              *anim->tmpVect = *anim->tmpVect * 0.5*(1 - cos(M_PI * anim->localTime / anim->currentFrame->time));     
463              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
464              *anim->lastPosition = *anim->tmpVect;
465              break;
466            case COS:
467             
468              break;
469            case QUADRATIC:
470              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
471              *anim->tmpVect = *anim->tmpVect * 1/3 * ldexpf(anim->localTime, 3);
472              break;
473            default:
474              break;
475            }
476        }
477      anim = iterator->nextElement();
478    }
479  delete anim;
480}
481
482
483
484Animation3D* SimpleAnimation::getAnimationFromWorldEntity(WorldEntity* entity)
485{
486  tIterator<Animation3D>* iterator = this->animators->getIterator();
487  Animation3D* anim = iterator->nextElement();
488  while( anim != NULL)
489    {
490      if( anim->object == entity)
491        return anim;
492      anim = iterator->nextElement();
493    }
494  delete iterator;
495  return NULL;
496}
Note: See TracBrowser for help on using the repository browser.