Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

EulerArrayInterpolator.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * オイラー回転配列補間実装
00022  * @author Junpee
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     // コピーコンストラクタは強制的にNULL設定
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 == &copy){ return *this; }
00059     size_ = copy.size_;
00060     length_ = copy.length_;
00061     // 代入の際は解放してNULLを設定
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     // 補間の為には2以上のsizeが必要
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     // +-PIにクランプ
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 } // End of namespace Lamp
00184 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:30 2005 for Lamp by doxygen 1.3.2