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