Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: adding the same Key with the same Position multiple times does not work anymore (as it should)

File size: 8.9 KB
RevLine 
[4597]1/*
[1853]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.
[1855]10
11   ### File Specific:
12   main-programmer: ...
13   co-programmer: ...
[1853]14*/
15
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[1853]17
[4415]18#include "quick_animation.h"
[1853]19
[7333]20#include <algorithm>
[4415]21
[1856]22using namespace std;
[1853]23
[3245]24/**
[7333]25 * @brief standard constructor
26 * @param resolution the Resolution of the LookupTable
27 */
28QuickAnimation::QuickAnimation (unsigned int resolution)
[3365]29{
[7333]30  this->lookupValues.resize(resolution, 0.0f);
[3365]31}
[1853]32
[3245]33/**
[7333]34 * @brief deletes all the deconstructor stuff
35 */
[4746]36QuickAnimation::~QuickAnimation ()
[7333]37{ }
[4597]38
[4421]39/**
[7333]40 * @brief adds a new entry to the list of keyframes
[4836]41 * @param position the position to add the key to
42 * @param value the Value to set for the position
43 * @returns false if the key existed already for a given position
[7333]44 */
45bool QuickAnimation::addKey(float position, float value)
[4415]46{
[7333]47  if (position > 1.0f || position < 0.0f)
[4654]48  {
[7333]49    printf("QuickAnimation::Position MUST BE between 0.0f and 1.0f\n");
50    return false;
[4654]51  }
[7335]52  if(std::find(this->keyFrames.begin(), this->keyFrames.end(), position) != this->keyFrames.end())
53  {
54    printf("QuickAnimation:: key at position %f already added. Use changeValue instead\n", position);
55    return false;
56  }
[7333]57  this->keyFrames.push_back(QuickKeyFrame(position, value));
[4654]58
[7333]59  this->rebuild();
60  return true;
61}
62
63
64/**
65 * @brief changes an entry in the region of position
66 * @param position the Position of an existing keyframe
67 * @param region a deviation of the existing keyframe (like a delta in witch to search for)
68 * @param value the new Value
69 */
70bool QuickAnimation::changeValueKey(unsigned int keyFrameNumber, float newValue)
71{
72  if (keyFrameNumber < this->keyFrames.size())
[4654]73  {
[7333]74    this->keyFrames[keyFrameNumber].value = newValue;
75    this->rebuild();
76    return true;
[4654]77  }
78  else
[7333]79    return false;
[4415]80}
81
[4421]82/**
[7333]83 * @brief changes an entry in the region of position
[4836]84 * @param position the Position of an existing keyframe
[7333]85 * @param region a deviation of the existing keyframe (like a delta in witch to search for)
[4836]86 * @param value the new Value
[7333]87 *
88 * This Function adds a new KeyFrame at position with newValue, if none was found in region of position.
89 */
90bool QuickAnimation::changeValue(float position, float newValue, float region)
91{
92  int keyFrame = this->getKeyAt(position, region);
93  if (keyFrame == -1)
94    return this->addKey(position, newValue);
95  else
96    return this->changeValueKey(keyFrame, newValue);
97}
[4654]98
[7333]99
100/**
101 * @brief removes the keyFrameNumber'th entry.
102 * @param keyFrameNumber the n'th Keyframe to remove.
103 * @returns true on success, false if keyFrameNumber did not exist.
104 */
105bool QuickAnimation::removeKey(unsigned int keyFrameNumber)
[4425]106{
[7333]107  if (keyFrameNumber < this->keyFrames.size())
[4656]108  {
[7333]109    this->keyFrames.erase(this->keyFrames.begin() + keyFrameNumber);
110    this->rebuild();
111    return true;
[4656]112  }
[7333]113  else
114    return false;
[4425]115}
116
[4597]117
[4657]118/**
[7333]119 * @brief removes a KeyFrame from the List.
120 * @param position the Keyframe at position position will be erased.
121 * @param region a deviation of the existing keyframe (like a delta in witch to search for)
122 * @returns true on success, false if no KeyFrame was found.
[4657]123 */
[7333]124bool QuickAnimation::remove(float position, float region)
[4657]125{
[7333]126  int keyFrame = this->getKeyAt(position, region);
127  if (keyFrame == -1)
128    return false;
129  else
130    return this->removeKey(keyFrame);
131}
[4597]132
[7333]133/**
134 * @brief moves the keyFrame keyFrameNumber to newPosition/newValue.
135 * @param keyFrameNumber the n'th KeyFrame to move.
136 * @param newPosition the new Position for the KeyFrame.
137 * @param newValue the new Value for the KeyFrame.
138 * @returns true on success, false if the KeyFrame did not exist.
139 */
140bool QuickAnimation::moveKey(unsigned int keyFrameNumber, float newPosition, float newValue)
141{
142  if (keyFrameNumber < this->keyFrames.size())
[4425]143  {
[7333]144    this->keyFrames[keyFrameNumber].position = newPosition;
145    this->keyFrames[keyFrameNumber].value = newValue;
146    this->rebuild();
147    return true;
[4657]148  }
149  else
[7333]150    return false;
151}
152
153/**
154 * @brief moves the keyFrame keyFrameNumber to newPosition/value.
155 * @param keyFrameNumber the n'th KeyFrame to move.
156 * @param newPosition the new Position for the KeyFrame.
157 * @returns true on success, false if the KeyFrame did not exist.
158 */
159bool QuickAnimation::moveKey(unsigned int keyFrameNumber, float newPosition)
160{
161  if (keyFrameNumber < this->keyFrames.size())
[4425]162  {
[7333]163    this->keyFrames[keyFrameNumber].position = newPosition;
164    this->rebuild();
165    return true;
166  }
167  else
168    return false;
169}
[4597]170
[7333]171/**
172 * @brief moves the keyFrame in the region of oldPosition to newPosition/newValue.
173 * @param oldPosition the old Position for the KeyFrame.
174 * @param newPosition the new Position for the KeyFrame.
175 * @param newValue the new Value for the KeyFrame.
176 * @param region the region around oldPosition to search for the KeyFrame.
177 * @returns true on success, false if the KeyFrame was not found within the region of oldPosition.
178 */
179bool QuickAnimation::move(float oldPosition, float newPosition, float newValue, float region)
180{
181  int keyFrame = this->getKeyAt(oldPosition, region);
182  if (keyFrame == -1)
183    return false;
184  else
185    return this->moveKey(keyFrame, newPosition, newValue);
186}
187
188/**
189 * @brief moves the keyFrame in the region of oldPosition to newPosition/Value.
190 * @param oldPosition the old Position for the KeyFrame.
191 * @param newPosition the new Position for the KeyFrame.
192 * @param region the region around oldPosition to search for the KeyFrame.
193 * @returns true on success, false if the KeyFrame was not found within the region of oldPosition.
194 */
195bool QuickAnimation::move(float oldPosition, float newPosition, float region)
196{
197  int keyFrame = this->getKeyAt(oldPosition, region);
198  if (keyFrame == -1)
199    return false;
200  else
201    return this->moveKey(keyFrame, newPosition);
202}
203
204
205/**
206 * @brief searches for a Keyframe in the region of position
207 * @param position the Keyframe at position position will searched for.
208 * @param region a deviation of the existing keyframe (like a delta in witch to search for)
209 * @returns the keyFrame on success, -1 on fault.
210 */
211int QuickAnimation::getKeyAt(float position, float region)
212{
213  for (unsigned int i = 0; i < this->keyFrames.size(); i++)
214  {
215    if (this->keyFrames[i].position + region/2.0 > position && this->keyFrames[i].position - region/2.0 < position)
216      return i;
[4425]217  }
[7333]218  return -1;
[4657]219}
[4425]220
[4657]221
[4425]222/**
[7333]223 * @brief rebuilds the QuickAnimation.
224 */
225void QuickAnimation::rebuild()
[4415]226{
[7333]227  // if we do not have any KeyFrames
228  if (this->keyFrames.empty())
[4654]229  {
[7333]230    for (unsigned int i = 0; i < this->lookupValues.size(); i++)
231      this->lookupValues[i] = 0.0f;
232    return;
233  }
[4654]234
[7333]235  // Sort the List.
236  std::sort(this->keyFrames.begin(), this->keyFrames.end(), QuickKeyFrame::sortPositionPredicate);
237
238  // rebuild the lookup-table
239  float sliceSize = 1.0f / this->lookupValues.size();
240  unsigned int key = 0;
241  float preVal = this->keyFrames[0].value;
242  float prePos = this->keyFrames[0].position;
243
244  float postVal = preVal;
245  float postPos = 1.0;
246
247  if (this->keyFrames.size() > 1)
248  {
249    postVal = this->keyFrames[1].value;
250    postPos = this->keyFrames[1].position;
[4654]251  }
[7333]252
253
254  for (unsigned int i = 0; i < this->lookupValues.size(); i++)
255  {
256    float position = (float)i * sliceSize;
257
258    // if we reach the Next KeyFrame
259    if (position > postPos)
260    {
261      // if we have more KeyFrames.
262      if (this->keyFrames.size() > ++key + 1)
263      {
264        preVal = this->keyFrames[key].value;
265        prePos = this->keyFrames[key].position;
266        postVal = this->keyFrames[key+1].value;
267        postPos = this->keyFrames[key+1].position;
268      }
269      // otherwise we reached the last KeyFrame
270      else
271      {
272        preVal = postVal;
273        prePos = postPos;
274        postPos = 1.0;
275      }
276    }
277    this->lookupValues[i] = preVal + ( postVal - preVal) / (postPos - prePos) * (position - prePos);
278  }
[4415]279}
280
[4479]281/**
[7333]282 * @brief outputs some nice information about this class
283 */
284void QuickAnimation::debug() const
[4421]285{
[7333]286  printf("QuickAnim(KeyFrames:%d, Resolution:%d)::(position, value) ", this->keyFrames.size(), this->lookupValues.size());
[4421]287
[7333]288  for (unsigned int i = 0; i < this->keyFrames.size(); i++)
289    printf("(%f, %f)->", this->keyFrames[i].position, this->keyFrames[i].value);
290  printf("\n");
291}
[4421]292
[7333]293
294
[7334]295/**
296 * @brief compares two QuickKeyFrames with their positions.
297 * @param key1 the first keyframe
298 * @param key2 the second keyframe
299 * @returns true, if the key1.position < key2.position.
300 */
[7333]301bool QuickAnimation::QuickKeyFrame::sortPositionPredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2)
302{
303  return (key1.position < key2.position);
[4421]304}
[7333]305
[7334]306/**
307 * @brief compares two QuickKeyFrames with their values.
308 * @param key1 the first keyframe
309 * @param key2 the second keyframe
310 * @returns true, if the key1.value < key2.value.
311 */
[7333]312bool QuickAnimation::QuickKeyFrame::sortValuePredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2)
313{
314  return (key1.value < key2.value);
315}
316
Note: See TracBrowser for help on using the repository browser.