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

QuaternionArrayInterpolator.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/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     // コピーコンストラクタは強制的にNULL設定
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 == &copy){ return *this; }
00060     size_ = copy.size_;
00061     length_ = copy.length_;
00062     // 代入の際は解放してNULLを設定
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     // 補間の為には2以上のsizeが必要
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 } // End of namespace Lamp
00167 //------------------------------------------------------------------------------

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