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

# QuaternionLinearInterpolator.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/QuaternionLinearInterpolator.h"
    00027
    00028 namespace Lamp{
    00029
    00030 //------------------------------------------------------------------------------
    00031 // コンストラクタ
    00032 QuaternionLinearInterpolator::QuaternionLinearInterpolator() :
    00033     keys_(NULL), keyCount_(0), lastestUseKeyIndex_(0){
    00034 }
    00035 //------------------------------------------------------------------------------
    00036 // デストラクタ
    00037 QuaternionLinearInterpolator::~QuaternionLinearInterpolator(){
    00038     SafeArrayDelete(keys_);
    00039 }
    00040 //------------------------------------------------------------------------------
    00041 // コピーコンストラクタ
    00042 QuaternionLinearInterpolator::QuaternionLinearInterpolator(
    00043     const QuaternionLinearInterpolator& copy){
    00044     keyCount_ = copy.keyCount_;
    00045     lastestUseKeyIndex_ = 0;
    00046     // コピーコンストラクタは強制的にNULL設定
    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 QuaternionLinearInterpolator& QuaternionLinearInterpolator::operator =(
    00055     const QuaternionLinearInterpolator& copy){
    00056     // 自分自身ならリターン
    00057     if(this == &copy){ return *this; }
    00058     keyCount_ = copy.keyCount_;
    00059     lastestUseKeyIndex_ = 0;
    00060     // 代入の際は解放してNULLを設定
    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 QuaternionLinearInterpolator::getLength() const{
    00072     Assert((keyCount_ > 0) && (keys_ != NULL));
    00073     return keys_[keyCount_ - 1].time_;
    00074 }
    00075 //------------------------------------------------------------------------------
    00076 // 補間
    00077 //------------------------------------------------------------------------------
    00078 // オイラー補間
    00079 Vector3 QuaternionLinearInterpolator::eulerInterpolate(float time){
    00080     // 四元数で補間してオイラー角に変換する
    00081     Quaternion resultQuaternion = quaternionInterpolate(time);
    00082     Vector3 result;
    00083     resultQuaternion.getRotationXYZ(&result);
    00084 #ifdef _DEBUG
    00085     if((!Math::classCheck(result.x)) ||
    00086         (!Math::classCheck(result.y)) ||
    00087         (!Math::classCheck(result.z))){
    00088         _asm{ int 3 }
    00089     }
    00090 #endif
    00091     return result;
    00092 }
    00093 //------------------------------------------------------------------------------
    00094 // 四元数補間
    00095 Quaternion QuaternionLinearInterpolator::quaternionInterpolate(float time){
    00096     Assert(keys_ != NULL);
    00097     // 時間が前にあふれている
    00098     if(time <= 0.f){ return keys_[0].value_; }
    00099     // 時間が後ろにあふれている
    00100     float length = getLength();
    00101     int maxKeyIndex = keyCount_ - 1;
    00102     if(time >= length){ return keys_[maxKeyIndex].value_; }
    00103
    00104     // キーの探索、前回のキー位置から探索する
    00105     int keyIndex = lastestUseKeyIndex_;
    00106     Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
    00107     for(int i = 0; i < maxKeyIndex; i++){
    00108         const Key& preKey = keys_[keyIndex];
    00109         const Key& postKey = keys_[keyIndex + 1];
    00110         Assert(preKey.time_ < postKey.time_);
    00111         if((time >= preKey.time_) && (time < postKey.time_)){ break; }
    00112         keyIndex++;
    00113         if(keyIndex == maxKeyIndex){ keyIndex = 0; }
    00114         Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
    00115     }
    00116     Assert((keyIndex >= 0) && (keyIndex < maxKeyIndex));
    00117     lastestUseKeyIndex_ = keyIndex;
    00118
    00119     // 線形補間
    00120     const Key& key = keys_[keyIndex];
    00121     float keyTime = key.time_;
    00122     const Key& nextKey = keys_[keyIndex + 1];
    00123     Assert(keyTime < nextKey.time_);
    00124     Assert((time >= keyTime) && (time < nextKey.time_));
    00125     float rate = (time - keyTime) / (nextKey.time_ - keyTime);
    00126     Assert(key.value_.dotProduct(nextKey.value_) >= 0.f);
    00127     Assert(key.value_.isUnit() && nextKey.value_.isUnit());
    00128     Quaternion result = Quaternion::slerp(key.value_, nextKey.value_, rate);
    00129 #ifdef _DEBUG
    00130     if((!Math::classCheck(result.x)) ||
    00131         (!Math::classCheck(result.y)) ||
    00132         (!Math::classCheck(result.z)) ||
    00133         (!Math::classCheck(result.w))){
    00134         _asm{ int 3 }
    00135     }
    00136 #endif
    00137     return result;
    00138 }
    00139 //------------------------------------------------------------------------------
    00140 // キー
    00141 //------------------------------------------------------------------------------
    00142 // キー数の設定
    00143 void QuaternionLinearInterpolator::setKeyCount(int keyCount){
    00144     // 補間の為には2以上のキー数が必要
    00145     Assert(keyCount > 1);
    00146     keyCount_ = keyCount;
    00147     SafeArrayDelete(keys_);
    00148     keys_ = new Key[keyCount_];
    00149     lastestUseKeyIndex_ = 0;
    00150 }
    00151 //------------------------------------------------------------------------------
    00152 } // End of namespace Lamp
    00153 //------------------------------------------------------------------------------