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

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