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

# TranslationBone.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 "System/stdafx.h"
    00026 #include "Translator/Model/TranslationBone.h"
    00027 #include "Translator/Model/TranslationCharacterModel.h"
    00028 #include "Graphics/Model/CharacterModel.h"
    00029 #include "Translator/Animation/TranslationAnimationUtility.h"
    00030 #include "Animation/VectorInterpolator/VectorArrayInterpolator.h"
    00031 #include "Animation/RotationInterpolator/EulerArrayInterpolator.h"
    00032
    00033 namespace LampForMaya{
    00034
    00035 //------------------------------------------------------------------------------
    00036 // コンストラクタ
    00037 TranslationBone::TranslationBone() :
    00038     scaleAnimation_(NULL), rotationAnimation_(NULL),
    00039     translationAnimation_(NULL){
    00040 }
    00041 //------------------------------------------------------------------------------
    00042 // デストラクタ
    00043 TranslationBone::~TranslationBone(){
    00044     SafeDelete(translationAnimation_);
    00045     SafeDelete(rotationAnimation_);
    00046     SafeDelete(scaleAnimation_);
    00047 }
    00048 //------------------------------------------------------------------------------
    00049 // 分析
    00050 bool TranslationBone::analyze(const MDagPath& dagPath){
    00051     MStatus result;
    00052     // 初期化
    00053     dagPath_ = dagPath;
    00054     MFnDagNode dagNode(dagPath, &result);
    00055     MayaStatusCheck(result);
    00056     object_ = dagPath_.node(&result);
    00057     MayaStatusCheck(result);
    00058     MFnIkJoint joint(object_, &result);
    00059     MayaStatusCheck(result);
    00060     // 名前取得
    00061     name_ = dagNode.name(&result).asChar();
    00062     MayaStatusCheck(result);
    00063
    00064     // 子供の取得
    00065     u_int length = dagPath_.length(&result);
    00066     MayaStatusCheck(result);
    00067     MItDag childIterator(MItDag::kBreadthFirst, MFn::kInvalid, &result);
    00068     MayaStatusCheck(result);
    00069     result = childIterator.reset(
    00070         dagPath_, MItDag::kBreadthFirst, MFn::kInvalid);
    00071     MayaStatusCheck(result);
    00072     // 自分自身を読み飛ばす
    00073     childIterator.next();
    00074     MDagPath childPath;
    00075     for( ; !childIterator.isDone(); childIterator.next()){
    00076         result = childIterator.getPath(childPath);
    00077         MayaStatusCheck(result);
    00078         // 一階層下以下になったらループを抜ける
    00079         u_int childLength = childPath.length(&result);
    00080         MayaStatusCheck(result);
    00081         if(childLength > length + 1){ break; }
    00082         // 有効なDagノードかチェック
    00083         if(childPath.node().apiType() != MFn::kJoint){
    00084             // IKエフェクタが含まれている場合がある
    00085             continue;
    00086         }
    00087         // 名前の取得
    00088         MFnDagNode childNode(childPath, &result);
    00089         MayaStatusCheck(result);
    00090         String childName(childNode.name(&result).asChar());
    00091         MayaStatusCheck(result);
    00092         bones_.add(childName);
    00093     }
    00094
    00095     // バインドポーズの取得
    00096     MObject bindPoseAttribute = dagNode.attribute("bindPose", &result);
    00097     MayaStatusCheck(result);
    00098     MPlug bindPosePlug(object_, bindPoseAttribute);
    00099     MPlugArray bindPosePlugArray;
    00100     bindPosePlug.connectedTo(bindPosePlugArray, false, true);
    00101     u_int bindPosePlugCount = bindPosePlugArray.length();
    00102     if(bindPosePlugCount != 1){
    00103         MayaErrorOut(String("TranslationBone::analyze() ") +
    00104             name_ + "に複数のポーズがバインドされています");
    00105         return false;
    00106     }
    00107     u_int logicalIndex = bindPosePlugArray[0].logicalIndex(&result);
    00108     MayaStatusCheck(result);
    00109     MObject bindPoseObject = bindPosePlugArray[0].node(&result);
    00110     MayaStatusCheck(result);
    00111     MFnDependencyNode bindPose(bindPoseObject, &result);
    00112     MayaStatusCheck(result);
    00113     // バインドポーズ行列取得
    00114     MPlug xformPlug = bindPose.findPlug("xformMatrix", &result);
    00115     MayaStatusCheck(result);
    00116     xformPlug.selectAncestorLogicalIndex(logicalIndex);
    00117     MObject xformObject;
    00118     MayaStatusCheck(xformPlug.getValue(xformObject));
    00119     MFnMatrixData xformData(xformObject);
    00120     MMatrix xform = xformData.matrix();
    00121     Matrix44 bindPoseMatrix;
    00122     for(int i = 0; i < 4; i++){
    00123         for(int j = 0; j < 4; j++){
    00124             // 転置しておく
    00125             bindPoseMatrix.m[j][i] = (float)xform(i, j);
    00126         }
    00127     }
    00128     bindPoseMatrix.invert();
    00129     inversePoseMatrix_.set(bindPoseMatrix);
    00130
    00131     // ジョイント回転
    00132     MEulerRotation jointRotation;
    00133     result = joint.getOrientation(jointRotation);
    00134     MayaStatusCheck(result);
    00135     if(jointRotation.order != MEulerRotation::kXYZ){
    00136         MayaErrorOut(String("TranslationBone::analyze() "
    00137             "ジョイント回転順序はXYZしかサポートしていません ") + name_);
    00138         return false;
    00139     }
    00140     jointRotation_.set(
    00141         (float)jointRotation.x, (float)jointRotation.y, (float)jointRotation.z);
    00142
    00143     // スケール
    00144     double scale[3];
    00145     result = joint.getScale(scale);
    00146     MayaStatusCheck(result);
    00147     scale_.set((float)scale[0], (float)scale[1], (float)scale[2]);
    00148
    00149     // 回転
    00150     MEulerRotation rotation;
    00151     result = joint.getRotation(rotation);
    00152     MayaStatusCheck(result);
    00153     if(rotation.order != MEulerRotation::kXYZ){
    00154         MayaErrorOut(String("TranslationBone::analyze() "
    00155             "回転順序はXYZしかサポートしていません ") + name_);
    00156         return false;
    00157     }
    00158     rotation_.set((float)rotation.x, (float)rotation.y, (float)rotation.z);
    00159     originalRotation_ = rotation_;
    00160
    00161     // ジョイント回転補正、アニメーション分析後に行う必要がある
    00162     Matrix33 rotationMatrix;
    00163     rotationMatrix.setRotationXYZ(originalRotation_);
    00164     rotationMatrix.addRotationXYZ(jointRotation_);
    00165     if(!rotationMatrix.getRotationXYZ(&rotation_)){
    00166         MayaMessageOut(String("TranslationBone::convertToLamp() "
    00167             "ジョイント回転補正の解が一つでは有りません") + name_);
    00168     }
    00169
    00170     // 移動
    00171     MVector translation = joint.translation(MSpace::kTransform, &result);
    00172     MayaStatusCheck(result);
    00173     translation_.set(
    00174         (float)translation.x, (float)translation.y, (float)translation.z);
    00175 /*
    00176     DebugOut("\n%s\n", name_.getBytes());
    00177     DebugOut("bindPoseMatrix %s\n", bindPoseMatrix_.toString().getBytes());
    00178     DebugOut("inverseBindPoseMatrix %s\n", inverseBindPoseMatrix_.toString().getBytes());
    00179     DebugOut("jointRotation %s\n", jointRotation_.toString().getBytes());
    00180     DebugOut("scale %s\n", scale_.toString().getBytes());
    00181     DebugOut("rotation %s\n", rotation_.toString().getBytes());
    00182     DebugOut("translation %s\n", translation_.toString().getBytes());
    00183     DebugOut("bones %d  ", bones_.getCount());
    00184     for(int i = 0; i < bones_.getCount(); i++){
    00185         DebugOut(" %s", bones_.get(i).getBytes());
    00186     }
    00187     DebugOut("\n");
    00188 //*/
    00189     return true;
    00190 }
    00191 //------------------------------------------------------------------------------
    00192 // モデル行列の構築
    00193 void TranslationBone::buildModelMatrix(
    00194     TranslationCharacterModel* characterModel, const Matrix34& parentMatrix){
    00195     inversePoseMatrix_ = inversePoseMatrix_ * parentMatrix;
    00196     for(int i = 0; i < bones_.getCount(); i++){
    00197         TranslationBone* bone = characterModel->searchBone(bones_.get(i));
    00198         bone->buildModelMatrix(characterModel, inversePoseMatrix_);
    00199     }
    00200 }
    00201 //------------------------------------------------------------------------------
    00202 // アニメーションの分析
    00203 bool TranslationBone::analyzeAnimation(int startTime, int endTime){
    00204     // スケールアニメーション
    00205     scaleAnimation_ =
    00206         TranslationAnimationUtility::analyzeVectorAnimation(
    00207         object_, "scale", scale_, startTime, endTime);
    00208     // 回転アニメーション
    00209     rotationAnimation_ =
    00210         TranslationAnimationUtility::analyzeRotationAnimation(
    00211         object_, "rotate", originalRotation_, startTime, endTime);
    00212     // ジョイント回転補正
    00213     if(rotationAnimation_ != NULL){
    00214         int size = rotationAnimation_->getSize();
    00215         for(int i = 0; i < size; i++){
    00216             Vector3 rotation = rotationAnimation_->getValue(i);
    00217             Matrix33 rotationMatrix;
    00218             rotationMatrix.setRotationXYZ(rotation);
    00219             rotationMatrix.addRotationXYZ(jointRotation_);
    00220             if(!rotationMatrix.getRotationXYZ(&rotation)){
    00221                 MayaMessageOut(String("TranslationBone::analyzeAnimation() "
    00222                     "ジョイント回転補正の解が一つでは有りません") + name_);
    00223             }
    00224             rotationAnimation_->setValue(i, rotation);
    00225         }
    00226     }
    00227     // 移動アニメーション
    00228     translationAnimation_ =
    00229         TranslationAnimationUtility::analyzeVectorAnimation(
    00230         object_, "translate", translation_, startTime, endTime);
    00231     return true;
    00232 }
    00233 //------------------------------------------------------------------------------
    00234 // Lampへの変換
    00235 bool TranslationBone::convertToLamp(CharacterModel* model){
    00236     // 変換
    00237     Bone* bone = model->createBone(name_);
    00238     bone->setInversePoseMatrix(inversePoseMatrix_);
    00239     bone->setScale(scale_);
    00240     bone->setRotationXYZ(rotation_);
    00241     bone->setTranslation(translation_);
    00242     return true;
    00243 }
    00244 //------------------------------------------------------------------------------
    00245 // ボーンのリンク
    00246 bool TranslationBone::boneLink(CharacterModel* model, int index){
    00247     Bone* bone = model->getBone(index);
    00248     for(int i = 0; i < bones_.getCount(); i++){
    00249         Bone* child = model->searchBone(bones_.get(i));
    00250         if(child == NULL){
    00251             MayaErrorOut(String("TranslationBone::boneLink() "
    00252                 "ボーンが見つかりません ") + bones_.get(i));
    00253             return false;
    00254         }
    00255         bone->addBone(child);
    00256     }
    00257     return true;
    00258 }
    00259 //------------------------------------------------------------------------------
    00260 // スケールアニメーションの取得
    00261 VectorInterpolator* TranslationBone::getScaleAnimation(
    00262     int startTime, int endTime){
    00263     if(scaleAnimation_ == NULL){ return NULL; }
    00264     int size = endTime - startTime + 1;
    00265     VectorArrayInterpolator* array = new VectorArrayInterpolator();
    00266     array->setSize(size);
    00267     for(int i = 0; i < size; i++){
    00268         array->setValue(i, scaleAnimation_->getValue(startTime + i));
    00269     }
    00270     return array;
    00271 }
    00272 //------------------------------------------------------------------------------
    00273 // 回転アニメーションの取得
    00274 RotationInterpolator* TranslationBone::getRotationAnimation(
    00275     int startTime, int endTime){
    00276     if(rotationAnimation_ == NULL){ return NULL; }
    00277     int size = endTime - startTime + 1;
    00278     EulerArrayInterpolator* array = new EulerArrayInterpolator();
    00279     array->setSize(size);
    00280     for(int i = 0; i < size; i++){
    00281         array->setValue(i, rotationAnimation_->getValue(startTime + i));
    00282     }
    00283     return array;
    00284 }
    00285 //------------------------------------------------------------------------------
    00286 // 移動アニメーションの取得
    00287 VectorInterpolator* TranslationBone::getTranslationAnimation(
    00288     int startTime, int endTime){
    00289     if(translationAnimation_ == NULL){ return NULL; }
    00290     int size = endTime - startTime + 1;
    00291     VectorArrayInterpolator* array = new VectorArrayInterpolator();
    00292     array->setSize(size);
    00293     for(int i = 0; i < size; i++){
    00294         array->setValue(i, translationAnimation_->getValue(startTime + i));
    00295     }
    00296     return array;
    00297 }
    00298 //------------------------------------------------------------------------------
    00299 } // End of namespace Lamp
    00300 //------------------------------------------------------------------------------