Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3744 was 3744, checked in by patrick, 19 years ago

orxonox/trunk: SimpleAnimation works again :)

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