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/RotationInterpolator/EulerArrayInterpolator.h"
00027 #include "Animation/RotationInterpolator/QuaternionArrayInterpolator.h"
00028
00029 namespace Lamp{
00030
00031
00032
00033 EulerArrayInterpolator::EulerArrayInterpolator() :
00034 array_(NULL), size_(0), length_(0.f){
00035 }
00036
00037
00038 EulerArrayInterpolator::~EulerArrayInterpolator(){
00039 SafeArrayDelete(array_);
00040 }
00041
00042
00043 EulerArrayInterpolator::EulerArrayInterpolator(
00044 const EulerArrayInterpolator& copy){
00045 size_ = copy.size_;
00046 length_ = copy.length_;
00047
00048 array_ = NULL;
00049 if(size_ == 0){ return; }
00050 array_ = new Vector3[size_];
00051 std::memcpy(array_, copy.array_, sizeof(Vector3) * size_);
00052 }
00053
00054
00055 EulerArrayInterpolator& EulerArrayInterpolator::operator =(
00056 const EulerArrayInterpolator& copy){
00057
00058 if(this == ©){ return *this; }
00059 size_ = copy.size_;
00060 length_ = copy.length_;
00061
00062 SafeArrayDelete(array_);
00063 if(size_ == 0){ return *this; }
00064 array_ = new Vector3[size_];
00065 std::memcpy(array_, copy.array_, sizeof(Vector3) * size_);
00066 return *this;
00067 }
00068
00069
00070
00071
00072 Vector3 EulerArrayInterpolator::eulerInterpolate(float time){
00073 Assert(array_ != NULL);
00074
00075 if(time <= 0.f){ return array_[0]; }
00076
00077 if(time >= length_){ return array_[size_ - 1]; }
00078
00079 Quaternion resultQuaternion = quaternionInterpolate(time);
00080 Vector3 result;
00081 resultQuaternion.getRotationXYZ(&result);
00082 #ifdef _DEBUG
00083 if((!Math::classCheck(result.x)) ||
00084 (!Math::classCheck(result.y)) ||
00085 (!Math::classCheck(result.z))){
00086 _asm{ int 3 }
00087 }
00088 #endif
00089 return result;
00090 }
00091
00092
00093 Quaternion EulerArrayInterpolator::quaternionInterpolate(float time){
00094 Assert(array_ != NULL);
00095 Quaternion result;
00096
00097 if(time <= 0.f){
00098 result.setRotationXYZ(array_[0]);
00099 return result;
00100 }
00101
00102 if(time >= length_){
00103 result.setRotationXYZ(array_[size_ - 1]);
00104 return result;
00105 }
00106
00107 float integer, rate;
00108 rate = Math::modf(time, &integer);
00109 int index = (int)integer;
00110
00111 Quaternion pre, post;
00112 pre.setRotationXYZ(array_[index]);
00113 post.setRotationXYZ(array_[index + 1]);
00114
00115 result = Quaternion::correctSlerp(pre, post, rate);
00116 #ifdef _DEBUG
00117 if((!Math::classCheck(result.x)) ||
00118 (!Math::classCheck(result.y)) ||
00119 (!Math::classCheck(result.z)) ||
00120 (!Math::classCheck(result.w))){
00121 _asm{ int 3 }
00122 }
00123 #endif
00124 return result;
00125 }
00126
00127
00128
00129
00130 void EulerArrayInterpolator::setSize(int size){
00131
00132 Assert(size > 1);
00133 size_ = size;
00134 length_ = (float)(size_ - 1);
00135 SafeArrayDelete(array_);
00136 array_ = new Vector3[size_];
00137 }
00138
00139
00140 void EulerArrayInterpolator::setValue(int index, const Vector3& value){
00141 Assert(array_ != NULL);
00142 Assert(index >= 0);
00143 Assert(index < size_);
00144
00145 Vector3 correctValue;
00146 for(int i = 0; i < 3; i++){
00147 float temp = value.array[i];
00148 if((temp <= Math::PI) && (temp >= -Math::PI)){
00149 correctValue.array[i] = temp;
00150 continue;
00151 }
00152 temp += Math::PI;
00153 if(temp < 0.f){
00154 temp = Math::abs(temp);
00155 temp = Math::fmod(temp, Math::doublePI) - Math::PI;
00156 temp *= -1;
00157 }else{
00158 temp = Math::fmod(temp, Math::doublePI) - Math::PI;
00159 }
00160 correctValue.array[i] = temp;
00161 }
00162 array_[index] = correctValue;
00163 }
00164
00165
00166
00167
00168 QuaternionArrayInterpolator*
00169 EulerArrayInterpolator::convertQuaternionArrayInterpolator() const{
00170 QuaternionArrayInterpolator* result = new QuaternionArrayInterpolator();
00171 int size = getSize();
00172 result->setSize(size);
00173 Quaternion quaternion;
00174 for(int i = 0; i < size; i++){
00175 quaternion.setRotationXYZ(getValue(i));
00176 result->setValue(i, quaternion);
00177 }
00178
00179 result->correctValue();
00180 return result;
00181 }
00182
00183 }
00184