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

# TranslationInstanceManager.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/Instance/TranslationInstanceManager.h"
    00027 #include "Translator/Instance/TranslationSceneNodeInstance.h"
    00028 #include "Translator/Instance/TranslationLightInstance.h"
    00029 #include "Translator/Instance/TranslationModelInstance.h"
    00030 #include "Translator/SceneNode/TranslationSceneNodeManager.h"
    00031 #include "Graphics/Scene/Scene.h"
    00032 #include "Graphics/SceneNode/SceneNodeManager.h"
    00033 #include "Graphics/Model/Model.h"
    00034
    00035 namespace LampForMaya{
    00036
    00037 //------------------------------------------------------------------------------
    00038 // コンストラクタ
    00039 TranslationInstanceManager::TranslationInstanceManager() :
    00040     array_(256), convertedArray_(256){
    00041 }
    00042 //------------------------------------------------------------------------------
    00043 // デストラクタ
    00044 TranslationInstanceManager::~TranslationInstanceManager(){
    00045     Assert(array_.getCount() == 0);
    00046     Assert(convertedArray_.getCount() == 0);
    00047     if((array_.getCount() != 0) || (convertedArray_.getCount() != 0)){
    00048         clear();
    00049     }
    00050 }
    00051 //------------------------------------------------------------------------------
    00052 // クリア
    00053 int TranslationInstanceManager::clear(){
    00054     int result = 0;
    00055     // 配列のクリア
    00056     int count = array_.getCount();
    00057     Assert(count == 0);
    00058     for(int i = 0; i < count; i++){ delete array_.get(i); }
    00059     array_.clear();
    00060     result += count;
    00061     // コンバート済み配列のクリア
    00062     int convertedCount = convertedArray_.getCount();
    00063     for(int i = 0; i < convertedCount; i++){ delete convertedArray_.get(i); }
    00064     convertedArray_.clear();
    00065     result += convertedCount;
    00066     return result;
    00067 }
    00068 //------------------------------------------------------------------------------
    00069 // インスタンスの収集
    00070 bool TranslationInstanceManager::collectInstances(){
    00071     MStatus result;
    00072     MItDag dagIterator(MItDag::kBreadthFirst, MFn::kInvalid, &result);
    00073     MayaStatusCheck(result);
    00074     MDagPath dagPath;
    00075     for( ; !dagIterator.isDone(); dagIterator.next()){
    00076         result = dagIterator.getPath(dagPath);
    00077         MayaStatusCheck(result);
    00078         MFnDagNode dagNode(dagPath, &result);
    00079         MayaStatusCheck(result);
    00080         // 最上階層以下になったらループを抜ける
    00081         u_int length = dagPath.length(&result);
    00082         MayaStatusCheck(result);
    00083         if(length > 1){ break; }
    00084         // 有効なDagノードかチェック、シーンノードのチェック使用
    00085         if(!TranslationSceneNodeManager::checkValidDagNode(dagPath)){
    00086             continue;
    00087         }
    00088         // 最上階層かつトランスフォームファンクションを持っていなければキャンセル
    00089         // これでworldオブジェクトをはじける
    00090         if(!dagPath.hasFn(MFn::kTransform)){ continue; }
    00091         // グラウンドプレーンならキャンセル
    00092         if(MayaDAGUtility::getName(dagPath) == "groundPlane_transform"){
    00093             continue;
    00094         }
    00095         // インスタンスの解析
    00096         if(!analysisInstance(dagPath)){ return false; }
    00097     }
    00098     return true;
    00099 }
    00100 //------------------------------------------------------------------------------
    00101 // インスタンスの解析
    00102 bool TranslationInstanceManager::analysisInstance(MDagPath dagPath){
    00103     MStatus result;
    00104     MFnDagNode dagNode(dagPath, &result);
    00105     MayaStatusCheck(result);
    00106
    00107     // インスタンスオブジェクトかどうか
    00108     u_int instanceNumber = dagPath.instanceNumber(&result);
    00109     MayaStatusCheck(result);
    00110     if(instanceNumber > 0){
    00111         // インスタンスオブジェクトの作成し、それ以上の子はたどらない
    00112         String instanceName = MayaDAGUtility::getName(dagPath);
    00113         TranslationInstance* instance;
    00114         if(dagPath.hasFn(MFn::kTransform)){
    00115             // シーンノードインスタンス
    00116             instance = new TranslationSceneNodeInstance(dagPath, instanceName);
    00117         }else if(dagPath.hasFn(MFn::kLight)){
    00118             // ライトインスタンス
    00119             instance = new TranslationLightInstance(dagPath, instanceName);
    00120         }else{
    00121             // モデルインスタンス
    00122             instance = new TranslationModelInstance(dagPath, instanceName);
    00123         }
    00124         // 各インスタンスの解析
    00125         if(!instance->analyze()){
    00126             delete instance;
    00127             return false;
    00128         }
    00129         array_.add(instance);
    00130         return true;
    00131     }
    00132
    00133     // インスタンスではなかったので子をたどる
    00134     u_int length = dagPath.length(&result);
    00135     MItDag childIterator(MItDag::kBreadthFirst, MFn::kInvalid, &result);
    00136     MayaStatusCheck(result);
    00137     result = childIterator.reset(
    00138         dagPath, MItDag::kBreadthFirst, MFn::kInvalid);
    00139     MayaStatusCheck(result);
    00140     // 自分自身を読み飛ばす
    00141     childIterator.next();
    00142     MDagPath childPath;
    00143     for( ; !childIterator.isDone(); childIterator.next()){
    00144         result = childIterator.getPath(childPath);
    00145         MayaStatusCheck(result);
    00146         // 一階層下以下になったらループを抜ける
    00147         u_int childLength = childPath.length(&result);
    00148         MayaStatusCheck(result);
    00149         if(childLength > length + 1){ break; }
    00150         // 有効なDagノードかチェック、シーンノードのチェック使用
    00151         if(!TranslationSceneNodeManager::checkValidDagNode(childPath)){
    00152             continue;
    00153         }
    00154         // 子の分析
    00155         analysisInstance(childPath);
    00156     }
    00157     return true;
    00158 }
    00159 //------------------------------------------------------------------------------
    00160 // Lampへの変換
    00161 //------------------------------------------------------------------------------
    00162 // Lampへの変換
    00163 bool TranslationInstanceManager::convertToLamp(Scene* scene){
    00164     // コピー元およびその子供のSceneNode,Modelがインスタンス対象になっていないか
    00165     //      インスタンス対象になっていれば、それをさらに同じチェックにかける
    00166     //      インスタンス対象になっていなければ、インスタンス解決
    00167     // 全てのインスタンスオブジェクトが片付くまで繰り返す
    00168     while(true){
    00169         if(array_.getCount() == 0){ break; }
    00170         TranslationInstance* instance =
    00171             searchValidInstance(scene, array_.get(0));
    00172         // インスタンスの解決を行う
    00173         if(!instance->convertToLamp(scene)){ return false; }
    00174         array_.removeByValue(instance);
    00175         convertedArray_.add(instance);
    00176     }
    00177     return true;
    00178 }
    00179 //------------------------------------------------------------------------------
    00180 // インスタンスの解決
    00181 TranslationInstance* TranslationInstanceManager::searchValidInstance(
    00182     Scene* scene, TranslationInstance* instance){
    00183     SceneNodeManager* sceneNodeManager = scene->getSceneNodeManager();
    00184     // シーンノードインスタンスでないなら無条件でインスタンス解決を行ってよい
    00185     if(!instance->isTranslationSceneNodeInstance()){ return instance; }
    00186     // コピー元が他のインスタンスを含んでいないか調査
    00187     int instanceCount = array_.getCount();
    00188     TranslationInstance* includeInstance = NULL;
    00189     for(int i = 0; i < instanceCount; i++){
    00190         TranslationInstance* target = array_.get(i);
    00191         // 自分自身は無視
    00192         if(target == instance){ continue; }
    00193         // 同じオブジェクトをインスタンス化しようとしている時は無視
    00194         if(instance->getName() == target->getName()){ continue; }
    00195         SceneNode* sceneNode = sceneNodeManager->search(instance->getName());
    00196         if(searchSceneNode(sceneNode, target->getName())){
    00197             // ターゲットと同じ名前のオブジェクトが見つかった
    00198             includeInstance = target;
    00199             break;
    00200         }
    00201     }
    00202     // 他のインスタンスを先に解決する
    00203     if(includeInstance != NULL){
    00204         return searchValidInstance(scene, includeInstance);
    00205     }
    00206     return instance;
    00207 }
    00208 //------------------------------------------------------------------------------
    00209 // シーンノードの検索
    00210 bool TranslationInstanceManager::searchSceneNode(
    00211     SceneNode* sceneNode, const String& targetName){
    00212     if(sceneNode->getName().equals(targetName)){ return true; }
    00213     // シーンリーフの検索
    00214     int sceneLeafCount = sceneNode->getSceneLeafCount();
    00215     for(int i = 0; i < sceneLeafCount; i++){
    00216         SceneLeaf* sceneLeaf = sceneNode->getSceneLeaf(i);
    00217         if(sceneLeaf->getName().equals(targetName)){ return true; }
    00218     }
    00219     // 子シーンノードの検索
    00220     int sceneNodeCount = sceneNode->getSceneNodeCount();
    00221     for(int i = 0; i < sceneNodeCount; i++){
    00222         bool result = searchSceneNode(sceneNode->getSceneNode(i), targetName);
    00223         if(result){ return true; }
    00224     }
    00225     return false;
    00226 }
    00227 //------------------------------------------------------------------------------
    00228 // アニメーション
    00229 //------------------------------------------------------------------------------
    00230 // アニメーションの変換
    00231 bool TranslationInstanceManager::convertAnimation(
    00232     AnimationManager* animationManager, AnimationSet* animationSet){
    00233     int count = convertedArray_.getCount();
    00234     for(int i = 0; i < count; i++){
    00235         if(!convertedArray_.get(i)->convertAnimation(
    00236             animationManager, animationSet)){
    00237             return false;
    00238         }
    00239     }
    00240     return true;
    00241 }
    00242 //------------------------------------------------------------------------------
    00243 } // End of namespace LampForMaya
    00244 //------------------------------------------------------------------------------