Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/particles/quick_animation.cc @ 4697

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

orxonox/trunk: minor QuickAnim: deleteEntry should work

File size: 6.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: ...
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "quick_animation.h"
19
20#include "compiler.h"
21#include "debug.h"
22#ifndef NULL
23#define NULL 0
24#endif
25
26
27using namespace std;
28
29/**
30   \brief standard constructor
31*/
32QuickAnimation::QuickAnimation (void)
33{
34   this->setClassID(CL_QUICK_ANIMATION, "QuickAnimation");
35
36   // initialize the First KeyFrame (will be deleted if a new one gets created)
37   this->count = 0;
38   this->first = this->current = new QuickKeyFrame;
39   this->first->next = this->first->prev = this->first;
40   this->first->position = 0.0;
41   this->first->value = 0.0;
42}
43
44/**
45   \brief deletes all the deconstructor stuff
46*/
47QuickAnimation::~QuickAnimation (void)
48{
49  this->current = this->first;
50  QuickKeyFrame* delKF = this->first;
51
52  do
53  {
54    delKF = this->current;
55    this->current = this->current->next;
56    delete delKF;
57  }  while (this->current != this->first);
58
59}
60
61/**
62   \brief adds a new entry to the list of keyframes
63   \param position the position to add the key to
64   \param value the Value to set for the position
65   \returns false if the key existed already for a given position
66*/
67void QuickAnimation::addEntry(float position, float value)
68{
69  // create the new KeyFrame
70  QuickKeyFrame* newKey = new QuickKeyFrame;
71  newKey->position = position;
72  newKey->value = value;
73
74  // if we add a KeyFrame for the first Time:
75  if (unlikely (this->count == 0))
76  {
77    delete this->first;
78
79    newKey->next  = newKey;
80    newKey->prev  = newKey;
81    this->first   = newKey;
82    this->current = newKey;
83  }
84  // if the KeyFrame is in front of the FIRST keyFrame
85  else if (this->first->position > position)
86  {
87    newKey->next = this->first;
88    newKey->prev = this->first->prev;
89    newKey->prev->next = newKey;
90    newKey->next->prev = newKey;
91
92    this->first = newKey; // the new Key becomes the FIRST.
93  }
94  // if the KeyFrame is at the End of the Animation
95  else if (this->first->prev->position < position)
96  {
97    newKey->next = this->first;
98    newKey->prev = this->first->prev;
99    newKey->prev->next = newKey;
100    newKey->next->prev = newKey;
101  }
102  // if the Key is between two frames.
103  else
104  {
105    this->current = this->first;
106    do
107    {
108      if (this->current->position < position && this->current->next->position > position)
109        break;
110      // if it is the same as an already existing keyframe
111      else if (this->current->position == position)
112      {
113        this->current->value = value;
114        delete newKey;
115        return;
116      }
117      this->current = this->current->next;
118    } while (this->current != this->first);
119
120    newKey->next = this->current->next;
121    newKey->prev = this->current;
122    newKey->next->prev = newKey;
123    newKey->prev->next = newKey;
124  }
125  this->current = this->first;
126  ++this->count;
127}
128
129/**
130   \brief changes an entry in the region of position
131   \param position the Position of an existing keyframe
132   \param region a deviation of the existing keyframe (like a delta in witch to search for
133   \param value the new Value
134
135   if the Entry at the in the region of the specified position is found, it will be changed.
136    Otherwise a new KeyFrame will be created with value at position.
137   \todo rimplement
138*/
139void QuickAnimation::changeEntry(float position, float value, float region)
140{
141
142  if ((this->first->position > position + region) || this->first->prev->position < position - region || this->count == 0)
143    this->addEntry(position, value);
144  else
145  {
146    this->current = this->first;
147    do
148    {
149      if (this->current->position > position + region)
150      {
151        this->addEntry(position, value);
152        return;
153      }
154      if (this->current->position < position+region && this->current->position > position-region)
155      {
156        this->current->value = value;
157        return;
158      }
159      this->current = this->current->next;
160    }  while (this->current != this->first);
161  }
162}
163
164
165/**
166 * removes a KeyFrame from the List.
167 * @param position
168 * @return
169 */
170void QuickAnimation::removeEntry(float position)
171{
172  this->current = this->first;
173
174  if (this->count <= 0)
175  {
176    this->current->value = 0.0;
177    this->current->position = 0.0;
178    count = 0;
179    return;
180  }
181  else
182  {
183    do
184    {
185      if (this->current->position == position)
186      {
187        if (this->current == this->first)
188          this->first = this->first->next;
189        this->current->next->prev = this->current->prev;
190        this->current->prev->next = this->current->next;
191        delete this->current;
192        break;
193      }
194      this->current = this->current->next;
195    } while (this->current != this->first);
196
197    count --;
198    this->current = this->first;
199  }
200}
201
202
203/**
204   \brief returns the value of the animation at a certain position
205   \param position the position to get the value from :)
206*/
207float QuickAnimation::getValue(float position)
208{
209  while (true)
210  {
211    // if we have a match
212    if (likely(this->current->position <= position && this->current->next->position >= position))
213      return this->current->value + (this->current->next->value - this->current->value)
214          * ((position-this->current->position) / (this->current->next->position -this->current->position));
215
216    else if (unlikely(this->first->prev->position < position))
217      return this->first->prev->value;
218    else if (unlikely(this->first->position > position))
219      return this->first->value;
220    else if(likely(this->current->next->position < position))
221      this->current = this->current->next;
222    else if (likely(this->current->position > position))
223      this->current = this->current->prev;
224  }
225}
226
227/**
228   \brief outputs some nice information about this class
229*/
230void QuickAnimation::debug(void)
231{
232  this->current = this->first;
233
234  PRINT(0)("QuickAnim(entries:%d)::(position, value)", this->count);
235  do
236    {
237      PRINT(0)("->(%f, %f)", this->current->position, this->current->value);
238      this->current = this->current->next;
239    } while(this->current != this->first);
240
241  PRINT(0)("\n");
242  this->current = this->first;
243}
Note: See TracBrowser for help on using the repository browser.