Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: SimpleAnimation: the NEG_EXP function now gets scaled in a very smooth manner.

File size: 7.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: ...
16*/
17
18
19#include "simple_animation.h"
20#include "stdincl.h"
21#include "vector.h"
22#include "world_entity.h"
23
24using namespace std;
25
26
27
28SimpleAnimation* SimpleAnimation::singletonRef = 0;
29/**
30   \brief gets the singleton instance
31   \returns singleton instance
32*/
33SimpleAnimation* SimpleAnimation::getInstance()
34{
35  if( singletonRef == NULL)
36    singletonRef = new SimpleAnimation();
37  return singletonRef;
38}
39
40/**
41   \brief standard constructor
42*/
43SimpleAnimation::SimpleAnimation () 
44{
45   this->setClassName ("SimpleAnimation");
46   this->frames = new tList<KeyFrame>();
47   this->localTime = 0;
48   this->bRunning = false;
49   this->currentFrame = NULL;
50   this->lastFrame = NULL;
51
52   this->tmpVect = new Vector();
53   this->lastPosition = new Vector();
54   this->deltaT = 0.2;
55}
56
57
58/**
59   \brief standard deconstructor
60
61*/
62SimpleAnimation::~SimpleAnimation () 
63{
64  tIterator<KeyFrame>* iterator = this->frames->getIterator();
65  KeyFrame* frame = iterator->nextElement(); 
66  while( frame != NULL) 
67    { 
68      delete frame;
69      frame = iterator->nextElement();
70    }
71  delete iterator;
72  delete this->frames;
73}
74
75
76/**
77   \brief this determines the start of an Animator Describtion
78
79   this can then be followed by different commands like addKeyFrame(..) etc. and
80   will be closed with AnimatiorEnd()
81*/
82void SimpleAnimation::animatorBegin()
83{
84  this->bDescriptive = true;
85}
86
87
88/**
89   \brief this determines the end of an Animator Describtion
90
91   this can then be followed by different commands like addKeyFrame(..) etc. and
92   will be closed with AnimatiorEnd()
93*/
94void SimpleAnimation::animatorEnd()
95{
96  this->workingObject = NULL;
97  this->bDescriptive = false;
98}
99
100
101/**
102   \brief select an object to work on by using this function
103   \param object wo work on
104*/
105void SimpleAnimation::selectObject(WorldEntity* entity)
106{
107  this->workingObject = entity;
108}
109
110
111
112/**
113   \brief adds a keyframe with properties
114   \param the point of the object
115   \param and the direction of it
116   \param at this time
117*/
118void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time)
119{
120  if( !this->bDescriptive)
121    {
122      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
123      return;
124    }
125  KeyFrame* frame = new KeyFrame;
126  frame->position = point;
127  frame->direction = direction;
128  frame->time = time;
129  frame->mode = DEFAULT_ANIMATION_MODE;
130  frame->object = this->workingObject;
131  this->frames->add(frame);
132}
133
134
135/**
136   \brief adds a keyframe with properties
137   \param the point of the object
138   \param and the direction of it
139   \param at this time
140   \param function of the velocity of the movement
141*/
142void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* direction, float time, movementMode mode)
143{
144  if( !this->bDescriptive)
145    {
146      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
147      return;
148    }
149  KeyFrame* frame = new KeyFrame;
150  frame->position = point;
151  frame->direction = direction;
152  frame->time = time;
153  frame->mode = mode;
154  frame->object = this->workingObject;
155  this->frames->add(frame);
156}
157
158/**
159   \brief adds a already defined keyframe
160   \param the keyframe to add
161*/
162void SimpleAnimation::addKeyFrame(KeyFrame* frame)
163{
164  if( !this->bDescriptive)
165    {
166      PRINTF(1)("SimpleAnimation: executing animation code outside a AnimationBegin()/AnimationEnd() - ignoring\n");
167      return;
168    }
169  frame->object = this->workingObject;
170  this->frames->add(frame);
171}
172
173
174/**
175   \brief clear the list of keyframes, deleting all keyframes included
176*/
177void SimpleAnimation::reset()
178{
179  tIterator<KeyFrame>* iterator = this->frames->getIterator();
180  KeyFrame* frame = iterator->nextElement(); 
181  while( frame != NULL) 
182    { 
183      delete frame;
184      frame = iterator->nextElement();
185    }
186  delete iterator;
187  delete this->frames;
188
189  this->frames = new tList<KeyFrame>();
190  this->localTime = 0;
191  this->bRunning = false;
192
193  this->currentFrame = NULL;
194  this->lastFrame = NULL;
195}
196
197/**
198   \brief starts the animation, therefore listens to tick signals
199*/
200void SimpleAnimation::start()
201{
202  if( this->bRunning)
203    {
204      PRINTF(2)("SimpleAnimatin is already running. You are trying to start it again.\n");
205    return;
206    }
207 
208  this->localTime = 0;
209  this->lastFrame = this->frames->firstElement();
210  this->currentFrame = this->frames->nextElement(this->currentFrame);
211  this->bRunning = true;
212}
213
214
215/**
216   \brief stops the animation, immune to tick signals
217*/
218void SimpleAnimation::stop()
219{
220  this->bRunning = false;
221}
222
223/**
224   \brief stops and then starts the animation from begining
225*/
226void SimpleAnimation::restart()
227{
228  this->localTime = 0;
229  this->lastFrame = this->frames->firstElement();
230  this->currentFrame = this->frames->nextElement(this->currentFrame);
231  this->bRunning = true;
232}
233
234/**
235   \brief pauses the animation until resumed
236*/
237void SimpleAnimation::pause()
238{
239  this->bRunning = false;
240}
241
242/**
243   \brief resumes a pause, if not paused, no effect
244*/
245void SimpleAnimation::resume()
246{
247  this->bRunning = true;
248}
249
250
251/**
252   \brief heart beat, next animation step
253*/
254void SimpleAnimation::tick(float time)
255{
256  if( !this->bRunning)
257    return;
258
259  this->localTime += time;
260  /* first get the current frame via time-stamps */ 
261  while( this->localTime > this->currentFrame->time)
262    {
263      printf("SimpleAnimation::tick(...) - changing Frame\n");
264      this->localTime -= this->currentFrame->time;
265
266      //this->currentFrame->object->setRelCoor(*this->currentFrame->position);
267      *this->lastPosition = *this->currentFrame->position;
268
269      this->lastFrame = this->currentFrame;
270      this->currentFrame = this->frames->nextElement(this->currentFrame);
271      this->mode = this->currentFrame->mode;
272      if( this->mode == NEG_EXP)
273        {
274          *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
275          deltaT = 1/this->currentFrame->time * logf(1.0 + 600.0/this->tmpVect->len());
276        }
277    }
278
279  /* now animate it */
280  switch( this->mode)
281    {
282    case LINEAR:
283
284      *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
285      *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time;
286      this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
287      *this->lastPosition = *this->tmpVect;
288      break;
289    case EXP:
290     
291      break;
292    case NEG_EXP:
293      *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
294      *this->tmpVect = *this->tmpVect * (1 - exp(- this->localTime * this->deltaT));     
295      this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
296      *this->lastPosition = *this->tmpVect;
297      break;
298    case SIN:
299      *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
300      *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time));     
301      this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
302      *this->lastPosition = *this->tmpVect;
303      break;
304    case COS:
305     
306      break;
307    case QUADRATIC:
308      *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position;
309      *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3);
310      break;
311    default:
312      break;
313    }
314}
Note: See TracBrowser for help on using the repository browser.