123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../../idlib/precompiled.h"
- #pragma hdrstop
- #include "../Game_local.h"
- #include "../../MayaImport/maya_main.h"
- /***********************************************************************
- Maya conversion functions
- ***********************************************************************/
- static idStr Maya_Error;
- static exporterInterface_t Maya_ConvertModel = NULL;
- static exporterShutdown_t Maya_Shutdown = NULL;
- static int importDLL = 0;
- bool idModelExport::initialized = false;
- /*
- ====================
- idModelExport::idModelExport
- ====================
- */
- idModelExport::idModelExport() {
- Reset();
- }
- /*
- ====================
- idModelExport::Shutdown
- ====================
- */
- void idModelExport::Shutdown( void ) {
- if ( Maya_Shutdown ) {
- Maya_Shutdown();
- }
- if ( importDLL ) {
- sys->DLL_Unload( importDLL );
- }
- importDLL = 0;
- Maya_Shutdown = NULL;
- Maya_ConvertModel = NULL;
- Maya_Error.Clear();
- initialized = false;
- }
- /*
- =====================
- idModelExport::CheckMayaInstall
- Determines if Maya is installed on the user's machine
- =====================
- */
- bool idModelExport::CheckMayaInstall( void ) {
- #ifndef _WIN32
- return false;
- #elif 0
- HKEY hKey;
- long lres, lType;
- lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya\\4.5\\Setup\\InstallPath", &hKey );
- if ( lres != ERROR_SUCCESS ) {
- return false;
- }
- lres = RegQueryValueEx( hKey, "MAYA_INSTALL_LOCATION", NULL, (unsigned long*)&lType, (unsigned char*)NULL, (unsigned long*)NULL );
- RegCloseKey( hKey );
- if ( lres != ERROR_SUCCESS ) {
- return false;
- }
- return true;
- #else
- HKEY hKey;
- long lres;
- // only check the non-version specific key so that we only have to update the maya dll when new versions are released
- lres = RegOpenKey( HKEY_LOCAL_MACHINE, "SOFTWARE\\Alias|Wavefront\\Maya", &hKey );
- RegCloseKey( hKey );
- if ( lres != ERROR_SUCCESS ) {
- return false;
- }
- return true;
- #endif
- }
- /*
- =====================
- idModelExport::LoadMayaDll
- Checks to see if we can load the Maya export dll
- =====================
- */
- void idModelExport::LoadMayaDll( void ) {
- exporterDLLEntry_t dllEntry;
- char dllPath[ MAX_OSPATH ];
- fileSystem->FindDLL( "MayaImport", dllPath, false );
- if ( !dllPath[ 0 ] ) {
- return;
- }
- importDLL = sys->DLL_Load( dllPath );
- if ( !importDLL ) {
- return;
- }
- // look up the dll interface functions
- dllEntry = ( exporterDLLEntry_t )sys->DLL_GetProcAddress( importDLL, "dllEntry" );
- Maya_ConvertModel = ( exporterInterface_t )sys->DLL_GetProcAddress( importDLL, "Maya_ConvertModel" );
- Maya_Shutdown = ( exporterShutdown_t )sys->DLL_GetProcAddress( importDLL, "Maya_Shutdown" );
- if ( !Maya_ConvertModel || !dllEntry || !Maya_Shutdown ) {
- Maya_ConvertModel = NULL;
- Maya_Shutdown = NULL;
- sys->DLL_Unload( importDLL );
- importDLL = 0;
- gameLocal.Error( "Invalid interface on export DLL." );
- return;
- }
- // initialize the DLL
- if ( !dllEntry( MD5_VERSION, common, sys ) ) {
- // init failed
- Maya_ConvertModel = NULL;
- Maya_Shutdown = NULL;
- sys->DLL_Unload( importDLL );
- importDLL = 0;
- gameLocal.Error( "Export DLL init failed." );
- return;
- }
- }
- /*
- =====================
- idModelExport::ConvertMayaToMD5
- Checks if a Maya model should be converted to an MD5, and converts if if the time/date or
- version number has changed.
- =====================
- */
- bool idModelExport::ConvertMayaToMD5( void ) {
- ID_TIME_T sourceTime;
- ID_TIME_T destTime;
- int version;
- idToken cmdLine;
- idStr path;
- // check if our DLL got loaded
- if ( initialized && !Maya_ConvertModel ) {
- Maya_Error = "MayaImport dll not loaded.";
- return false;
- }
- // if idAnimManager::forceExport is set then we always reexport Maya models
- if ( idAnimManager::forceExport ) {
- force = true;
- }
- // get the source file's time
- if ( fileSystem->ReadFile( src, NULL, &sourceTime ) < 0 ) {
- // source file doesn't exist
- return true;
- }
- // get the destination file's time
- if ( !force && ( fileSystem->ReadFile( dest, NULL, &destTime ) >= 0 ) ) {
- idParser parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS );
- parser.LoadFile( dest );
- // read the file version
- if ( parser.CheckTokenString( MD5_VERSION_STRING ) ) {
- version = parser.ParseInt();
- // check the command line
- if ( parser.CheckTokenString( "commandline" ) ) {
- parser.ReadToken( &cmdLine );
- // check the file time, scale, and version
- if ( ( destTime >= sourceTime ) && ( version == MD5_VERSION ) && ( cmdLine == commandLine ) ) {
- // don't convert it
- return true;
- }
- }
- }
- }
- // if this is the first time we've been run, check if Maya is installed and load our DLL
- if ( !initialized ) {
- initialized = true;
- if ( !CheckMayaInstall() ) {
- Maya_Error = "Maya not installed in registry.";
- return false;
- }
- LoadMayaDll();
- // check if our DLL got loaded
- if ( !Maya_ConvertModel ) {
- Maya_Error = "Could not load MayaImport dll.";
- return false;
- }
- }
- // we need to make sure we have a full path, so convert the filename to an OS path
- // _D3XP :: we work out of the cdpath, at least until we get Alienbrain
- src = fileSystem->RelativePathToOSPath( src, "fs_cdpath" );
- dest = fileSystem->RelativePathToOSPath( dest, "fs_cdpath" );
- dest.ExtractFilePath( path );
- if ( path.Length() ) {
- fileSystem->CreateOSPath( path );
- }
- // get the os path in case it needs to create one
- path = fileSystem->RelativePathToOSPath( "", "fs_cdpath" /* _D3XP */ );
- common->SetRefreshOnPrint( true );
- Maya_Error = Maya_ConvertModel( path, commandLine );
- common->SetRefreshOnPrint( false );
- if ( Maya_Error != "Ok" ) {
- return false;
- }
-
- // conversion succeded
- return true;
- }
- /*
- ====================
- idModelExport::Reset
- ====================
- */
- void idModelExport::Reset( void ) {
- force = false;
- commandLine = "";
- src = "";
- dest = "";
- }
- /*
- ====================
- idModelExport::ExportModel
- ====================
- */
- bool idModelExport::ExportModel( const char *model ) {
- const char *game = cvarSystem->GetCVarString( "fs_game" );
- if ( strlen(game) == 0 ) {
- game = BASE_GAMEDIR;
- }
- Reset();
- src = model;
- dest = model;
- dest.SetFileExtension( MD5_MESH_EXT );
- sprintf( commandLine, "mesh %s -dest %s -game %s", src.c_str(), dest.c_str(), game );
- if ( !ConvertMayaToMD5() ) {
- gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
- return false;
- }
- return true;
- }
- /*
- ====================
- idModelExport::ExportAnim
- ====================
- */
- bool idModelExport::ExportAnim( const char *anim ) {
- const char *game = cvarSystem->GetCVarString( "fs_game" );
- if ( strlen(game) == 0 ) {
- game = BASE_GAMEDIR;
- }
- Reset();
- src = anim;
- dest = anim;
- dest.SetFileExtension( MD5_ANIM_EXT );
- sprintf( commandLine, "anim %s -dest %s -game %s", src.c_str(), dest.c_str(), game );
- if ( !ConvertMayaToMD5() ) {
- gameLocal.Printf( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
- return false;
- }
- return true;
- }
- /*
- ====================
- idModelExport::ParseOptions
- ====================
- */
- bool idModelExport::ParseOptions( idLexer &lex ) {
- idToken token;
- idStr destdir;
- idStr sourcedir;
- if ( !lex.ReadToken( &token ) ) {
- lex.Error( "Expected filename" );
- return false;
- }
- src = token;
- dest = token;
- while( lex.ReadToken( &token ) ) {
- if ( token == "-" ) {
- if ( !lex.ReadToken( &token ) ) {
- lex.Error( "Expecting option" );
- return false;
- }
- if ( token == "sourcedir" ) {
- if ( !lex.ReadToken( &token ) ) {
- lex.Error( "Missing pathname after -sourcedir" );
- return false;
- }
- sourcedir = token;
- } else if ( token == "destdir" ) {
- if ( !lex.ReadToken( &token ) ) {
- lex.Error( "Missing pathname after -destdir" );
- return false;
- }
- destdir = token;
- } else if ( token == "dest" ) {
- if ( !lex.ReadToken( &token ) ) {
- lex.Error( "Missing filename after -dest" );
- return false;
- }
- dest = token;
- } else {
- commandLine += va( " -%s", token.c_str() );
- }
- } else {
- commandLine += va( " %s", token.c_str() );
- }
- }
- if ( sourcedir.Length() ) {
- src.StripPath();
- sourcedir.BackSlashesToSlashes();
- sprintf( src, "%s/%s", sourcedir.c_str(), src.c_str() );
- }
- if ( destdir.Length() ) {
- dest.StripPath();
- destdir.BackSlashesToSlashes();
- sprintf( dest, "%s/%s", destdir.c_str(), dest.c_str() );
- }
- return true;
- }
- /*
- ====================
- idModelExport::ParseExportSection
- ====================
- */
- int idModelExport::ParseExportSection( idParser &parser ) {
- idToken command;
- idToken token;
- idStr defaultCommands;
- idLexer lex;
- idStr temp;
- idStr parms;
- int count;
- const char *game = cvarSystem->GetCVarString( "fs_game" );
- if ( strlen(game) == 0 ) {
- game = BASE_GAMEDIR;
- }
- // only export sections that match our export mask
- if ( g_exportMask.GetString()[ 0 ] ) {
- if ( parser.CheckTokenString( "{" ) ) {
- parser.SkipBracedSection( false );
- return 0;
- }
- parser.ReadToken( &token );
- if ( token.Icmp( g_exportMask.GetString() ) ) {
- parser.SkipBracedSection();
- return 0;
- }
- parser.ExpectTokenString( "{" );
- } else if ( !parser.CheckTokenString( "{" ) ) {
- // skip the export mask
- parser.ReadToken( &token );
- parser.ExpectTokenString( "{" );
- }
- count = 0;
- lex.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- while( 1 ) {
- if ( !parser.ReadToken( &command ) ) {
- parser.Error( "Unexpoected end-of-file" );
- break;
- }
- if ( command == "}" ) {
- break;
- }
- if ( command == "options" ) {
- parser.ParseRestOfLine( defaultCommands );
- } else if ( command == "addoptions" ) {
- parser.ParseRestOfLine( temp );
- defaultCommands += " ";
- defaultCommands += temp;
- } else if ( ( command == "mesh" ) || ( command == "anim" ) || ( command == "camera" ) ) {
- if ( !parser.ReadToken( &token ) ) {
- parser.Error( "Expected filename" );
- }
- temp = token;
- parser.ParseRestOfLine( parms );
- if ( defaultCommands.Length() ) {
- sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() );
- }
- if ( parms.Length() ) {
- sprintf( temp, "%s %s", temp.c_str(), parms.c_str() );
- }
- lex.LoadMemory( temp, temp.Length(), parser.GetFileName() );
- Reset();
- if ( ParseOptions( lex ) ) {
- const char *game = cvarSystem->GetCVarString( "fs_game" );
- if ( strlen(game) == 0 ) {
- game = BASE_GAMEDIR;
- }
- if ( command == "mesh" ) {
- dest.SetFileExtension( MD5_MESH_EXT );
- } else if ( command == "anim" ) {
- dest.SetFileExtension( MD5_ANIM_EXT );
- } else if ( command == "camera" ) {
- dest.SetFileExtension( MD5_CAMERA_EXT );
- } else {
- dest.SetFileExtension( command );
- }
- idStr back = commandLine;
- sprintf( commandLine, "%s %s -dest %s -game %s%s", command.c_str(), src.c_str(), dest.c_str(), game, commandLine.c_str() );
- if ( ConvertMayaToMD5() ) {
- count++;
- } else {
- parser.Warning( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() );
- }
- }
- lex.FreeSource();
- } else {
- parser.Error( "Unknown token: %s", command.c_str() );
- parser.SkipBracedSection( false );
- break;
- }
- }
- return count;
- }
- /*
- ================
- idModelExport::ExportDefFile
- ================
- */
- int idModelExport::ExportDefFile( const char *filename ) {
- idParser parser( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
- idToken token;
- int count;
- count = 0;
- if ( !parser.LoadFile( filename ) ) {
- gameLocal.Printf( "Could not load '%s'\n", filename );
- return 0;
- }
- while( parser.ReadToken( &token ) ) {
- if ( token == "export" ) {
- count += ParseExportSection( parser );
- } else {
- parser.ReadToken( &token );
- parser.SkipBracedSection();
- }
- }
- return count;
- }
- /*
- ================
- idModelExport::ExportModels
- ================
- */
- int idModelExport::ExportModels( const char *pathname, const char *extension ) {
- int count;
- count = 0;
- idFileList *files;
- int i;
- if ( !CheckMayaInstall() ) {
- // if Maya isn't installed, don't bother checking if we have anims to export
- return 0;
- }
- gameLocal.Printf( "--------- Exporting models --------\n" );
- if ( !g_exportMask.GetString()[ 0 ] ) {
- gameLocal.Printf( " Export mask: '%s'\n", g_exportMask.GetString() );
- }
- count = 0;
- files = fileSystem->ListFiles( pathname, extension );
- for( i = 0; i < files->GetNumFiles(); i++ ) {
- count += ExportDefFile( va( "%s/%s", pathname, files->GetFile( i ) ) );
- }
- fileSystem->FreeFileList( files );
- gameLocal.Printf( "...%d models exported.\n", count );
- gameLocal.Printf( "-----------------------------------\n" );
- return count;
- }
|