Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: naming of animation changed
Anim → Animation
tAnim → tAnimation
Animation → Animation3D

@paede: i hope you like it.

File size: 10.1 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
28
29SimpleAnimation* SimpleAnimation::singletonRef = 0;
30/**
31   \brief gets the singleton instance
32   \returns singleton instance
33*/
34SimpleAnimation* SimpleAnimation::getInstance()
35{
36  if( singletonRef == NULL)
37    singletonRef = new SimpleAnimation();
38  return singletonRef;
39}
40
41/**
42   \brief standard constructor
43*/
44SimpleAnimation::SimpleAnimation () 
45{
46   this->setClassName ("SimpleAnimation");
47   this->frames = new tList<KeyFrame>();
48   this->animators = new tList<Animation3D>();
49   this->localTime = 0;
50   this->bRunning = false;
51   this->currentFrame = NULL;
52   this->lastFrame = NULL;
53
54   this->tmpVect = new Vector();
55   this->lastPosition = new Vector();
56   this->deltaT = 0.2;
57}
58
59
60/**
61   \brief standard deconstructor
62
63*/
64SimpleAnimation::~SimpleAnimation () 
65{
66  tIterator<KeyFrame>* iterator = this->frames->getIterator();
67  KeyFrame* frame = iterator->nextElement(); 
68  while( frame != NULL) 
69    { 
70      delete frame;
71      frame = iterator->nextElement();
72    }
73  delete iterator;
74  delete this->frames;
75  singletonRef = NULL;
76}
77
78
79/**
80   \brief this determines the start of an Animator Describtion
81
82   this can then be followed by different commands like addKeyFrame(..) etc. and
83   will be closed with AnimatiorEnd()
84*/
85void SimpleAnimation::animatorBegin()
86{
87  this->bDescriptive = true;
88}
89
90
91/**
92   \brief this determines the end of an Animator Describtion
93
94   this can then be followed by different commands like addKeyFrame(..) etc. and
95   will be closed with AnimatiorEnd()
96*/
97void SimpleAnimation::animatorEnd()
98{
99  this->workingObject = NULL;
100  this->workingAnimator = NULL;
101  this->bDescriptive = false;
102}
103
104
105/*
106  Vector* lastPosition;
107  Vector* tmpVect;
108  tList<KeyFrame>* frames;
109  animationMode animMode;
110  movementMode movMode;
111  bool bRunning;
112  float deltaT;
113*/
114
115/**
116   \brief select an object to work on by using this function
117   \param object wo work on
118*/
119void SimpleAnimation::selectObject(WorldEntity* entity)
120{
121  Animation3D* anim = getAnimationFromWorldEntity(entity);
122  if( anim == NULL)
123    {
124      anim = new Animation3D;
125      anim->object = entity;
126      anim->lastPosition = new Vector();
127      anim->tmpVect = new Vector();
128      anim->frames = new tList<KeyFrame>();
129      anim->animMode = LOOP;
130      anim->bRunning = false;
131      deltaT = 0.0;
132      this->animators->add(anim);
133    }
134  this->workingAnimator = anim;
135}
136
137
138
139/**
140   \brief adds a keyframe with properties
141   \param the point of the object
142   \param and the direction of it
143   \param at this time
144*/
145void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time)
146{
147  if( !this->bDescriptive || this->workingAnimator == NULL)
148    {
149      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
150      return;
151    }
152  KeyFrame* frame = new KeyFrame;
153  frame->position = point;
154  frame->direction = direction;
155  frame->time = time;
156  frame->mode = DEFAULT_ANIMATION_MODE;
157  frame->object = this->workingAnimator->object;
158  this->workingAnimator->frames->add(frame);
159}
160
161
162/**
163   \brief adds a keyframe with properties
164   \param the point of the object
165   \param and the direction of it
166   \param at this time
167   \param function of the velocity of the movement
168*/
169void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time, movementMode mode)
170{
171  if( !this->bDescriptive || this->workingAnimator == NULL)
172    {
173      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
174      return;
175    }
176  KeyFrame* frame = new KeyFrame;
177  frame->position = point;
178  frame->direction = direction;
179  frame->time = time;
180  frame->mode = mode;
181  frame->object = this->workingAnimator->object;
182  this->workingAnimator->frames->add(frame);
183}
184
185/**
186   \brief adds a already defined keyframe
187   \param the keyframe to add
188*/
189void SimpleAnimation::addKeyFrame(KeyFrame* frame)
190{
191  if( !this->bDescriptive || this->workingAnimator == NULL)
192    {
193      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
194      return;
195    }
196  frame->object = this->workingAnimator->object;
197  this->workingAnimator->frames->add(frame);
198}
199
200
201void SimpleAnimation::setAnimationMode(animationMode mode)
202{
203  if( !this->bDescriptive || this->workingAnimator == NULL)
204    {
205      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
206      return;
207    }
208  this->workingAnimator->animMode = mode;
209}
210
211/**
212   \brief clear the list of keyframes, deleting all keyframes included
213*/
214void SimpleAnimation::reset()
215{
216  /*
217  tIterator<KeyFrame>* iterator = this->frames->getIterator();
218  KeyFrame* frame = iterator->nextElement();
219  while( frame != NULL)
220    {
221      delete frame;
222      frame = iterator->nextElement();
223    }
224  delete iterator;
225  delete this->frames;
226
227  this->frames = new tList<KeyFrame>();
228  this->localTime = 0;
229  this->bRunning = false;
230
231  this->currentFrame = NULL;
232  this->lastFrame = NULL;
233  */
234}
235
236/**
237   \brief starts the animation, therefore listens to tick signals
238*/
239void SimpleAnimation::start()
240{
241  if( this->bRunning)
242    {
243      PRINTF(2)("SimpleAnimatin is already running. You are trying to start it again.\n");
244    return;
245    }
246 
247  if( this->workingAnimator == NULL)
248    {
249      PRINTF(1)("You have no target selected to start: either do this with start(target) or by prev selecting it\n");
250      return;
251    }
252  this->workingAnimator->localTime = 0.0;
253  this->workingAnimator->bRunning = true;
254  this->workingAnimator->currentFrame = this->workingAnimator->frames->firstElement();
255  this->workingAnimator->lastFrame = this->workingAnimator->frames->nextElement(this->workingAnimator->currentFrame);
256
257  /*
258  tIterator<Animation>* iterator = this->animators->getIterator();
259  Animation* anim = iterator->nextElement();
260  while( anim != NULL)
261    {
262      printf("SimpleAnimation::start() - initializing an animaion\n");
263      anim->currentFrame = anim->frames->firstElement();
264      anim->lastFrame = anim->frames->nextElement(anim->currentFrame);
265      anim = iterator->nextElement();
266    }
267  */
268}
269
270
271/**
272   \brief stops the animation, immune to tick signals
273*/
274void SimpleAnimation::stop()
275{
276  this->bRunning = false;
277}
278
279/**
280   \brief stops and then starts the animation from begining
281*/
282void SimpleAnimation::restart()
283{
284  this->localTime = 0;
285  //this->lastFrame = this->frames->firstElement();
286  //this->currentFrame = this->frames->nextElement(this->currentFrame);
287  this->bRunning = true;
288}
289
290/**
291   \brief pauses the animation until resumed
292*/
293void SimpleAnimation::pause()
294{
295  this->bRunning = false;
296}
297
298/**
299   \brief resumes a pause, if not paused, no effect
300*/
301void SimpleAnimation::resume()
302{
303  this->bRunning = true;
304}
305
306
307/**
308   \brief heart beat, next animation step
309*/
310void SimpleAnimation::tick(float time)
311{
312  tIterator<Animation3D>* iterator = this->animators->getIterator();
313  Animation3D* anim = iterator->nextElement();
314  while( anim != NULL)
315    {
316      if( anim->bRunning)
317        { 
318          anim->localTime += time;
319          /* first get the current frame via time-stamps */ 
320          while( anim->localTime > anim->currentFrame->time)
321            {
322              PRINTF(4)("SimpleAnimation::tick(...) - changing Frame\n");
323             
324              anim->localTime -= anim->currentFrame->time;
325              //this->currentFrame->object->setRelCoor(*this->currentFrame->position);
326              *anim->lastPosition = *anim->currentFrame->position;
327             
328              anim->lastFrame = anim->currentFrame;
329              anim->currentFrame = anim->frames->nextElement(anim->currentFrame);
330              if( anim->currentFrame == anim->frames->firstElement() && anim->animMode == SINGLE)
331                {
332                  anim->bRunning = false;
333                  return;
334                }
335              anim->movMode = anim->currentFrame->mode;
336              if( anim->movMode == NEG_EXP)
337                {
338                  *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
339                  anim->deltaT = 1/anim->currentFrame->time * logf(1.0 + 600.0/anim->tmpVect->len());
340                }
341            }
342         
343          /* now animate it */
344          switch( anim->movMode)
345            {
346            case LINEAR:
347              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
348              *anim->tmpVect = *anim->tmpVect * anim->localTime / anim->currentFrame->time;
349              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
350              *anim->lastPosition = *anim->tmpVect;
351              break;
352            case EXP:
353             
354              break;
355            case NEG_EXP:
356              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
357              *anim->tmpVect = *anim->tmpVect * (1 - expf(- anim->localTime * anim->deltaT));     
358              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
359              *anim->lastPosition = *anim->tmpVect;
360              break;
361            case SIN:
362              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
363              *anim->tmpVect = *anim->tmpVect * 0.5*(1 - cos(M_PI * anim->localTime / anim->currentFrame->time));     
364              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
365              *anim->lastPosition = *anim->tmpVect;
366              break;
367            case COS:
368             
369              break;
370            case QUADRATIC:
371              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
372              *anim->tmpVect = *anim->tmpVect * 1/3 * ldexpf(anim->localTime, 3);
373              break;
374            default:
375              break;
376            }
377        }
378      anim = iterator->nextElement();
379    }
380  delete anim;
381}
382
383
384
385Animation3D* SimpleAnimation::getAnimationFromWorldEntity(WorldEntity* entity)
386{
387  tIterator<Animation3D>* iterator = this->animators->getIterator();
388  Animation3D* anim = iterator->nextElement();
389  while( anim != NULL)
390    {
391      if( anim->object == entity)
392        return anim;
393      anim = iterator->nextElement();
394    }
395  delete iterator;
396  return NULL;
397}
Note: See TracBrowser for help on using the repository browser.