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

Generated on Wed Mar 16 10:29:55 2005 for LampForMaya by doxygen 1.3.2