00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Animation/VectorInterpolator/VectorLinearInterpolator.h"
00027
00028 namespace Lamp{
00029
00030
00031
00032 VectorLinearInterpolator::VectorLinearInterpolator() :
00033 keys_(NULL), keyCount_(0), lastestUseKeyIndex_(0){
00034 }
00035
00036
00037 VectorLinearInterpolator::~VectorLinearInterpolator(){
00038 SafeArrayDelete(keys_);
00039 }
00040
00041
00042 VectorLinearInterpolator::VectorLinearInterpolator(
00043 const VectorLinearInterpolator& copy){
00044 keyCount_ = copy.keyCount_;
00045 lastestUseKeyIndex_ = 0;
00046
00047 keys_ = NULL;
00048 if(keyCount_ == 0){ return; }
00049 keys_ = new Key[keyCount_];
00050 std::memcpy(keys_, copy.keys_, sizeof(Key) * keyCount_);
00051 }
00052
00053
00054 VectorLinearInterpolator& VectorLinearInterpolator::operator =(
00055 const VectorLinearInterpolator& copy){
00056
00057 if(this == ©){ return *this; }
00058 keyCount_ = copy.keyCount_;
00059 lastestUseKeyIndex_ = 0;
00060
00061 SafeArrayDelete(keys_);
00062 if(keyCount_ == 0){ return *this; }
00063 keys_ = new Key[keyCount_];
00064 std::memcpy(keys_, copy.keys_, sizeof(Key) * keyCount_);
00065 return *this;
00066 }
00067
00068
00069
00070
00071 float VectorLinearInterpolator::getLength() const{
00072 Assert((keyCount_ > 0) && (keys_ != NULL));
00073 return keys_[keyCount_ - 1].time_;
00074 }
00075
00076
00077
00078
00079 AxisAlignedBox VectorLinearInterpolator::getBoundingBox() const{
00080 AxisAlignedBox result(AxisAlignedBox::zero);
00081 if(keyCount_ == 0){ return result; }
00082 result.set(keys_[0].value_, keys_[0].value_);
00083 for(int i = 1; i < keyCount_; i++){ result.merge(keys_[i].value_); }
00084 return result;
00085 }
00086
00087
00088
00089
00090 Vector3 VectorLinearInterpolator::interpolate(float time){
00091 Assert(keys_ != NULL);
00092
00093 if(time <= 0.f){ return keys_[0].value_; }
00094
00095 float length = getLength();
00096 int maxKeyIndex = keyCount_ - 1;
00097 if(time >= length){ return keys_[maxKeyIndex].value_; }
00098
00099
00100 int keyIndex = lastestUseKeyIndex_;
00101 Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
00102 for(int i = 0; i < maxKeyIndex; i++){
00103 const Key& preKey = keys_[keyIndex];
00104 const Key& postKey = keys_[keyIndex + 1];
00105 Assert(preKey.time_ < postKey.time_);
00106 if((time >= preKey.time_) && (time < postKey.time_)){ break; }
00107 keyIndex++;
00108 if(keyIndex == maxKeyIndex){ keyIndex = 0; }
00109 Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
00110 }
00111 Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
00112 lastestUseKeyIndex_ = keyIndex;
00113
00114
00115 const Key& key = keys_[keyIndex];
00116 float keyTime = key.time_;
00117 const Key& nextKey = keys_[keyIndex + 1];
00118 Assert(keyTime < nextKey.time_);
00119 Assert((time >= keyTime) && (time < nextKey.time_));
00120 float rate = (time - keyTime) / (nextKey.time_ - keyTime);
00121 const Vector3& keyValue = key.value_;
00122 return keyValue + (nextKey.value_ - keyValue) * rate;
00123 }
00124
00125
00126
00127
00128 void VectorLinearInterpolator::setKeyCount(int keyCount){
00129
00130 Assert(keyCount > 1);
00131 keyCount_ = keyCount;
00132 SafeArrayDelete(keys_);
00133 keys_ = new Key[keyCount_];
00134 lastestUseKeyIndex_ = 0;
00135 }
00136
00137 }
00138