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