Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: simpleanimation is on the way to support more than one world entity it is bound to… does not yet work, and may crash in segfault.

File size: 7.8 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->bDescriptive = false;
100}
101
102
103/**
104   \brief select an object to work on by using this function
105   \param object wo work on
106*/
107void SimpleAnimation::selectObject(WorldEntity* entity)
108{
109  this->workingObject = entity;
110}
111
112
113
114/**
115   \brief adds a keyframe with properties
116   \param the point of the object
117   \param and the direction of it
118   \param at this time
119*/
120void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time)
121{
122  if( !this->bDescriptive)
123    {
124      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
125      return;
126    }
127  KeyFrame* frame = new KeyFrame;
128  frame->position = point;
129  frame->direction = direction;
130  frame->time = time;
131  frame->mode = DEFAULT_ANIMATION_MODE;
132  frame->object = this->workingObject;
133  this->frames->add(frame);
134}
135
136
137/**
138   \brief adds a keyframe with properties
139   \param the point of the object
140   \param and the direction of it
141   \param at this time
142   \param function of the velocity of the movement
143*/
144void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time, movementMode mode)
145{
146  if( !this->bDescriptive)
147    {
148      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
149      return;
150    }
151  KeyFrame* frame = new KeyFrame;
152  frame->position = point;
153  frame->direction = direction;
154  frame->time = time;
155  frame->mode = mode;
156  frame->object = this->workingObject;
157  this->frames->add(frame);
158}
159
160/**
161   \brief adds a already defined keyframe
162   \param the keyframe to add
163*/
164void SimpleAnimation::addKeyFrame(KeyFrame* frame)
165{
166  if( !this->bDescriptive)
167    {
168      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
169      return;
170    }
171  frame->object = this->workingObject;
172  this->frames->add(frame);
173}
174
175
176/**
177   \brief clear the list of keyframes, deleting all keyframes included
178*/
179void SimpleAnimation::reset()
180{
181  tIterator<KeyFrame>* iterator = this->frames->getIterator();
182  KeyFrame* frame = iterator->nextElement(); 
183  while( frame != NULL) 
184    { 
185      delete frame;
186      frame = iterator->nextElement();
187    }
188  delete iterator;
189  delete this->frames;
190
191  this->frames = new tList<KeyFrame>();
192  this->localTime = 0;
193  this->bRunning = false;
194
195  this->currentFrame = NULL;
196  this->lastFrame = NULL;
197}
198
199/**
200   \brief starts the animation, therefore listens to tick signals
201*/
202void SimpleAnimation::start()
203{
204  if( this->bRunning)
205    {
206      PRINTF(2)("SimpleAnimatin is already running. You are trying to start it again.\n");
207    return;
208    }
209 
210  this->localTime = 0;
211  this->lastFrame = this->frames->firstElement();
212  this->currentFrame = this->frames->nextElement(this->currentFrame);
213  this->bRunning = true;
214}
215
216
217/**
218   \brief stops the animation, immune to tick signals
219*/
220void SimpleAnimation::stop()
221{
222  this->bRunning = false;
223}
224
225/**
226   \brief stops and then starts the animation from begining
227*/
228void SimpleAnimation::restart()
229{
230  this->localTime = 0;
231  this->lastFrame = this->frames->firstElement();
232  this->currentFrame = this->frames->nextElement(this->currentFrame);
233  this->bRunning = true;
234}
235
236/**
237   \brief pauses the animation until resumed
238*/
239void SimpleAnimation::pause()
240{
241  this->bRunning = false;
242}
243
244/**
245   \brief resumes a pause, if not paused, no effect
246*/
247void SimpleAnimation::resume()
248{
249  this->bRunning = true;
250}
251
252
253/**
254   \brief heart beat, next animation step
255*/
256void SimpleAnimation::tick(float time)
257{
258  this->localTime += time;
259  tIterator<Animation>* iterator = this->animators->getIterator();
260  Animation* anim = iterator->nextElement();
261  while( anim != NULL)
262    {
263      if( anim->bRunning)
264        {
265         
266         
267          /* first get the current frame via time-stamps */ 
268          while( this->localTime > anim->currentFrame->time)
269            {
270              printf("SimpleAnimation::tick(...) - changing Frame\n");
271             
272              //this->currentFrame->object->setRelCoor(*this->currentFrame->position);
273              *anim->lastPosition = *anim->currentFrame->position;
274             
275              anim->lastFrame = anim->currentFrame;
276              anim->currentFrame = anim->frames->nextElement(anim->currentFrame);
277              anim->movMode = anim->currentFrame->mode;
278              if( anim->movMode == NEG_EXP)
279                {
280                  *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
281                  anim->deltaT = 1/anim->currentFrame->time * logf(1.0 + 600.0/anim->tmpVect->len());
282                }
283            }
284         
285          /* now animate it */
286          switch( anim->movMode)
287            {
288            case LINEAR:
289             
290              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
291              *anim->tmpVect = *anim->tmpVect * this->localTime / anim->currentFrame->time;
292              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
293              *anim->lastPosition = *anim->tmpVect;
294              break;
295            case EXP:
296             
297              break;
298            case NEG_EXP:
299              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
300              *anim->tmpVect = *anim->tmpVect * (1 - exp(- this->localTime * anim->deltaT));     
301              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
302              *anim->lastPosition = *anim->tmpVect;
303              break;
304            case SIN:
305              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
306              *anim->tmpVect = *anim->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / anim->currentFrame->time));     
307              anim->currentFrame->object->setRelCoor(*anim->lastFrame->position + *anim->tmpVect);
308              *anim->lastPosition = *anim->tmpVect;
309              break;
310            case COS:
311             
312              break;
313            case QUADRATIC:
314              *anim->tmpVect = *anim->currentFrame->position - *anim->lastFrame->position;
315              *anim->tmpVect = *anim->tmpVect * 1/3 * ldexpf(this->localTime, 3);
316              break;
317            default:
318              break;
319            }
320        }
321      anim = iterator->nextElement();
322    }
323  delete anim;
324}
Note: See TracBrowser for help on using the repository browser.