Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

771 lines
22 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ==========++;
  2. //
  3. //=============================================================================
  4. // Valve includes
  5. #include "appframework/appframework.h"
  6. #include "appframework/tier3app.h"
  7. #include "datamodel/dmelement.h"
  8. #include "datamodel/dmelementfactoryhelper.h"
  9. #include "datamodel/idatamodel.h"
  10. #include "fbxsystem/ifbxsystem.h"
  11. #include "fbxutils/dmfbxserializer.h"
  12. #include "filesystem.h"
  13. #include "icommandline.h"
  14. #include "mathlib/mathlib.h"
  15. #include "movieobjects/dmeaxissystem.h"
  16. #include "movieobjects/dmefaceset.h"
  17. #include "movieobjects/dmematerial.h"
  18. #include "movieobjects/dmemesh.h"
  19. #include "movieobjects/dmemodel.h"
  20. #include "movieobjects/dmobjserializer.h"
  21. #include "dmserializers/idmserializers.h"
  22. #include "istudiorender.h"
  23. #ifdef SOURCE2
  24. #include "resourcesystem/resourcehandletypes.h"
  25. #endif
  26. #include "tier1/tier1.h"
  27. #include "tier2/tier2.h"
  28. #include "tier2/tier2dm.h"
  29. #include "tier3/tier3.h"
  30. #include "tier2/p4helpers.h"
  31. #include "p4lib/ip4.h"
  32. // Last include
  33. #include "tier0/memdbgon.h"
  34. class CStudioDataCache : public CBaseAppSystem < IStudioDataCache >
  35. {
  36. public:
  37. bool VerifyHeaders( studiohdr_t *pStudioHdr );
  38. vertexFileHeader_t *CacheVertexData( studiohdr_t *pStudioHdr );
  39. };
  40. static CStudioDataCache g_StudioDataCache;
  41. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CStudioDataCache, IStudioDataCache, STUDIO_DATA_CACHE_INTERFACE_VERSION, g_StudioDataCache );
  42. /*
  43. =================
  44. VerifyHeaders
  45. Minimal presence and header validation, no data loads
  46. Return true if successful, false otherwise.
  47. =================
  48. */
  49. bool CStudioDataCache::VerifyHeaders( studiohdr_t *pStudioHdr )
  50. {
  51. // default valid
  52. return true;
  53. }
  54. /*
  55. =================
  56. CacheVertexData
  57. Cache model's specified dynamic data
  58. =================
  59. */
  60. vertexFileHeader_t *CStudioDataCache::CacheVertexData( studiohdr_t *pStudioHdr )
  61. {
  62. // minimal implementation - return persisted data
  63. return ( vertexFileHeader_t* )pStudioHdr->VertexBase();
  64. }
  65. //-----------------------------------------------------------------------------
  66. //
  67. // Search for a material by name by generating resource names and seeing if
  68. // the resource exists on disk in content and then game and then on user
  69. // specified material search paths
  70. //
  71. // If a material file cannot be found, the original name is copied and false
  72. // is returned
  73. //
  74. //-----------------------------------------------------------------------------
  75. template <size_t maxLenInChars> bool FindMaterialResource( OUT_Z_ARRAY char (&szMaterialResourceName)[maxLenInChars], const char *pszMaterialName, const CUtlVector< CUtlString > &materialSearchPathList )
  76. {
  77. #ifdef SOURCE2
  78. char szResourceName[MAX_PATH] = { 0 };
  79. char szResourceFullPath[MAX_PATH] = { 0 };
  80. char szMaterialPath[MAX_PATH] = { 0 };
  81. ResourcePathGenerationType_t pSearchPaths[] =
  82. {
  83. RESOURCE_PATH_CONTENT,
  84. RESOURCE_PATH_GAME
  85. };
  86. for ( int s = 0; s < ARRAYSIZE( pSearchPaths ); ++s )
  87. {
  88. // Check if current material is valid
  89. FixupResourceName( pszMaterialName, RESOURCE_TYPE_MATERIAL, szResourceName, ARRAYSIZE( szResourceName ) );
  90. if ( GenerateStandardFullPathForResourceName( szResourceName, pSearchPaths[s], szResourceFullPath, ARRAYSIZE( szResourceFullPath ) ) )
  91. {
  92. V_strcpy_safe( szMaterialResourceName, szResourceName );
  93. return true;
  94. }
  95. }
  96. // Loop through material search paths and try to find the material
  97. for ( int s = 0; s < ARRAYSIZE( pSearchPaths ); s++ )
  98. {
  99. for ( int i = 0; i < materialSearchPathList.Count(); ++i )
  100. {
  101. V_ComposeFileName( materialSearchPathList[i].Get(), pszMaterialName, szMaterialPath, ARRAYSIZE( szMaterialPath ) );
  102. FixupResourceName( szMaterialPath, RESOURCE_TYPE_MATERIAL, szResourceName, ARRAYSIZE( szResourceName ) );
  103. if ( GenerateStandardFullPathForResourceName( szResourceName, pSearchPaths[s], szResourceFullPath, ARRAYSIZE( szResourceFullPath ) ) )
  104. {
  105. V_strcpy_safe( szMaterialResourceName, szResourceName );
  106. return true;
  107. }
  108. }
  109. }
  110. V_strcpy_safe( szMaterialResourceName, pszMaterialName );
  111. #endif
  112. return false;
  113. }
  114. //-----------------------------------------------------------------------------
  115. //
  116. //-----------------------------------------------------------------------------
  117. static void RemapMaterials( const CUtlVector< CUtlString > &materialSearchPathList )
  118. {
  119. char szResourceName[MAX_PATH] = {};
  120. char szMaterialName[MAX_PATH] = {};
  121. // Loop through all nodes in the
  122. for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement(); hElement != DMELEMENT_HANDLE_INVALID; hElement = g_pDataModel->NextAllocatedElement( hElement ) )
  123. {
  124. CDmeMesh *pDmeMesh = CastElement< CDmeMesh >( g_pDataModel->GetElement( hElement ) );
  125. if ( !pDmeMesh )
  126. continue;
  127. for ( int i = 0; i < pDmeMesh->FaceSetCount(); ++i )
  128. {
  129. CDmeFaceSet *pDmeFaceSet = pDmeMesh->GetFaceSet( i );
  130. CDmeMaterial *pDmeMaterial = pDmeFaceSet->GetMaterial();
  131. // Check if current material is valid, and just set the standard name found anyway
  132. if ( FindMaterialResource( szResourceName, pDmeMaterial->GetMaterialName(), materialSearchPathList ) )
  133. {
  134. V_FileBase( szResourceName, szMaterialName, ARRAYSIZE( szMaterialName ) );
  135. pDmeMaterial->SetName( szMaterialName );
  136. pDmeMaterial->SetMaterial( szResourceName );
  137. continue;
  138. }
  139. {
  140. bool bFound = false;
  141. const char *szSuffixes[] = { "_color." };
  142. FbxString sTmpResourceName = pDmeMaterial->GetMaterialName();
  143. for ( int i = 0; i < ARRAYSIZE( szSuffixes ); ++i )
  144. {
  145. if ( sTmpResourceName.FindAndReplace( szSuffixes[i], "." ) )
  146. {
  147. if ( FindMaterialResource( szResourceName, sTmpResourceName.Buffer(), materialSearchPathList ) )
  148. {
  149. V_FileBase( szResourceName, szMaterialName, ARRAYSIZE( szMaterialName ) );
  150. pDmeMaterial->SetName( szMaterialName );
  151. pDmeMaterial->SetMaterial( szResourceName );
  152. bFound = 1;
  153. break;
  154. }
  155. }
  156. }
  157. if ( bFound )
  158. continue;
  159. }
  160. Warning( "Warning! Cannot find a material resource for material \"%s\" on mesh \"%s\"\n", pDmeMaterial->GetMaterialName(), pDmeMesh->GetName() );
  161. }
  162. }
  163. }
  164. //-----------------------------------------------------------------------------
  165. //
  166. //-----------------------------------------------------------------------------
  167. int DoIt( CDmElement *pDmRoot, const char *pszOutFilename, const CUtlVector< CUtlString > &materialSearchPathList )
  168. {
  169. RemapMaterials( materialSearchPathList );
  170. CP4AutoAddFile outfile( pszOutFilename );
  171. char szDmxFilename[MAX_PATH];
  172. V_strncpy( szDmxFilename, pszOutFilename, ARRAYSIZE( szDmxFilename ) );
  173. V_SetExtension( szDmxFilename, ".dmx", ARRAYSIZE( szDmxFilename ) );
  174. CP4AutoEditAddFile dmxFile( szDmxFilename );
  175. CDmeModel *pDmeModel = pDmRoot->GetValueElement< CDmeModel >( "model" );
  176. if ( !pDmeModel )
  177. {
  178. pDmeModel = pDmRoot->GetValueElement< CDmeModel >( "skeleton" );
  179. }
  180. Assert( pDmeModel );
  181. CDmeAxisSystem *pDmeAxisSystem = pDmeModel->GetValueElement< CDmeAxisSystem >( "axisSystem" );
  182. Assert( pDmeAxisSystem );
  183. const bool bReturn = g_pDataModel->SaveToFile( szDmxFilename, NULL, "keyvalues2", "model", pDmRoot );
  184. g_pDataModel->UnloadFile( pDmRoot->GetFileId() );
  185. return bReturn ? 0 : -1;
  186. }
  187. bool ProcessAxisSystem( CDmFbxSerializer &dmFbxSerializer );
  188. //-----------------------------------------------------------------------------
  189. // DEFINE_CONSOLE_APPLICATION in Source2
  190. //-----------------------------------------------------------------------------
  191. class CFbx2DmxApp : public CDefaultAppSystemGroup < CSteamAppSystemGroup >
  192. {
  193. typedef CDefaultAppSystemGroup< CSteamAppSystemGroup > BaseClass;
  194. public:
  195. CFbx2DmxApp()
  196. {
  197. m_pszOptForceMod = NULL;
  198. m_bOptUFC = false;
  199. m_nOptVerbosity = 0;
  200. m_bOptAnimation = false;
  201. m_bOptPrintSearchPaths = false;
  202. m_pszOptFilename = NULL;
  203. m_pszOptOutFilename = NULL;
  204. }
  205. virtual bool Create() OVERRIDE;
  206. virtual int Main() OVERRIDE;
  207. virtual bool PreInit() OVERRIDE
  208. {
  209. CreateInterfaceFn factory = GetFactory();
  210. ConnectTier1Libraries( &factory, 1 );
  211. ConnectTier2Libraries( &factory, 1 );
  212. if ( !g_pFullFileSystem )
  213. return false;
  214. if ( !g_pCVar )
  215. return false;
  216. ConVar_Register();
  217. return true;
  218. }
  219. virtual void PostShutdown() OVERRIDE
  220. {
  221. ConVar_Unregister();
  222. DisconnectTier2Libraries();
  223. DisconnectTier1Libraries();
  224. }
  225. protected:
  226. const char *m_pszOptFilename;
  227. int m_nOptVerbosity;
  228. bool m_bOptAnimation;
  229. bool m_bOptPrintSearchPaths;
  230. bool m_bOptUFC;
  231. const char *m_pszOptForceMod;
  232. CUtlVector< CUtlString > m_sOptMaterialSearchPaths;
  233. const char *m_pszOptOutFilename;
  234. protected:
  235. bool ParseArguments();
  236. };
  237. static bool CStudioMDLApp_SuggestGameInfoDirFn( CFSSteamSetupInfo const *pFsSteamSetupInfo, char *pchPathBuffer, int nBufferLength, bool *pbBubbleDirectories )
  238. {
  239. const char *pProcessFileName = NULL;
  240. int nParmCount = CommandLine()->ParmCount();
  241. if ( nParmCount > 1 )
  242. {
  243. pProcessFileName = CommandLine()->GetParm( nParmCount - 1 );
  244. }
  245. if ( pProcessFileName )
  246. {
  247. Q_MakeAbsolutePath( pchPathBuffer, nBufferLength, pProcessFileName );
  248. if ( pbBubbleDirectories )
  249. *pbBubbleDirectories = true;
  250. return true;
  251. }
  252. return false;
  253. }
  254. int main( int argc, char **argv )
  255. {
  256. SetSuggestGameInfoDirFn( CStudioMDLApp_SuggestGameInfoDirFn );
  257. CFbx2DmxApp s_ApplicationObject;
  258. CSteamApplication s_SteamApplicationObject( &s_ApplicationObject );
  259. return AppMain( argc, argv, &s_SteamApplicationObject );
  260. }
  261. //-----------------------------------------------------------------------------
  262. //
  263. //-----------------------------------------------------------------------------
  264. static void PrintUsage()
  265. {
  266. Msg( "\n" );
  267. Msg( "NAME\n" );
  268. Msg( " fbx2dmx - Converts an FBX file to a DMX file\n" );
  269. Msg( "\n" );
  270. Msg( "SYNOPSIS\n" );
  271. Msg( " fbx2dmx [ opts ... ] < filename.fbx >\n" );
  272. Msg( "\n" );
  273. Msg( " -h | -help . . . . . . . . . . . Prints this information\n" );
  274. Msg( " -nop4 . . . . . . . . . . . . . Turns off Perforce integration\n" );
  275. Msg( " -i | -input <$> . . . . . . . . Specifies the input filename\n" );
  276. Msg( " -o | -output <$> . . . . . . . Specifies the output filename\n" );
  277. Msg( " -ufc . . . . . . . . . . . . . . _'s in delta names means they are\n"
  278. " corrective states\n" );
  279. Msg( " -v . . . . . . . . . . . . . . . Each -v increases verbosity\n" );
  280. Msg( " -a . . . . . . . . . . . . . . . Convert animation, normally models are\n"
  281. " converted\n" );
  282. Msg( " -msp | -materialSearchPath <$> . Specify a material search path to remap\n"
  283. " materials to\n" );
  284. Msg( " -psp . . . . . . . . . . . . . . Print the search paths that will be used\n" );
  285. Msg( " -up . . . . . . . . . . . . . . One of [ x, y, z, -x, -y, -z ], Def: y\n" );
  286. Msg( " -fp | -forwardParity . . . . . One of [ even, odd, -even, -odd ], Def: x\n" );
  287. Msg( "\n" );
  288. Msg( "DESCRIPTION\n" );
  289. Msg( " Converts an FBX file to a DMX file. File is saved in same location as FBX\n"
  290. " file with extension changed\n" );
  291. Msg( "\n" );
  292. Msg( " If -i isn't specified then any argument that isn't associated with a command\n"
  293. " line switch is considered to be the input.\n" );
  294. Msg( "\n" );
  295. Msg( " If -o isn't specified then the extension of the input is changed to be .fbx\n"
  296. " and used as the output filename.\n" );
  297. Msg( "\n" );
  298. Msg( "AXIS SYSTEM\n" );
  299. Msg( " To specify the axis system the resulting DMX file will contain, the\n"
  300. " combination of -up & -parity is used. -up specifies which axis is to be\n"
  301. " the up axis, prefix the x, y, or z with a minus to specify the negative\n"
  302. " axis. -forwardParity specifies the forward axis. Of the remaining two\n"
  303. " axes left after up is specified, parity specifies which of them,\n"
  304. " alphabetically, will be the forward, even being the first odd being the\n"
  305. " second. i.e. If Y is up, then even means X, odd means Z. Again prefix\n"
  306. " with a minus for the negative axis.\n"
  307. "\n"
  308. " e.g. To specify Maya Y Up which is +Y up and +Z forward: -up y -fp odd\n"
  309. " To specify Valve Engine which is +Z up and +X forward: -up z -fp even\n" );
  310. Msg( "\n" );
  311. Msg( "\n" );
  312. }
  313. //-----------------------------------------------------------------------------
  314. //
  315. //-----------------------------------------------------------------------------
  316. bool ProcessAxisSystem( CDmFbxSerializer &dmFbxSerializer )
  317. {
  318. // Defaults
  319. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Y;
  320. dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_ODD;
  321. const int nParmCount = CommandLine()->ParmCount();
  322. const int nUpIndex = CommandLine()->FindParm( "-up" );
  323. if ( nUpIndex > 0 )
  324. {
  325. if ( nUpIndex < ( nParmCount - 1 ) ) // Ensure there's a parameter value after -up
  326. {
  327. const char *pszUp = CommandLine()->GetParm( nUpIndex + 1 );
  328. if ( pszUp )
  329. {
  330. if ( StringHasPrefix( pszUp, "x" ) )
  331. {
  332. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_X;
  333. }
  334. else if ( StringHasPrefix( pszUp, "y" ) )
  335. {
  336. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Y;
  337. }
  338. else if ( StringHasPrefix( pszUp, "z" ) )
  339. {
  340. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Z;
  341. }
  342. else if ( StringHasPrefix( pszUp, "-x" ) )
  343. {
  344. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NX;
  345. }
  346. else if ( StringHasPrefix( pszUp, "-y" ) )
  347. {
  348. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NY;
  349. }
  350. else if ( StringHasPrefix( pszUp, "-z" ) )
  351. {
  352. dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NZ;
  353. }
  354. else
  355. {
  356. Warning( "Error! Invalid -up value specified, must be one of -up [ x, y, z, -x, -y, -z ]: \"%s\"\n", pszUp );
  357. return false;
  358. }
  359. }
  360. else
  361. {
  362. Warning( "Error! No parameter specified after -up, must be one of -up [ x, y, z, -x, -y, -z ]\n" );
  363. return false;
  364. }
  365. }
  366. else
  367. {
  368. Warning( "Error! No parameter specified after -up, must be one of -up [ x, y, z, -x, -y, -z ]\n" );
  369. return false;
  370. }
  371. }
  372. int nFpIndex = 0;
  373. const char *szFp[] = { "-fp", "-forwardParity", "-forwardParity" };
  374. for ( int i = 0; i < ARRAYSIZE( szFp ); ++i )
  375. {
  376. const int nTmpFpIndex = CommandLine()->FindParm( szFp[i] );
  377. if ( nTmpFpIndex > 0 )
  378. {
  379. if ( nTmpFpIndex < nParmCount - 1 )
  380. {
  381. nFpIndex = nTmpFpIndex;
  382. break;
  383. }
  384. else
  385. {
  386. Warning( "Error! No parameter specified after %s, must be one of %s [ even, odd, -even, -odd ]\n", CommandLine()->GetParm( nTmpFpIndex ), CommandLine()->GetParm( nTmpFpIndex ) );
  387. return false;
  388. }
  389. }
  390. }
  391. if ( nFpIndex > 0 )
  392. {
  393. const char *pszFp = CommandLine()->GetParm( nFpIndex + 1 );
  394. if ( pszFp )
  395. {
  396. if ( StringHasPrefix( pszFp, "e" ) )
  397. {
  398. dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_EVEN;
  399. }
  400. else if ( StringHasPrefix( pszFp, "o" ) )
  401. {
  402. dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_ODD;
  403. }
  404. else if ( StringHasPrefix( pszFp, "-e" ) )
  405. {
  406. dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_NEVEN;
  407. }
  408. else if ( StringHasPrefix( pszFp, "-o" ) )
  409. {
  410. dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_NODD;
  411. }
  412. else
  413. {
  414. Warning( "Error! Invalid -forwardParity value specified, must be one of [ even, odd, -even, -odd ]: \"%s\"\n", pszFp );
  415. return false;
  416. }
  417. }
  418. else
  419. {
  420. Warning( "Error! No parameter specified after %s, must be one of %s [ even, odd, -even, -odd ]\n", CommandLine()->GetParm( nFpIndex ), CommandLine()->GetParm( nFpIndex ) );
  421. return false;
  422. }
  423. }
  424. return true;
  425. }
  426. bool CFbx2DmxApp::Create()
  427. {
  428. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
  429. if ( !ParseArguments() )
  430. {
  431. return false;
  432. }
  433. AppSystemInfo_t appSystems[] =
  434. {
  435. { "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
  436. { "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
  437. { "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
  438. { "mdllib.dll", MDLLIB_INTERFACE_VERSION },
  439. { "filesystem_stdio.dll", FILESYSTEM_INTERFACE_VERSION },
  440. { "p4lib.dll", P4_INTERFACE_VERSION },
  441. { "", "" } // Required to terminate the list
  442. };
  443. AddSystem( g_pDataModel, VDATAMODEL_INTERFACE_VERSION );
  444. AddSystem( g_pDmElementFramework, VDMELEMENTFRAMEWORK_VERSION );
  445. AddSystem( g_pDmSerializers, DMSERIALIZERS_INTERFACE_VERSION );
  446. // Add in the locally-defined studio data cache
  447. AppModule_t studioDataCacheModule = LoadModule( Sys_GetFactoryThis() );
  448. AddSystem( studioDataCacheModule, STUDIO_DATA_CACHE_INTERFACE_VERSION );
  449. // Add the P4 module separately so that if it is absent (say in the SDK) then the other system will initialize properly
  450. if ( !CommandLine()->FindParm( "-nop4" ) )
  451. {
  452. AppModule_t p4Module = LoadModule( "p4lib.dll" );
  453. AddSystem( p4Module, P4_INTERFACE_VERSION );
  454. }
  455. AddSystem( g_pFbx, FBX_INTERFACE_VERSION );
  456. bool bOk = AddSystems( appSystems );
  457. if ( !bOk )
  458. return false;
  459. IMaterialSystem *pMaterialSystem = ( IMaterialSystem* )FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
  460. if ( !pMaterialSystem )
  461. return false;
  462. pMaterialSystem->SetShaderAPI( "shaderapiempty.dll" );
  463. return true;
  464. }
  465. int CFbx2DmxApp::Main()
  466. {
  467. char szOptFilename[ MAX_PATH ];
  468. // Globally disable DMX undo
  469. g_pDataModel->SetUndoEnabled( false );
  470. // This bit of hackery allows us to access files on the harddrive
  471. if ( m_bOptPrintSearchPaths )
  472. {
  473. g_pFullFileSystem->PrintSearchPaths();
  474. }
  475. //p4->SetVerbose( false );
  476. p4->SetOpenFileChangeList( "fbx2dmx" );
  477. int nRetVal = -1;
  478. char szExt[ MAX_PATH ] = { };
  479. V_ExtractFileExtension( szOptFilename, szExt, ARRAYSIZE( szExt ) );
  480. CDisableUndoScopeGuard noUndo;
  481. CDmElement *pDmRoot = NULL;
  482. if ( !V_stricmp( szExt, "obj" ) )
  483. {
  484. CDmObjSerializer dmObjSerializer;
  485. pDmRoot = dmObjSerializer.ReadOBJ( szOptFilename );
  486. if ( !pDmRoot )
  487. {
  488. Warning( "Couldn't load OBJ file: %s\n", szOptFilename );
  489. }
  490. }
  491. else
  492. {
  493. CDmFbxSerializer dmFbxSerializer;
  494. dmFbxSerializer.m_bOptUnderscoreForCorrectors = m_bOptUFC;
  495. dmFbxSerializer.m_nOptVerbosity = m_nOptVerbosity;
  496. dmFbxSerializer.m_bAnimation = m_bOptAnimation;
  497. dmFbxSerializer.m_sOptMaterialSearchPathList = m_sOptMaterialSearchPaths;
  498. if ( ProcessAxisSystem( dmFbxSerializer ) )
  499. {
  500. pDmRoot = dmFbxSerializer.ReadFBX( m_pszOptFilename );
  501. if ( !pDmRoot )
  502. {
  503. Warning( "Couldn't load FBX file: %s\n", szOptFilename );
  504. }
  505. }
  506. }
  507. if ( pDmRoot )
  508. {
  509. if ( m_pszOptOutFilename )
  510. {
  511. nRetVal = DoIt( pDmRoot, m_pszOptOutFilename, m_sOptMaterialSearchPaths );
  512. }
  513. else
  514. {
  515. nRetVal = DoIt( pDmRoot, m_pszOptFilename, m_sOptMaterialSearchPaths );
  516. }
  517. }
  518. return nRetVal;
  519. }
  520. bool CFbx2DmxApp::ParseArguments()
  521. {
  522. if ( CommandLine()->CheckParm( "-h" ) || CommandLine()->CheckParm( "--help" ) || CommandLine()->CheckParm( "-help" ) )
  523. {
  524. PrintUsage();
  525. return false;
  526. }
  527. for ( int i = 1; i < CommandLine()->ParmCount(); ++i )
  528. {
  529. const char *pszParam = CommandLine()->GetParm( i );
  530. if ( !V_stricmp( pszParam, "-game" ) )
  531. {
  532. m_pszOptForceMod = CommandLine()->GetParm( ++i );
  533. continue;
  534. }
  535. if ( !V_stricmp( pszParam, "-nop4" ) )
  536. {
  537. continue;
  538. }
  539. if ( !V_stricmp( pszParam, "-ufc" ) )
  540. {
  541. m_bOptUFC = true;
  542. continue;
  543. }
  544. if ( !V_stricmp( pszParam, "-v" ) )
  545. {
  546. ++m_nOptVerbosity;
  547. continue;
  548. }
  549. if ( !V_stricmp( pszParam, "-a" ) )
  550. {
  551. m_bOptAnimation = true;
  552. continue;
  553. }
  554. if ( !V_stricmp( pszParam, "-msp" ) || !V_stricmp( pszParam, "-materialSearchPath" ) )
  555. {
  556. m_sOptMaterialSearchPaths.AddToTail( CommandLine()->GetParm( ++i ) );
  557. continue;
  558. }
  559. if ( !V_stricmp( pszParam, "-psp" ) )
  560. {
  561. m_bOptPrintSearchPaths = true;
  562. continue;
  563. }
  564. if ( !V_stricmp( pszParam, "-up" ) )
  565. {
  566. ++i;
  567. continue;
  568. }
  569. if ( !V_stricmp( pszParam, "-fp" ) || !V_stricmp( pszParam, "-forwardParity" ) || !V_stricmp( pszParam, "-forwardparity" ) )
  570. {
  571. ++i;
  572. continue;
  573. }
  574. if ( !V_stricmp( pszParam, "-i" ) || !V_stricmp( pszParam, "-input" ) )
  575. {
  576. ++i;
  577. pszParam = CommandLine()->GetParm( i );
  578. if ( m_pszOptFilename )
  579. {
  580. Warning( "Warning! Filename was already specified as: \"%s\", using -i \"%s\"\n", m_pszOptFilename, pszParam );
  581. }
  582. m_pszOptFilename = pszParam;
  583. continue;
  584. }
  585. if ( !V_stricmp( pszParam, "-o" ) || !V_stricmp( pszParam, "-output" ) )
  586. {
  587. ++i;
  588. pszParam = CommandLine()->GetParm( i );
  589. if ( m_pszOptOutFilename )
  590. {
  591. Warning( "Warning! Output filename was already specified as: \"%s\", using -o \"%s\"\n", m_pszOptOutFilename, pszParam );
  592. }
  593. m_pszOptOutFilename = pszParam;
  594. continue;
  595. }
  596. if ( StringHasPrefix( pszParam, "-" ) )
  597. {
  598. Warning( "Warning! Unknown command line switch \"%s\"\n", pszParam );
  599. continue;
  600. }
  601. if ( m_pszOptFilename )
  602. {
  603. Warning( "Warning! Filename already specified: \"%s\", ignoring \"%s\"\n", m_pszOptFilename, pszParam );
  604. }
  605. else
  606. {
  607. m_pszOptFilename = pszParam;
  608. }
  609. }
  610. if ( !m_pszOptFilename )
  611. {
  612. Warning( "Error! Cannot find any file to execute from passed command line arguments\n\n" );
  613. PrintUsage();
  614. return false;
  615. }
  616. return true;
  617. }
  618. //-----------------------------------------------------------------------------
  619. // Purpose: bind studiohdr_t support functions to fbx2dmx utility
  620. // FIXME: This should be moved into studio.cpp?
  621. //-----------------------------------------------------------------------------
  622. const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *pModelName ) const
  623. {
  624. MDLHandle_t handle = g_pMDLCache->FindMDL( pModelName );
  625. *cache = ( void* )( uintp )handle;
  626. return g_pMDLCache->GetStudioHdr( handle );
  627. }
  628. virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const
  629. {
  630. if ( numincludemodels == 0 )
  631. return NULL;
  632. return g_pMDLCache->GetVirtualModelFast( this, VoidPtrToMDLHandle( VirtualModel() ) );
  633. }
  634. byte *studiohdr_t::GetAnimBlock( int i, bool preloadIfMissing ) const
  635. {
  636. return g_pMDLCache->GetAnimBlock( VoidPtrToMDLHandle( VirtualModel() ), i, preloadIfMissing );
  637. }
  638. bool studiohdr_t::hasAnimBlockBeenPreloaded( int i ) const
  639. {
  640. return g_pMDLCache->HasAnimBlockBeenPreloaded( VoidPtrToMDLHandle( VirtualModel() ), i );
  641. }
  642. int studiohdr_t::GetAutoplayList( unsigned short **pOut ) const
  643. {
  644. return g_pMDLCache->GetAutoplayList( VoidPtrToMDLHandle( VirtualModel() ), pOut );
  645. }
  646. const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const
  647. {
  648. return g_pMDLCache->GetStudioHdr( VoidPtrToMDLHandle( cache ) );
  649. }