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
771 lines
22 KiB
//============ Copyright (c) Valve Corporation, All rights reserved. ==========++;
|
|
//
|
|
//=============================================================================
|
|
|
|
|
|
// Valve includes
|
|
#include "appframework/appframework.h"
|
|
#include "appframework/tier3app.h"
|
|
#include "datamodel/dmelement.h"
|
|
#include "datamodel/dmelementfactoryhelper.h"
|
|
#include "datamodel/idatamodel.h"
|
|
#include "fbxsystem/ifbxsystem.h"
|
|
#include "fbxutils/dmfbxserializer.h"
|
|
#include "filesystem.h"
|
|
#include "icommandline.h"
|
|
#include "mathlib/mathlib.h"
|
|
#include "movieobjects/dmeaxissystem.h"
|
|
#include "movieobjects/dmefaceset.h"
|
|
#include "movieobjects/dmematerial.h"
|
|
#include "movieobjects/dmemesh.h"
|
|
#include "movieobjects/dmemodel.h"
|
|
#include "movieobjects/dmobjserializer.h"
|
|
#include "dmserializers/idmserializers.h"
|
|
#include "istudiorender.h"
|
|
#ifdef SOURCE2
|
|
#include "resourcesystem/resourcehandletypes.h"
|
|
#endif
|
|
#include "tier1/tier1.h"
|
|
#include "tier2/tier2.h"
|
|
#include "tier2/tier2dm.h"
|
|
#include "tier3/tier3.h"
|
|
#include "tier2/p4helpers.h"
|
|
#include "p4lib/ip4.h"
|
|
|
|
|
|
// Last include
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
|
|
class CStudioDataCache : public CBaseAppSystem < IStudioDataCache >
|
|
{
|
|
public:
|
|
bool VerifyHeaders( studiohdr_t *pStudioHdr );
|
|
vertexFileHeader_t *CacheVertexData( studiohdr_t *pStudioHdr );
|
|
};
|
|
|
|
static CStudioDataCache g_StudioDataCache;
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CStudioDataCache, IStudioDataCache, STUDIO_DATA_CACHE_INTERFACE_VERSION, g_StudioDataCache );
|
|
|
|
|
|
/*
|
|
=================
|
|
VerifyHeaders
|
|
|
|
Minimal presence and header validation, no data loads
|
|
Return true if successful, false otherwise.
|
|
=================
|
|
*/
|
|
bool CStudioDataCache::VerifyHeaders( studiohdr_t *pStudioHdr )
|
|
{
|
|
// default valid
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
CacheVertexData
|
|
|
|
Cache model's specified dynamic data
|
|
=================
|
|
*/
|
|
vertexFileHeader_t *CStudioDataCache::CacheVertexData( studiohdr_t *pStudioHdr )
|
|
{
|
|
// minimal implementation - return persisted data
|
|
return ( vertexFileHeader_t* )pStudioHdr->VertexBase();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Search for a material by name by generating resource names and seeing if
|
|
// the resource exists on disk in content and then game and then on user
|
|
// specified material search paths
|
|
//
|
|
// If a material file cannot be found, the original name is copied and false
|
|
// is returned
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
template <size_t maxLenInChars> bool FindMaterialResource( OUT_Z_ARRAY char (&szMaterialResourceName)[maxLenInChars], const char *pszMaterialName, const CUtlVector< CUtlString > &materialSearchPathList )
|
|
{
|
|
#ifdef SOURCE2
|
|
char szResourceName[MAX_PATH] = { 0 };
|
|
char szResourceFullPath[MAX_PATH] = { 0 };
|
|
char szMaterialPath[MAX_PATH] = { 0 };
|
|
|
|
ResourcePathGenerationType_t pSearchPaths[] =
|
|
{
|
|
RESOURCE_PATH_CONTENT,
|
|
RESOURCE_PATH_GAME
|
|
};
|
|
|
|
for ( int s = 0; s < ARRAYSIZE( pSearchPaths ); ++s )
|
|
{
|
|
// Check if current material is valid
|
|
FixupResourceName( pszMaterialName, RESOURCE_TYPE_MATERIAL, szResourceName, ARRAYSIZE( szResourceName ) );
|
|
if ( GenerateStandardFullPathForResourceName( szResourceName, pSearchPaths[s], szResourceFullPath, ARRAYSIZE( szResourceFullPath ) ) )
|
|
{
|
|
V_strcpy_safe( szMaterialResourceName, szResourceName );
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Loop through material search paths and try to find the material
|
|
for ( int s = 0; s < ARRAYSIZE( pSearchPaths ); s++ )
|
|
{
|
|
for ( int i = 0; i < materialSearchPathList.Count(); ++i )
|
|
{
|
|
V_ComposeFileName( materialSearchPathList[i].Get(), pszMaterialName, szMaterialPath, ARRAYSIZE( szMaterialPath ) );
|
|
FixupResourceName( szMaterialPath, RESOURCE_TYPE_MATERIAL, szResourceName, ARRAYSIZE( szResourceName ) );
|
|
|
|
if ( GenerateStandardFullPathForResourceName( szResourceName, pSearchPaths[s], szResourceFullPath, ARRAYSIZE( szResourceFullPath ) ) )
|
|
{
|
|
V_strcpy_safe( szMaterialResourceName, szResourceName );
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
V_strcpy_safe( szMaterialResourceName, pszMaterialName );
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
static void RemapMaterials( const CUtlVector< CUtlString > &materialSearchPathList )
|
|
{
|
|
char szResourceName[MAX_PATH] = {};
|
|
char szMaterialName[MAX_PATH] = {};
|
|
|
|
// Loop through all nodes in the
|
|
|
|
for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement(); hElement != DMELEMENT_HANDLE_INVALID; hElement = g_pDataModel->NextAllocatedElement( hElement ) )
|
|
{
|
|
CDmeMesh *pDmeMesh = CastElement< CDmeMesh >( g_pDataModel->GetElement( hElement ) );
|
|
if ( !pDmeMesh )
|
|
continue;
|
|
|
|
for ( int i = 0; i < pDmeMesh->FaceSetCount(); ++i )
|
|
{
|
|
CDmeFaceSet *pDmeFaceSet = pDmeMesh->GetFaceSet( i );
|
|
CDmeMaterial *pDmeMaterial = pDmeFaceSet->GetMaterial();
|
|
|
|
// Check if current material is valid, and just set the standard name found anyway
|
|
if ( FindMaterialResource( szResourceName, pDmeMaterial->GetMaterialName(), materialSearchPathList ) )
|
|
{
|
|
V_FileBase( szResourceName, szMaterialName, ARRAYSIZE( szMaterialName ) );
|
|
pDmeMaterial->SetName( szMaterialName );
|
|
pDmeMaterial->SetMaterial( szResourceName );
|
|
continue;
|
|
}
|
|
|
|
{
|
|
bool bFound = false;
|
|
|
|
const char *szSuffixes[] = { "_color." };
|
|
|
|
FbxString sTmpResourceName = pDmeMaterial->GetMaterialName();
|
|
|
|
for ( int i = 0; i < ARRAYSIZE( szSuffixes ); ++i )
|
|
{
|
|
if ( sTmpResourceName.FindAndReplace( szSuffixes[i], "." ) )
|
|
{
|
|
if ( FindMaterialResource( szResourceName, sTmpResourceName.Buffer(), materialSearchPathList ) )
|
|
{
|
|
V_FileBase( szResourceName, szMaterialName, ARRAYSIZE( szMaterialName ) );
|
|
pDmeMaterial->SetName( szMaterialName );
|
|
pDmeMaterial->SetMaterial( szResourceName );
|
|
bFound = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( bFound )
|
|
continue;
|
|
}
|
|
|
|
Warning( "Warning! Cannot find a material resource for material \"%s\" on mesh \"%s\"\n", pDmeMaterial->GetMaterialName(), pDmeMesh->GetName() );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
int DoIt( CDmElement *pDmRoot, const char *pszOutFilename, const CUtlVector< CUtlString > &materialSearchPathList )
|
|
{
|
|
RemapMaterials( materialSearchPathList );
|
|
|
|
CP4AutoAddFile outfile( pszOutFilename );
|
|
|
|
char szDmxFilename[MAX_PATH];
|
|
V_strncpy( szDmxFilename, pszOutFilename, ARRAYSIZE( szDmxFilename ) );
|
|
V_SetExtension( szDmxFilename, ".dmx", ARRAYSIZE( szDmxFilename ) );
|
|
|
|
CP4AutoEditAddFile dmxFile( szDmxFilename );
|
|
|
|
CDmeModel *pDmeModel = pDmRoot->GetValueElement< CDmeModel >( "model" );
|
|
if ( !pDmeModel )
|
|
{
|
|
pDmeModel = pDmRoot->GetValueElement< CDmeModel >( "skeleton" );
|
|
}
|
|
Assert( pDmeModel );
|
|
CDmeAxisSystem *pDmeAxisSystem = pDmeModel->GetValueElement< CDmeAxisSystem >( "axisSystem" );
|
|
Assert( pDmeAxisSystem );
|
|
|
|
const bool bReturn = g_pDataModel->SaveToFile( szDmxFilename, NULL, "keyvalues2", "model", pDmRoot );
|
|
|
|
g_pDataModel->UnloadFile( pDmRoot->GetFileId() );
|
|
|
|
return bReturn ? 0 : -1;
|
|
}
|
|
|
|
|
|
bool ProcessAxisSystem( CDmFbxSerializer &dmFbxSerializer );
|
|
//-----------------------------------------------------------------------------
|
|
// DEFINE_CONSOLE_APPLICATION in Source2
|
|
//-----------------------------------------------------------------------------
|
|
class CFbx2DmxApp : public CDefaultAppSystemGroup < CSteamAppSystemGroup >
|
|
{
|
|
typedef CDefaultAppSystemGroup< CSteamAppSystemGroup > BaseClass;
|
|
public:
|
|
|
|
CFbx2DmxApp()
|
|
{
|
|
m_pszOptForceMod = NULL;
|
|
m_bOptUFC = false;
|
|
m_nOptVerbosity = 0;
|
|
m_bOptAnimation = false;
|
|
m_bOptPrintSearchPaths = false;
|
|
m_pszOptFilename = NULL;
|
|
m_pszOptOutFilename = NULL;
|
|
}
|
|
|
|
virtual bool Create() OVERRIDE;
|
|
virtual int Main() OVERRIDE;
|
|
|
|
virtual bool PreInit() OVERRIDE
|
|
{
|
|
CreateInterfaceFn factory = GetFactory();
|
|
ConnectTier1Libraries( &factory, 1 );
|
|
ConnectTier2Libraries( &factory, 1 );
|
|
|
|
if ( !g_pFullFileSystem )
|
|
return false;
|
|
|
|
if ( !g_pCVar )
|
|
return false;
|
|
|
|
ConVar_Register();
|
|
|
|
return true;
|
|
}
|
|
|
|
virtual void PostShutdown() OVERRIDE
|
|
{
|
|
ConVar_Unregister();
|
|
DisconnectTier2Libraries();
|
|
DisconnectTier1Libraries();
|
|
}
|
|
|
|
protected:
|
|
const char *m_pszOptFilename;
|
|
int m_nOptVerbosity;
|
|
bool m_bOptAnimation;
|
|
bool m_bOptPrintSearchPaths;
|
|
bool m_bOptUFC;
|
|
const char *m_pszOptForceMod;
|
|
CUtlVector< CUtlString > m_sOptMaterialSearchPaths;
|
|
const char *m_pszOptOutFilename;
|
|
protected:
|
|
bool ParseArguments();
|
|
};
|
|
|
|
static bool CStudioMDLApp_SuggestGameInfoDirFn( CFSSteamSetupInfo const *pFsSteamSetupInfo, char *pchPathBuffer, int nBufferLength, bool *pbBubbleDirectories )
|
|
{
|
|
const char *pProcessFileName = NULL;
|
|
int nParmCount = CommandLine()->ParmCount();
|
|
if ( nParmCount > 1 )
|
|
{
|
|
pProcessFileName = CommandLine()->GetParm( nParmCount - 1 );
|
|
}
|
|
|
|
if ( pProcessFileName )
|
|
{
|
|
Q_MakeAbsolutePath( pchPathBuffer, nBufferLength, pProcessFileName );
|
|
|
|
if ( pbBubbleDirectories )
|
|
*pbBubbleDirectories = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int main( int argc, char **argv )
|
|
{
|
|
SetSuggestGameInfoDirFn( CStudioMDLApp_SuggestGameInfoDirFn );
|
|
CFbx2DmxApp s_ApplicationObject;
|
|
CSteamApplication s_SteamApplicationObject( &s_ApplicationObject );
|
|
return AppMain( argc, argv, &s_SteamApplicationObject );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
static void PrintUsage()
|
|
{
|
|
Msg( "\n" );
|
|
Msg( "NAME\n" );
|
|
Msg( " fbx2dmx - Converts an FBX file to a DMX file\n" );
|
|
Msg( "\n" );
|
|
Msg( "SYNOPSIS\n" );
|
|
Msg( " fbx2dmx [ opts ... ] < filename.fbx >\n" );
|
|
Msg( "\n" );
|
|
Msg( " -h | -help . . . . . . . . . . . Prints this information\n" );
|
|
Msg( " -nop4 . . . . . . . . . . . . . Turns off Perforce integration\n" );
|
|
Msg( " -i | -input <$> . . . . . . . . Specifies the input filename\n" );
|
|
Msg( " -o | -output <$> . . . . . . . Specifies the output filename\n" );
|
|
Msg( " -ufc . . . . . . . . . . . . . . _'s in delta names means they are\n"
|
|
" corrective states\n" );
|
|
Msg( " -v . . . . . . . . . . . . . . . Each -v increases verbosity\n" );
|
|
Msg( " -a . . . . . . . . . . . . . . . Convert animation, normally models are\n"
|
|
" converted\n" );
|
|
Msg( " -msp | -materialSearchPath <$> . Specify a material search path to remap\n"
|
|
" materials to\n" );
|
|
Msg( " -psp . . . . . . . . . . . . . . Print the search paths that will be used\n" );
|
|
Msg( " -up . . . . . . . . . . . . . . One of [ x, y, z, -x, -y, -z ], Def: y\n" );
|
|
Msg( " -fp | -forwardParity . . . . . One of [ even, odd, -even, -odd ], Def: x\n" );
|
|
Msg( "\n" );
|
|
Msg( "DESCRIPTION\n" );
|
|
Msg( " Converts an FBX file to a DMX file. File is saved in same location as FBX\n"
|
|
" file with extension changed\n" );
|
|
Msg( "\n" );
|
|
Msg( " If -i isn't specified then any argument that isn't associated with a command\n"
|
|
" line switch is considered to be the input.\n" );
|
|
Msg( "\n" );
|
|
Msg( " If -o isn't specified then the extension of the input is changed to be .fbx\n"
|
|
" and used as the output filename.\n" );
|
|
Msg( "\n" );
|
|
Msg( "AXIS SYSTEM\n" );
|
|
Msg( " To specify the axis system the resulting DMX file will contain, the\n"
|
|
" combination of -up & -parity is used. -up specifies which axis is to be\n"
|
|
" the up axis, prefix the x, y, or z with a minus to specify the negative\n"
|
|
" axis. -forwardParity specifies the forward axis. Of the remaining two\n"
|
|
" axes left after up is specified, parity specifies which of them,\n"
|
|
" alphabetically, will be the forward, even being the first odd being the\n"
|
|
" second. i.e. If Y is up, then even means X, odd means Z. Again prefix\n"
|
|
" with a minus for the negative axis.\n"
|
|
"\n"
|
|
" e.g. To specify Maya Y Up which is +Y up and +Z forward: -up y -fp odd\n"
|
|
" To specify Valve Engine which is +Z up and +X forward: -up z -fp even\n" );
|
|
Msg( "\n" );
|
|
Msg( "\n" );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
bool ProcessAxisSystem( CDmFbxSerializer &dmFbxSerializer )
|
|
{
|
|
// Defaults
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Y;
|
|
dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_ODD;
|
|
|
|
const int nParmCount = CommandLine()->ParmCount();
|
|
const int nUpIndex = CommandLine()->FindParm( "-up" );
|
|
|
|
if ( nUpIndex > 0 )
|
|
{
|
|
if ( nUpIndex < ( nParmCount - 1 ) ) // Ensure there's a parameter value after -up
|
|
{
|
|
const char *pszUp = CommandLine()->GetParm( nUpIndex + 1 );
|
|
|
|
if ( pszUp )
|
|
{
|
|
if ( StringHasPrefix( pszUp, "x" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_X;
|
|
}
|
|
else if ( StringHasPrefix( pszUp, "y" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Y;
|
|
}
|
|
else if ( StringHasPrefix( pszUp, "z" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_Z;
|
|
}
|
|
else if ( StringHasPrefix( pszUp, "-x" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NX;
|
|
}
|
|
else if ( StringHasPrefix( pszUp, "-y" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NY;
|
|
}
|
|
else if ( StringHasPrefix( pszUp, "-z" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptUpAxis = CDmeAxisSystem::AS_AXIS_NZ;
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! Invalid -up value specified, must be one of -up [ x, y, z, -x, -y, -z ]: \"%s\"\n", pszUp );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! No parameter specified after -up, must be one of -up [ x, y, z, -x, -y, -z ]\n" );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! No parameter specified after -up, must be one of -up [ x, y, z, -x, -y, -z ]\n" );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int nFpIndex = 0;
|
|
|
|
const char *szFp[] = { "-fp", "-forwardParity", "-forwardParity" };
|
|
for ( int i = 0; i < ARRAYSIZE( szFp ); ++i )
|
|
{
|
|
const int nTmpFpIndex = CommandLine()->FindParm( szFp[i] );
|
|
if ( nTmpFpIndex > 0 )
|
|
{
|
|
if ( nTmpFpIndex < nParmCount - 1 )
|
|
{
|
|
nFpIndex = nTmpFpIndex;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! No parameter specified after %s, must be one of %s [ even, odd, -even, -odd ]\n", CommandLine()->GetParm( nTmpFpIndex ), CommandLine()->GetParm( nTmpFpIndex ) );
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( nFpIndex > 0 )
|
|
{
|
|
const char *pszFp = CommandLine()->GetParm( nFpIndex + 1 );
|
|
|
|
if ( pszFp )
|
|
{
|
|
if ( StringHasPrefix( pszFp, "e" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_EVEN;
|
|
}
|
|
else if ( StringHasPrefix( pszFp, "o" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_ODD;
|
|
}
|
|
else if ( StringHasPrefix( pszFp, "-e" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_NEVEN;
|
|
}
|
|
else if ( StringHasPrefix( pszFp, "-o" ) )
|
|
{
|
|
dmFbxSerializer.m_eOptForwardParity = CDmeAxisSystem::AS_PARITY_NODD;
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! Invalid -forwardParity value specified, must be one of [ even, odd, -even, -odd ]: \"%s\"\n", pszFp );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Warning( "Error! No parameter specified after %s, must be one of %s [ even, odd, -even, -odd ]\n", CommandLine()->GetParm( nFpIndex ), CommandLine()->GetParm( nFpIndex ) );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CFbx2DmxApp::Create()
|
|
{
|
|
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
|
|
|
|
if ( !ParseArguments() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
AppSystemInfo_t appSystems[] =
|
|
{
|
|
{ "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
|
|
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
|
|
{ "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
|
|
{ "mdllib.dll", MDLLIB_INTERFACE_VERSION },
|
|
{ "filesystem_stdio.dll", FILESYSTEM_INTERFACE_VERSION },
|
|
{ "p4lib.dll", P4_INTERFACE_VERSION },
|
|
{ "", "" } // Required to terminate the list
|
|
};
|
|
|
|
AddSystem( g_pDataModel, VDATAMODEL_INTERFACE_VERSION );
|
|
AddSystem( g_pDmElementFramework, VDMELEMENTFRAMEWORK_VERSION );
|
|
AddSystem( g_pDmSerializers, DMSERIALIZERS_INTERFACE_VERSION );
|
|
|
|
// Add in the locally-defined studio data cache
|
|
AppModule_t studioDataCacheModule = LoadModule( Sys_GetFactoryThis() );
|
|
AddSystem( studioDataCacheModule, STUDIO_DATA_CACHE_INTERFACE_VERSION );
|
|
|
|
// Add the P4 module separately so that if it is absent (say in the SDK) then the other system will initialize properly
|
|
if ( !CommandLine()->FindParm( "-nop4" ) )
|
|
{
|
|
AppModule_t p4Module = LoadModule( "p4lib.dll" );
|
|
AddSystem( p4Module, P4_INTERFACE_VERSION );
|
|
}
|
|
AddSystem( g_pFbx, FBX_INTERFACE_VERSION );
|
|
|
|
bool bOk = AddSystems( appSystems );
|
|
if ( !bOk )
|
|
return false;
|
|
|
|
IMaterialSystem *pMaterialSystem = ( IMaterialSystem* )FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
|
|
if ( !pMaterialSystem )
|
|
return false;
|
|
|
|
pMaterialSystem->SetShaderAPI( "shaderapiempty.dll" );
|
|
|
|
return true;
|
|
}
|
|
|
|
int CFbx2DmxApp::Main()
|
|
{
|
|
char szOptFilename[ MAX_PATH ];
|
|
|
|
// Globally disable DMX undo
|
|
g_pDataModel->SetUndoEnabled( false );
|
|
|
|
// This bit of hackery allows us to access files on the harddrive
|
|
|
|
if ( m_bOptPrintSearchPaths )
|
|
{
|
|
g_pFullFileSystem->PrintSearchPaths();
|
|
}
|
|
|
|
//p4->SetVerbose( false );
|
|
p4->SetOpenFileChangeList( "fbx2dmx" );
|
|
|
|
int nRetVal = -1;
|
|
|
|
char szExt[ MAX_PATH ] = { };
|
|
V_ExtractFileExtension( szOptFilename, szExt, ARRAYSIZE( szExt ) );
|
|
|
|
CDisableUndoScopeGuard noUndo;
|
|
|
|
CDmElement *pDmRoot = NULL;
|
|
|
|
if ( !V_stricmp( szExt, "obj" ) )
|
|
{
|
|
CDmObjSerializer dmObjSerializer;
|
|
pDmRoot = dmObjSerializer.ReadOBJ( szOptFilename );
|
|
|
|
if ( !pDmRoot )
|
|
{
|
|
Warning( "Couldn't load OBJ file: %s\n", szOptFilename );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CDmFbxSerializer dmFbxSerializer;
|
|
|
|
dmFbxSerializer.m_bOptUnderscoreForCorrectors = m_bOptUFC;
|
|
dmFbxSerializer.m_nOptVerbosity = m_nOptVerbosity;
|
|
dmFbxSerializer.m_bAnimation = m_bOptAnimation;
|
|
dmFbxSerializer.m_sOptMaterialSearchPathList = m_sOptMaterialSearchPaths;
|
|
|
|
if ( ProcessAxisSystem( dmFbxSerializer ) )
|
|
{
|
|
pDmRoot = dmFbxSerializer.ReadFBX( m_pszOptFilename );
|
|
|
|
if ( !pDmRoot )
|
|
{
|
|
Warning( "Couldn't load FBX file: %s\n", szOptFilename );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pDmRoot )
|
|
{
|
|
if ( m_pszOptOutFilename )
|
|
{
|
|
nRetVal = DoIt( pDmRoot, m_pszOptOutFilename, m_sOptMaterialSearchPaths );
|
|
}
|
|
else
|
|
{
|
|
nRetVal = DoIt( pDmRoot, m_pszOptFilename, m_sOptMaterialSearchPaths );
|
|
}
|
|
}
|
|
return nRetVal;
|
|
}
|
|
|
|
bool CFbx2DmxApp::ParseArguments()
|
|
{
|
|
if ( CommandLine()->CheckParm( "-h" ) || CommandLine()->CheckParm( "--help" ) || CommandLine()->CheckParm( "-help" ) )
|
|
{
|
|
PrintUsage();
|
|
return false;
|
|
}
|
|
|
|
for ( int i = 1; i < CommandLine()->ParmCount(); ++i )
|
|
{
|
|
const char *pszParam = CommandLine()->GetParm( i );
|
|
|
|
if ( !V_stricmp( pszParam, "-game" ) )
|
|
{
|
|
m_pszOptForceMod = CommandLine()->GetParm( ++i );
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-nop4" ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-ufc" ) )
|
|
{
|
|
m_bOptUFC = true;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-v" ) )
|
|
{
|
|
++m_nOptVerbosity;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-a" ) )
|
|
{
|
|
m_bOptAnimation = true;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-msp" ) || !V_stricmp( pszParam, "-materialSearchPath" ) )
|
|
{
|
|
m_sOptMaterialSearchPaths.AddToTail( CommandLine()->GetParm( ++i ) );
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-psp" ) )
|
|
{
|
|
m_bOptPrintSearchPaths = true;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-up" ) )
|
|
{
|
|
++i;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-fp" ) || !V_stricmp( pszParam, "-forwardParity" ) || !V_stricmp( pszParam, "-forwardparity" ) )
|
|
{
|
|
++i;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-i" ) || !V_stricmp( pszParam, "-input" ) )
|
|
{
|
|
++i;
|
|
pszParam = CommandLine()->GetParm( i );
|
|
if ( m_pszOptFilename )
|
|
{
|
|
Warning( "Warning! Filename was already specified as: \"%s\", using -i \"%s\"\n", m_pszOptFilename, pszParam );
|
|
}
|
|
|
|
m_pszOptFilename = pszParam;
|
|
continue;
|
|
}
|
|
|
|
if ( !V_stricmp( pszParam, "-o" ) || !V_stricmp( pszParam, "-output" ) )
|
|
{
|
|
++i;
|
|
pszParam = CommandLine()->GetParm( i );
|
|
if ( m_pszOptOutFilename )
|
|
{
|
|
Warning( "Warning! Output filename was already specified as: \"%s\", using -o \"%s\"\n", m_pszOptOutFilename, pszParam );
|
|
}
|
|
|
|
m_pszOptOutFilename = pszParam;
|
|
continue;
|
|
}
|
|
|
|
if ( StringHasPrefix( pszParam, "-" ) )
|
|
{
|
|
Warning( "Warning! Unknown command line switch \"%s\"\n", pszParam );
|
|
continue;
|
|
}
|
|
|
|
if ( m_pszOptFilename )
|
|
{
|
|
Warning( "Warning! Filename already specified: \"%s\", ignoring \"%s\"\n", m_pszOptFilename, pszParam );
|
|
}
|
|
else
|
|
{
|
|
m_pszOptFilename = pszParam;
|
|
}
|
|
}
|
|
|
|
if ( !m_pszOptFilename )
|
|
{
|
|
Warning( "Error! Cannot find any file to execute from passed command line arguments\n\n" );
|
|
PrintUsage();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: bind studiohdr_t support functions to fbx2dmx utility
|
|
// FIXME: This should be moved into studio.cpp?
|
|
//-----------------------------------------------------------------------------
|
|
const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *pModelName ) const
|
|
{
|
|
MDLHandle_t handle = g_pMDLCache->FindMDL( pModelName );
|
|
*cache = ( void* )( uintp )handle;
|
|
return g_pMDLCache->GetStudioHdr( handle );
|
|
}
|
|
|
|
virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const
|
|
{
|
|
if ( numincludemodels == 0 )
|
|
return NULL;
|
|
return g_pMDLCache->GetVirtualModelFast( this, VoidPtrToMDLHandle( VirtualModel() ) );
|
|
}
|
|
|
|
byte *studiohdr_t::GetAnimBlock( int i, bool preloadIfMissing ) const
|
|
{
|
|
return g_pMDLCache->GetAnimBlock( VoidPtrToMDLHandle( VirtualModel() ), i, preloadIfMissing );
|
|
}
|
|
|
|
bool studiohdr_t::hasAnimBlockBeenPreloaded( int i ) const
|
|
{
|
|
return g_pMDLCache->HasAnimBlockBeenPreloaded( VoidPtrToMDLHandle( VirtualModel() ), i );
|
|
}
|
|
|
|
int studiohdr_t::GetAutoplayList( unsigned short **pOut ) const
|
|
{
|
|
return g_pMDLCache->GetAutoplayList( VoidPtrToMDLHandle( VirtualModel() ), pOut );
|
|
}
|
|
|
|
const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const
|
|
{
|
|
return g_pMDLCache->GetStudioHdr( VoidPtrToMDLHandle( cache ) );
|
|
}
|