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

# LampTranslator.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  * Lampトランスレータ実装
    00022  * @author Junpee
    00023  */
    00024
    00025 #include "System/stdafx.h"
    00026 #include "Translator/Core/LampTranslator.h"
    00027 #include "Translator/Scene/TranslationScene.h"
    00028 #include <Core/Utility/Timer.h>
    00029 #include <Core/Utility/StringTokenizer.h>
    00030 #include <Graphics/System/LampGraphics.h>
    00031 #include <Graphics/InputOutput/TextSceneSaver.h>
    00032 #include <Graphics/InputOutput/BinarySceneSaver.h>
    00033 #include <Graphics/SceneFilter/SceneFilter.h>
    00034 #include <Animation/System/AnimationManager.h>
    00035 #include <Animation/System/AnimationSet.h>
    00036 #include <Animation/Utility/AnimationCompressor.h>
    00037 #include <Animation/InputOutput/TextAnimationSaver.h>
    00038 #include <Animation/InputOutput/BinaryAnimationSaver.h>
    00039
    00040 namespace LampForMaya{
    00041
    00042 //------------------------------------------------------------------------------
    00043 // コンストラクタ
    00044 LampTranslator::LampTranslator() :
    00045     translationScene_(NULL), scene_(NULL), animationManager_(NULL),
    00046     animationSet_(NULL), exportSceneFlag_(true), picturePath_("pictures/"),
    00047     meshOptimizeFlag_(true), characterScale_(1.f), exportAnimationFlag_(true),
    00048     deleteStaticChannelsFlag_(false){
    00049 }
    00050 //------------------------------------------------------------------------------
    00051 // デストラクタ
    00052 LampTranslator::~LampTranslator(){
    00053     Assert(translationScene_ == NULL);
    00054     Assert(scene_ == NULL);
    00055     Assert(animationManager_ == NULL);
    00056     Assert(animationSet_ == NULL);
    00057 }
    00058 //------------------------------------------------------------------------------
    00059 // 書き出し
    00060 MStatus LampTranslator::write(const MFileObject& file,
    00061     const MString& optionsString, MPxFileTranslator::FileAccessMode mode,
    00062     bool textFlag){
    00063     Timer::Tick startTime = Timer::getTick();
    00064     textExportFlag_ = textFlag;
    00065     // 全てエクスポートのみ受け付ける
    00066     if(mode != MPxFileTranslator::kExportAccessMode){
    00067         MayaErrorOut("\"Export All\"しかサポートしていません。");
    00068         return errorCleanup();
    00069     }
    00070     // オプション解析
    00071     analyzeOption(String(optionsString.asChar()));
    00072     // 開始メッセージ出力
    00073     outputStartMessage();
    00074
    00075     // 静的チャンネル削除
    00076     if(exportAnimationFlag_ && deleteStaticChannelsFlag_){
    00077         MGlobal::executeCommand("delete -all -staticChannels;", false, true);
    00078     }
    00079
    00080     //--------------------------------------------------------------------------
    00081     // 変換用シーンによる情報の収集
    00082     Timer::Tick startSceneCollectionTime = Timer::getTick();
    00083     translationScene_ = new TranslationScene();
    00084     bool result = translationScene_->collection();
    00085     if(!result){ return errorCleanup(); }
    00086     float sceneCollectionTime =
    00087         Timer::getInterval(startSceneCollectionTime)  * 0.001f;
    00088
    00089
    00090     // 変換用シーンによるアニメーション情報の収集
    00091     Timer::Tick startAnimationCollectionTime = Timer::getTick();
    00092     result = translationScene_->collectAnimation();
    00093     if(!result){ return errorCleanup(); }
    00094     float animationCollectionTime =
    00095         Timer::getInterval(startAnimationCollectionTime)  * 0.001f;
    00096
    00097     //--------------------------------------------------------------------------
    00098     // Lampシーンへの変換
    00099     Timer::Tick startSceneTranslateTime = Timer::getTick();
    00100     scene_ = LampGraphics::createScene("TranslateScene");
    00101     result = translationScene_->convertToLamp(scene_);
    00102     if(!result){ return errorCleanup(); }
    00103     float sceneTranslateTime =
    00104         Timer::getInterval(startSceneTranslateTime)  * 0.001f;
    00105
    00106     // Lampアニメーションへの変換
    00107     Timer::Tick startAnimationTranslateTime = Timer::getTick();
    00108     animationManager_ = new AnimationManager();
    00109     String animationName = file.name().asChar();
    00110     if(textFlag){
    00111         Assert(animationName.endsWith("." + getTextSceneExtension()));
    00112     }else{
    00113         Assert(animationName.endsWith("." + getBinarySceneExtension()));
    00114     }
    00115     animationName = animationName.getSubstring(0, animationName.getSize() - 4);
    00116     animationSet_ = animationManager_->createAnimationSet(animationName);
    00117     result = translationScene_->convertAnimation(
    00118         animationManager_, animationSet_);
    00119     if(!result){ return errorCleanup(); }
    00120     float animationTranslateTime =
    00121         Timer::getInterval(startAnimationTranslateTime)  * 0.001f;
    00122
    00123     // アニメーションの圧縮
    00124     Timer::Tick startAnimationCompressTime = Timer::getTick();
    00125     AnimationCompressor animationCompressor;
    00126     animationCompressor.compress(animationSet_);
    00127     float animationCompressTime =
    00128         Timer::getInterval(startAnimationCompressTime)  * 0.001f;
    00129
    00130     //--------------------------------------------------------------------------
    00131     // 変換用シーンの削除
    00132     translationScene_->clear();
    00133     delete translationScene_;
    00134     translationScene_ = NULL;
    00135
    00136     //--------------------------------------------------------------------------
    00137     // シーンへのフィルタ処理
    00138     Timer::Tick startFilterTime = Timer::getTick();
    00139     SceneFilter sceneFilter(scene_);
    00140     // ピクチャパス変更
    00141     if(exportSceneFlag_){
    00142         if(!sceneFilter.filter(String("ChangePicturePath ") + picturePath_)){
    00143             return errorCleanup();
    00144         }
    00145         // バウンディング算出
    00146         String scaleString;
    00147         scaleString.format("characterScale %.8f", characterScale_);
    00148         // バウンディングボックス算出
    00149         if(!sceneFilter.filter("CalculateBoundingBox " + scaleString)){
    00150             return errorCleanup();
    00151         }
    00152         // バウンディングスフィア算出
    00153         if(!sceneFilter.filter("CalculateBoundingSphere " + scaleString)){
    00154             return errorCleanup();
    00155         }
    00156         // メッシュ最適化
    00157         if(meshOptimizeFlag_){
    00158             // インデックストライアングル構築
    00159             if(!sceneFilter.filter("BuildIndexedTriangle")){
    00160                 return errorCleanup();
    00161             }
    00162         }
    00163     }
    00164     // シーンの論理チェック
    00165     if(!sceneFilter.filter("SceneLogicCheck")){ return errorCleanup(); }
    00166     float filterTime = Timer::getInterval(startFilterTime)  * 0.001f;
    00167
    00168     //--------------------------------------------------------------------------
    00169     // シーン出力
    00170     Timer::Tick startSceneExportTime = Timer::getTick();
    00171     if(exportSceneFlag_){
    00172         if(textExportFlag_){
    00173             TextSceneSaver* textSceneSaver = new TextSceneSaver();
    00174             textSceneSaver->save(file.fullName().asChar(), scene_);
    00175             delete textSceneSaver;
    00176         }else{
    00177             BinarySceneSaver* binarySceneSaver = new BinarySceneSaver();
    00178             binarySceneSaver->save(file.fullName().asChar(), scene_);
    00179             delete binarySceneSaver;
    00180         }
    00181     }
    00182     float sceneExportTime = Timer::getInterval(startSceneExportTime)  * 0.001f;
    00183
    00184     // Lampシーンの破棄
    00185     scene_->clear();
    00186     LampGraphics::destroyScene(scene_);
    00187     scene_ = NULL;
    00188
    00189     //--------------------------------------------------------------------------
    00190     // アニメーション出力
    00191     Timer::Tick startAnimationExportTime = Timer::getTick();
    00192     if(exportAnimationFlag_ && (animationSet_->getAnimationCount() != 0)){
    00193         String animationFileName = file.fullName().asChar();
    00194         if(textExportFlag_){
    00195             Assert(animationFileName.endsWith("." + getTextSceneExtension()));
    00196             animationFileName = animationFileName.getSubstring(
    00197                 0, animationFileName.getSize() - 3);
    00198             animationFileName += getTextAnimationExtension();
    00199             TextAnimationSaver* textAnimationSaver = new TextAnimationSaver();
    00200             textAnimationSaver->save(animationFileName, animationManager_);
    00201             delete textAnimationSaver;
    00202         }else{
    00203             Assert(animationFileName.endsWith("." + getBinarySceneExtension()));
    00204             animationFileName = animationFileName.getSubstring(
    00205                 0, animationFileName.getSize() - 3);
    00206             animationFileName += getBinaryAnimationExtension();
    00207             BinaryAnimationSaver* binaryAnimationSaver =
    00208                 new BinaryAnimationSaver();
    00209             binaryAnimationSaver->save(animationFileName, animationManager_);
    00210             delete binaryAnimationSaver;
    00211         }
    00212     }
    00213     float animationExportTime =
    00214         Timer::getInterval(startAnimationExportTime)  * 0.001f;
    00215
    00216     // Lampアニメーションの破棄
    00217     animationManager_->clear();
    00218     delete animationManager_;
    00219     animationSet_ = NULL;
    00220     animationManager_ = NULL;
    00221
    00222     //--------------------------------------------------------------------------
    00223     // 終了メッセージ
    00224     float totalTime = Timer::getInterval(startTime)  * 0.001f;
    00225     float otherTime = totalTime - (
    00226         sceneCollectionTime + animationCollectionTime +
    00227         sceneTranslateTime + animationTranslateTime + animationCompressTime +
    00228         filterTime + sceneExportTime + animationExportTime);
    00229     String finishMessage;
    00230     finishMessage.format("\nエクスポート終了  トータル　%.2f秒\n"
    00231         "　シーン情報収集  %.2f秒\n"
    00232         "　アニメーション情報収集  %.2f秒\n"
    00233         "　シーン変換  %.2f秒\n"
    00234         "　アニメーション変換  %.2f秒\n"
    00235         "　アニメーション圧縮  %.2f秒\n"
    00236         "　フィルタ  %.2f秒\n"
    00237         "　シーン出力  %.2f秒\n"
    00238         "　アニメーション出力  %.2f秒\n"
    00239         "　その他  %.2f秒\n",
    00240         totalTime, sceneCollectionTime, animationCollectionTime,
    00241         sceneTranslateTime, animationTranslateTime, animationCompressTime,
    00242         filterTime, sceneExportTime, animationExportTime, otherTime);
    00243     MayaMessageOut(finishMessage);
    00244     return MStatus(MStatus::kSuccess);
    00245 }
    00246 //------------------------------------------------------------------------------
    00247 // エラー後始末
    00248 MStatus LampTranslator::errorCleanup(){
    00249     if(translationScene_ != NULL){
    00250         translationScene_->clear();
    00251         delete translationScene_;
    00252         translationScene_ = NULL;
    00253     }
    00254     if(scene_ != NULL){
    00255         scene_->clear();
    00256         LampGraphics::destroyScene(scene_);
    00257         scene_ = NULL;
    00258     }
    00259     if(animationManager_ != NULL){
    00260         animationManager_->clear();
    00261         delete animationManager_;
    00262         animationSet_ = NULL;
    00263         animationManager_ = NULL;
    00264     }
    00265     return MStatus(MStatus::kFailure);
    00266 }
    00267 //------------------------------------------------------------------------------
    00268 // オプション解析
    00269 void LampTranslator::analyzeOption(const String& options){
    00270     StringTokenizer optionList(options, ";");
    00271     while(optionList.hasMoreTokens()){
    00272         StringTokenizer option(optionList.getNextToken(), "=");
    00273         if(!option.hasMoreTokens()){ continue; }
    00274         String optionName = option.getNextToken();
    00275         if(!option.hasMoreTokens()){ continue; }
    00276         String optionData = option.getNextToken();
    00277         if(optionName == "scene"){
    00278             exportSceneFlag_ = (optionData != "0");
    00279         }else if(optionName == "picturePath"){
    00280             picturePath_ = optionData;
    00281             if(!picturePath_.endsWith("/")){ picturePath_ += "/"; }
    00282         }else if(optionName == "meshOptimize"){
    00283             meshOptimizeFlag_ = (optionData != "0");
    00284         }else if(optionName == "characterScale"){
    00285             if(!optionData.parseFloat(&characterScale_)){
    00286                 characterScale_ = 1.f;
    00287             }
    00288         }else if(optionName == "animation"){
    00289             exportAnimationFlag_ = (optionData != "0");
    00290         }else if(optionName == "deleteStaticChannnels"){
    00291             deleteStaticChannelsFlag_ = (optionData != "0");
    00292         }
    00293     }
    00294 }
    00295 //------------------------------------------------------------------------------
    00296 // 開始メッセージ出力
    00297 void LampTranslator::outputStartMessage(){
    00298     String startMessage;
    00299     if(textExportFlag_){ startMessage += "\nテキストエクスポート開始\n"; }
    00300     else{ startMessage += "\nバイナリエクスポート開始\n"; }
    00301     if(exportSceneFlag_){ startMessage += "　シーン出力　有効\n"; }
    00302     else{ startMessage += "　シーン出力　無効\n"; }
    00303     if(exportSceneFlag_){
    00304         startMessage += "　　ピクチャ出力パス　" + picturePath_ + "\n";
    00305         if(meshOptimizeFlag_){ startMessage += "　　メッシュ最適化　有効\n"; }
    00306         else{ startMessage += "　　メッシュ最適化　無効\n"; }
    00307         String characterScaleString;
    00308         characterScaleString.format(
    00309             "　　キャラクタバウンディングスケール　%.8f\n", characterScale_);
    00310         startMessage += characterScaleString;
    00311     }
    00312     if(exportAnimationFlag_){ startMessage += "　アニメーション出力　有効\n"; }
    00313     else{ startMessage += "　アニメーション出力　無効\n"; }
    00314     if(exportAnimationFlag_){
    00315         if(deleteStaticChannelsFlag_){
    00316             startMessage += "　　静的チャンネル削除　有効\n";
    00317         }else{
    00318             startMessage += "　　静的チャンネル削除　無効\n";
    00319         }
    00320     }
    00321     startMessage += "\n";
    00322     MayaMessageOut(startMessage);
    00323 }
    00324 //------------------------------------------------------------------------------
    00325 } // End of namespace Lamp
    00326 //------------------------------------------------------------------------------