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 //------------------------------------------------------------------------------