Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7333 in orxonox.OLD for trunk/src/lib/particles


Ignore:
Timestamp:
Apr 18, 2006, 8:29:51 PM (19 years ago)
Author:
bensch
Message:

orxonox/trunk: Totally new QuickAnimation. This should be much faster, but it isn't … this again shows, that most of the Time the processor is used on the Draw functions….

Location:
trunk/src/lib/particles
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/particles/particle_system.cc

    r7301 r7333  
    202202void ParticleSystem::setRadius(float lifeCycleTime, float radius, float randRadius)
    203203{
    204   this->radiusAnim.changeEntry(lifeCycleTime, radius);
    205   this->randRadiusAnim.changeEntry(lifeCycleTime, randRadius);
     204  this->radiusAnim.changeValue(lifeCycleTime, radius);
     205  this->randRadiusAnim.changeValue(lifeCycleTime, randRadius);
    206206
    207207  PRINTF(4)("Radius of %s::%s at timeSlice %f is %f with a Random of %f\n",
     
    217217void ParticleSystem::setMass(float lifeCycleTime, float mass, float randMass)
    218218{
    219   this->massAnim.changeEntry(lifeCycleTime, mass);
    220   this->randMassAnim.changeEntry(lifeCycleTime, randMass);
     219  this->massAnim.changeValue(lifeCycleTime, mass);
     220  this->randMassAnim.changeValue(lifeCycleTime, randMass);
    221221}
    222222
     
    231231void ParticleSystem::setColor(float lifeCycleTime, float red, float green, float blue, float alpha)
    232232{
    233   this->colorAnim[0].changeEntry(lifeCycleTime, red);
    234   this->colorAnim[1].changeEntry(lifeCycleTime, green);
    235   this->colorAnim[2].changeEntry(lifeCycleTime, blue);
    236   this->colorAnim[3].changeEntry(lifeCycleTime, alpha);
     233  this->colorAnim[0].changeValue(lifeCycleTime, red);
     234  this->colorAnim[1].changeValue(lifeCycleTime, green);
     235  this->colorAnim[2].changeValue(lifeCycleTime, blue);
     236  this->colorAnim[3].changeValue(lifeCycleTime, alpha);
    237237
    238238  PRINTF(4)("Color of %s::%s on timeslice %f is r:%f g:%f b:%f a:%f\n",
     
    310310
    311311    // applying Color
    312     tickPart->color[0] = this->colorAnim[0].getValue(tickPart->lifeCycle);
    313     tickPart->color[1] = this->colorAnim[1].getValue(tickPart->lifeCycle);
    314     tickPart->color[2] = this->colorAnim[2].getValue(tickPart->lifeCycle);
    315     tickPart->color[3] = this->colorAnim[3].getValue(tickPart->lifeCycle);
     312    this->colorAnim[0].getValue(tickPart->color[0], tickPart->lifeCycle);
     313    this->colorAnim[1].getValue(tickPart->color[1], tickPart->lifeCycle);
     314    this->colorAnim[2].getValue(tickPart->color[2], tickPart->lifeCycle);
     315    this->colorAnim[3].getValue(tickPart->color[3], tickPart->lifeCycle);
    316316
    317317    // rendering new position.
  • trunk/src/lib/particles/quick_animation.cc

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

    r5405 r7333  
    88#define _QUICK_ANIMATION_H
    99
    10 #include "base_object.h"
    11 
     10#include <vector>
    1211// FORWARD DECLARATION
    13 
    14 
    15 
    1612
    1713//! A class for that linearely interpolates between multiple values.
    1814/**
    19    to be quick this only has the capability to store very little date
     15 * QuickAnimation is a Class that creates a LookupTable with
     16 * position between [0.0f - 1.0f] so that one can resolve the
     17 * given Value.
     18 */
     19class QuickAnimation
     20{
     21public:
     22  QuickAnimation(unsigned int resolution = 100);
     23  virtual ~QuickAnimation();
    2024
    21    this class is optimized for a raising value. eg. 100 particles sorted
    22    by age.
    23 */
    24 class QuickAnimation : public BaseObject {
     25  bool addKey(float position, float value);
    2526
    26  public:
     27  bool changeValueKey(unsigned int keyFrameNumber, float newValue);
     28  bool changeValue(float position, float newValue, float region = 0.04f);
    2729
     30  bool removeKey(unsigned int keyFrameNumber);
     31  bool remove(float position, float region = 0.04f);
     32
     33  bool moveKey(unsigned int keyFrameNumber, float newPosition, float newValue);
     34  bool moveKey(unsigned int keyFrameNumber, float newPosition);
     35  bool move(float oldPosition, float newPosition, float newValue, float region = 0.04f);
     36  bool move(float oldPosition, float newPosition, float region = 0.04f);
     37
     38  int getKeyAt(float position, float region = 0.04f);
     39
     40  /**
     41   * @brief returns the value of the animation at a certain position
     42   * @param value returns the calculated value.
     43   * @param position The position to get the Value from.
     44   */
     45  void QuickAnimation::getValue(float& value, float position) const
     46  {
     47    value = this->lookupValues[int(position*this->lookupValues.size())];
     48  }
     49
     50/**
     51   * @brief returns the value of the animation at a certain position
     52   * @param position the position to get the value from :)
     53   * @returns the calculated Value.
     54 */
     55  float QuickAnimation::getValue(float position) const
     56  {
     57    return this->lookupValues[int(position*this->lookupValues.size())];
     58  }
     59
     60  void debug() const;
     61private:
     62  void rebuild();
     63
     64private:
    2865  //! a simple struct that stores keyframes for the QuickAnimation-Class.
    2966  struct QuickKeyFrame
    3067  {
    31     float            value;             //!< The starting value of this KeyFrame
    32     float            position;          //!< The end position of thies KeyFrame
     68    //! Creates a new QuickKeyFrame with @param position position @param value value */
     69    QuickKeyFrame(float position, float value) :  position(position), value(value) {};
     70    float            value;             //!< The value of this KeyFrame
     71    float            position;          //!< The position of thies KeyFrame
    3372
    34     QuickKeyFrame*   next;              //!< The next Animation
    35     QuickKeyFrame*   prev;              //!< The previous QuickKeyFrame
     73    static bool sortPositionPredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2);
     74    static bool sortValuePredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2);
    3675  };
    3776
    38   QuickAnimation();
    39   virtual ~QuickAnimation();
    40 
    41   void addEntry(float position, float value);
    42   void changeEntry(float position, float value, float region = .04);
    43 
    44   void removeEntry(float position);
    45   /** @todo implemente those functions
    46       bool moveEntry(float position);
    47   */
    48 
    49   float getValue(float position);
    50 
    51   void debug();
    52 
    53  private:
    54   QuickKeyFrame*       first;          //!< The first KeyFrame in a Sequence of Keyframes.
    55   QuickKeyFrame*       current;        //!< The currently selected KeyFrame.
    56   unsigned int         count;          //!< How many Keyframes the QuickAnimation has.
     77  std::vector<QuickKeyFrame>    keyFrames;              //!< An Array of KeyFrames.
     78  std::vector<float>            lookupValues;           //!< The lookup-table where the values are stored.
    5779};
    5880
Note: See TracChangeset for help on using the changeset viewer.