hl2_src-leak-2017/src/utils/mdlinfo/main.cpp

886 lines
24 KiB
C++

//============ Copyright (c) Valve Corporation, All rights reserved. ==========++;
//
//=============================================================================
// Valve includes
#include "appframework/appframework.h"
#include "appframework/tier3app.h"
#include "filesystem.h"
#include "icommandline.h"
#include "mathlib/mathlib.h"
#include "tier1/tier1.h"
#include "tier2/tier2.h"
#include "tier3/tier3.h"
#include "tier1/utlbuffer.h"
#include "tier1/fmtstr.h"
#include "studio.h"
#include "datacache/idatacache.h"
#include "datacache/imdlcache.h"
#include "vphysics_interface.h"
#include "materialsystem/imaterialsystem.h"
#include "istudiorender.h"
#include "vstdlib/iprocessutils.h"
#include "tier2/fileutils.h"
// Last include
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static CFmtStr PrettyPrintFloat( const float &flVal, float flEps = 0.000005f )
{
if ( FloatMakePositive( flVal ) <= flEps )
{
return CFmtStr( "%.6f", 0.0f );
}
return CFmtStr( "%.6f", flVal );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static CFmtStr PrettyPrintVector( const Vector &v )
{
return CFmtStr( "%s %s %s",
PrettyPrintFloat( v.x ).Get(),
PrettyPrintFloat( v.y ).Get(),
PrettyPrintFloat( v.z ).Get() );
}
//-----------------------------------------------------------------------------
// A src bone transform transforms pre-compiled data (.dmx or .smd files, for example)
// into post-compiled data (.mdl or .ani files)
//-----------------------------------------------------------------------------
static const mstudiosrcbonetransform_t *GetSrcBoneTransform( const studiohdr_t *pStudioHdr, int nBoneIndex )
{
if ( !pStudioHdr || nBoneIndex < 0 || nBoneIndex >= pStudioHdr->numbones )
return false;
const char *pszBoneName = pStudioHdr->pBone( nBoneIndex )->pszName();
const int nSrcBoneTransformCount = pStudioHdr->NumSrcBoneTransforms();
for ( int i = 0; i < nSrcBoneTransformCount; ++i )
{
const mstudiosrcbonetransform_t *pSrcBoneTransform = pStudioHdr->SrcBoneTransform( i );
if ( pSrcBoneTransform && !Q_stricmp( pSrcBoneTransform->pszName(), pszBoneName ) )
return pSrcBoneTransform;
}
return NULL;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
struct CommandLineBinaryOpt_t
{
const char *m_pszShortName;
const char *m_pszLongName;
const char *m_pszDoc;
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
class CMdlInfoApp : public CTier3SteamApp
{
typedef CTier3SteamApp BaseClass;
public:
CMdlInfoApp();
// Methods of IApplication
virtual bool Create() OVERRIDE;
virtual bool PreInit() OVERRIDE;
virtual int Startup() OVERRIDE;
virtual int Main() OVERRIDE;
virtual void Shutdown() OVERRIDE;
virtual void PostShutdown() OVERRIDE;
virtual void Destroy() OVERRIDE {};
static const CommandLineBinaryOpt_t s_binaryOptions[];
bool m_bOptAll;
bool m_bOptVerbose;
static const char kOptHelp[];
static const char kOptVerbose[];
static const char kOptInput[];
static const char kOptGeneral[];
static const char kOptBones[];
static const char kOptAttachments[];
static const char kOptAnimation[];
static const char kOptSequence[];
static const char kOptMesh[];
static const char kOptTexture[];
static const char kOptSkin[];
static bool CommandLineHasOpt( const char *pszOpt );
bool DoIt( const char *pszFileIn );
void HandleOptions();
static MDLHandle_t GetMDLHandle( const char *pszFilename );
void PrintHelp();
void DumpGeneral( MDLHandle_t hMdl, CStudioHdr &cStudioHdr ) const;
void DumpBones( CStudioHdr &cStudioHdr ) const;
void DumpAttachments( CStudioHdr &cStudioHdr ) const;
void DumpAnimationList( CStudioHdr &cStudioHdr ) const;
void DumpSequenceList( CStudioHdr &cStudioHdr ) const;
void DumpMesh( CStudioHdr &cStudioHdr ) const;
void DumpTexture( CStudioHdr &cStudioHdr ) const;
void DumpSkin( CStudioHdr &cStudioHdr ) const;
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
const char CMdlInfoApp::kOptHelp[] = "-help";
const char CMdlInfoApp::kOptVerbose[] = "-verbose";
const char CMdlInfoApp::kOptInput[] = "-input";
const char CMdlInfoApp::kOptGeneral[] = "-general";
const char CMdlInfoApp::kOptBones[] = "-bones";
const char CMdlInfoApp::kOptAttachments[] = "-attachments";
const char CMdlInfoApp::kOptAnimation[] = "-animation";
const char CMdlInfoApp::kOptSequence[] = "-sequence";
const char CMdlInfoApp::kOptMesh[] = "-mesh";
const char CMdlInfoApp::kOptTexture[] = "-texture";
const char CMdlInfoApp::kOptSkin[] = "-skin";
const CommandLineBinaryOpt_t CMdlInfoApp::s_binaryOptions[] =
{
{ "-h", kOptHelp, "Print usage information" },
{ "-v", kOptVerbose, "Print extra junk" },
{ "-i", kOptInput, "Specifies the input MDL file" },
{ "-g", kOptGeneral, "Print general information section" },
{ "-b", kOptBones, "Print bones/skeleton section" },
{ "-at", kOptAttachments, "Print attachments section" },
{ "-a", kOptAnimation, "Print animation section" },
{ "-s", kOptSequence, "Print sequence section" },
{ "-m", kOptMesh, "Print mesh section" },
{ "-t", kOptTexture, "Print texture section" },
{ "-k", kOptSkin, "Print sKin section" }
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( CMdlInfoApp );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CMdlInfoApp::CMdlInfoApp()
: m_bOptAll( true )
, m_bOptVerbose( false )
{
}
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
bool CMdlInfoApp::Create()
{
AppSystemInfo_t appSystems[] =
{
{ "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
{ "materialsystem.dll", MATERIAL_SYSTEM_INTERFACE_VERSION },
{ "datacache.dll", DATACACHE_INTERFACE_VERSION },
{ "datacache.dll", MDLCACHE_INTERFACE_VERSION },
{ "vphysics.dll", VPHYSICS_INTERFACE_VERSION },
{ "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
{ "", "" } // Required to terminate the list
};
if ( !AddSystems( appSystems ) )
return false;
IMaterialSystem *pMaterialSystem = (IMaterialSystem*)FindSystem( MATERIAL_SYSTEM_INTERFACE_VERSION );
if ( !pMaterialSystem )
{
Warning( "Create: Unable to connect to material system interface!\n" );
return false;
}
pMaterialSystem->SetShaderAPI( "shaderapiempty.dll" );
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CMdlInfoApp::PreInit()
{
MathLib_Init();
if ( !BaseClass::PreInit() )
return false;
CreateInterfaceFn factory = GetFactory();
ConnectTier1Libraries( &factory, 1 );
ConnectTier2Libraries( &factory, 1 );
ConnectTier3Libraries( &factory, 1 );
if ( !g_pFullFileSystem || !g_pMDLCache )
{
Warning( "Error! mdlinfo is missing a required interface!\n" );
return false;
}
SetupSearchPaths( NULL, false, true );
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CMdlInfoApp::Startup()
{
if ( BaseClass::Startup() < 0 )
return -1;
if ( g_pMaterialSystem )
{
g_pMaterialSystem->ModInit();
}
if ( g_pDataCache )
{
g_pDataCache->SetSize( 64 * 1024 * 1024 );
}
return 0;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CMdlInfoApp::Main()
{
// This bit of hackery allows us to access files on the harddrive
g_pFullFileSystem->AddSearchPath( "", "LOCAL", PATH_ADD_TO_HEAD );
if ( CommandLineHasOpt( kOptHelp ) )
{
PrintHelp();
return 0;
}
const char *pszOptFileIn = CommandLine()->ParmValue( "-i" );
if ( !pszOptFileIn )
pszOptFileIn = CommandLine()->ParmValue( "-input" );
if ( pszOptFileIn )
return DoIt( pszOptFileIn );
Warning( "Error! Missing -i <file>.mdl\n\n" );
PrintHelp();
return -1;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::Shutdown()
{
if ( g_pMaterialSystem )
{
g_pMaterialSystem->ModShutdown();
}
BaseClass::Shutdown();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::PostShutdown()
{
DisconnectTier3Libraries();
DisconnectTier2Libraries();
DisconnectTier1Libraries();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CMdlInfoApp::CommandLineHasOpt( const char *pszOpt )
{
for ( int ii = 0; ii < ARRAYSIZE( s_binaryOptions ); ++ii )
{
if ( !V_stricmp( pszOpt, s_binaryOptions[ii].m_pszShortName ) || !V_stricmp( pszOpt, s_binaryOptions[ii].m_pszLongName ) )
{
if ( CommandLine()->FindParm( s_binaryOptions[ii].m_pszShortName ) > 0 || CommandLine()->FindParm( s_binaryOptions[ii].m_pszLongName ) > 0 )
return true;
return false;
}
}
if ( CommandLine()->FindParm( pszOpt ) > 0 )
return true;
return false;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CMdlInfoApp::DoIt( const char *pszFileIn )
{
HandleOptions();
MDLHandle_t hMdl = GetMDLHandle( pszFileIn );
if ( hMdl == MDLHANDLE_INVALID )
return false;
// Get the model
studiohdr_t *pHdr = g_pMDLCache->GetStudioHdr( hMdl );
if ( !pHdr )
return false;
CStudioHdr cStudioHdr( pHdr, g_pMDLCache );
DumpGeneral( hMdl, cStudioHdr );
DumpBones( cStudioHdr );
DumpAttachments( cStudioHdr );
DumpAnimationList( cStudioHdr );
DumpSequenceList( cStudioHdr );
DumpMesh( cStudioHdr );
DumpTexture( cStudioHdr );
DumpSkin( cStudioHdr );
g_pMDLCache->Release( hMdl );
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::HandleOptions()
{
if (
CommandLineHasOpt( kOptGeneral ) ||
CommandLineHasOpt( kOptBones ) ||
CommandLineHasOpt( kOptAttachments ) ||
CommandLineHasOpt( kOptAnimation ) ||
CommandLineHasOpt( kOptSequence ) ||
CommandLineHasOpt( kOptMesh ) ||
CommandLineHasOpt( kOptTexture ) ||
CommandLineHasOpt( kOptSkin ) )
{
m_bOptAll = false;
}
if ( CommandLineHasOpt( kOptVerbose ) )
{
m_bOptVerbose = true;
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MDLHandle_t CMdlInfoApp::GetMDLHandle( const char *pszFilename )
{
if ( pszFilename == NULL )
return MDLHANDLE_INVALID;
char szFullPath[ MAX_PATH ];
if ( !GenerateFullPath( pszFilename, NULL, szFullPath, ARRAYSIZE( szFullPath ) ) )
{
V_strncpy( szFullPath, pszFilename, ARRAYSIZE( szFullPath ) );
}
MDLHandle_t hMdl = g_pMDLCache->FindMDL( szFullPath );
if ( hMdl == MDLHANDLE_INVALID )
{
Error( "Couldn't Load MDL %s via g_pMDLCache\n", pszFilename );
}
else
{
studiohdr_t *pHdr = g_pMDLCache->GetStudioHdr( hMdl );
if ( !pHdr || !V_strcmp( "error.mdl", pHdr->pszName() ) )
{
Error( "Couldn't Load MDL %s via g_pMDLCache, got error model instead\n", pszFilename );
g_pMDLCache->Release( hMdl );
hMdl = MDLHANDLE_INVALID;
}
}
return hMdl;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::PrintHelp()
{
Msg( "\n" );
Msg( "NAME\n" );
Msg( " mdlinfo - Prints information about a VALVe MDL file\n" );
Msg( "\n" );
Msg( "SYNOPSIS\n" );
Msg( " mdlinfo [ options ] < -i filename.mdl >\n" );
Msg( "\n" );
for ( int ii = 0; ii < ARRAYSIZE( s_binaryOptions ); ++ii )
{
const CommandLineBinaryOpt_t &opt = s_binaryOptions[ii];
Msg( " %s | %s : %s\n", opt.m_pszShortName, opt.m_pszLongName, opt.m_pszDoc );
}
Msg( "\n" );
Msg( "DESCRIPTION\n" );
Msg( " Prints information about a VALVe MDL file\n" );
Msg( " If no sections are specified, all are printed\n" );
Msg( " Multiple section specifiers can be specified but print order is fixed\n" );
Msg( "\n" );
Msg( "\n" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpGeneral( MDLHandle_t hMdl, CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptGeneral ) ) )
return;
const studiohdr_t *pHdr = cStudioHdr.GetRenderHdr();
Msg( "//\n" );
Msg( "// MDL General Info\n" );
Msg( "//\n" );
Msg( "\n" );
Msg( "// MDL: %s\n", cStudioHdr.pszName() );
Msg( "// Filename: %s\n", g_pMDLCache->GetModelName( hMdl ) );
Msg( "// Id: 0x%08x\n", pHdr->id );
Msg( "// Version: 0x%08x\n", pHdr->version );
Msg( "// Checksum: 0x%08x\n", pHdr->checksum );
Msg( "// EyePosition: %s\n", PrettyPrintVector( pHdr->eyeposition ).Get() );
Msg( "// IllumPosition: %s\n", PrettyPrintVector( pHdr->illumposition ).Get() );
Msg( "// Hull Min: %s\n", PrettyPrintVector( pHdr->hull_min ).Get() );
Msg( "// Hull Max: %s\n", PrettyPrintVector( pHdr->hull_max ).Get() );
Msg( "// Bone Count: %d\n", cStudioHdr.numbones() );
const char *pszSurfaceProp = cStudioHdr.pszSurfaceProp();
if ( pszSurfaceProp )
{
Msg( "// SurfaceProp: %s\n", pszSurfaceProp );
}
Msg( "\n" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static void PrintBoneFlags( const mstudiobone_t *pBone )
{
CFmtStrMax sBoneFlags;
struct BoneFlag_t
{
int m_nMask;
const char *m_pzsName;
};
static const BoneFlag_t boneFlags[] =
{
{ BONE_PHYSICALLY_SIMULATED, "BONE_PHYSICALLY_SIMULATED" },
{ BONE_PHYSICS_PROCEDURAL, "BONE_PHYSICS_PROCEDURAL" },
{ BONE_ALWAYS_PROCEDURAL, "BONE_ALWAYS_PROCEDURAL" },
{ BONE_SCREEN_ALIGN_SPHERE, "BONE_SCREEN_ALIGN_SPHERE" },
{ BONE_SCREEN_ALIGN_CYLINDER, "BONE_SCREEN_ALIGN_CYLINDER" },
{ BONE_USED_BY_HITBOX, "BONE_USED_BY_HITBOX" },
{ BONE_USED_BY_ATTACHMENT, "BONE_USED_BY_ATTACHMENT" },
{ BONE_USED_BY_VERTEX_LOD0, "BONE_USED_BY_VERTEX_LOD0" },
{ BONE_USED_BY_VERTEX_LOD1, "BONE_USED_BY_VERTEX_LOD1" },
{ BONE_USED_BY_VERTEX_LOD2, "BONE_USED_BY_VERTEX_LOD2" },
{ BONE_USED_BY_VERTEX_LOD3, "BONE_USED_BY_VERTEX_LOD3" },
{ BONE_USED_BY_VERTEX_LOD4, "BONE_USED_BY_VERTEX_LOD4" },
{ BONE_USED_BY_VERTEX_LOD5, "BONE_USED_BY_VERTEX_LOD5" },
{ BONE_USED_BY_VERTEX_LOD6, "BONE_USED_BY_VERTEX_LOD6" },
{ BONE_USED_BY_VERTEX_LOD7, "BONE_USED_BY_VERTEX_LOD7" },
{ BONE_USED_BY_BONE_MERGE, "BONE_USED_BY_BONE_MERGE" },
{ BONE_FIXED_ALIGNMENT, "BONE_FIXED_ALIGNMENT" },
{ BONE_HAS_SAVEFRAME_POS, "BONE_HAS_SAVEFRAME_POS" },
{ BONE_HAS_SAVEFRAME_ROT, "BONE_HAS_SAVEFRAME_ROT" },
};
Msg( "// + Bone Flags: 0x%08x\n", pBone->flags );
for ( int ii = 0; ii < ARRAYSIZE( boneFlags ); ++ii )
{
if ( pBone->flags & boneFlags[ii].m_nMask )
{
Msg( "// - 0x%08x %s\n", boneFlags[ii].m_nMask, boneFlags[ii].m_pzsName );
}
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpBones( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptBones ) ) )
return;
const float flEps = 1.0e-5;
static const Quaternion qIdentity( 0.0f, 0.0f, 0.0f, 1.0f );
const int nBoneCount = cStudioHdr.numbones();
Msg( "//\n" );
Msg( "// Define Bones, Bone Count: %d\n", nBoneCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nBoneCount; ++ii )
{
const mstudiobone_t *pBone = cStudioHdr.pBone( ii );
const mstudiobone_t *pParentBone = pBone->parent < ii && pBone->parent >= 0 ? cStudioHdr.pBone( pBone->parent ) : NULL;
const mstudiosrcbonetransform_t *pSrcBoneTransform = GetSrcBoneTransform( cStudioHdr.GetRenderHdr(), ii );
bool bRealigned = false;
Vector vAlignment;
QAngle aAlignment;
if ( pSrcBoneTransform )
{
MatrixAngles( pSrcBoneTransform->posttransform, aAlignment, vAlignment );
if ( !QAnglesAreEqual( QAngle( 0.0f, 0.0f, 0.0f ), aAlignment, flEps ) || !VectorsAreEqual( Vector( 0.0f, 0.0f, 0.0f ), vAlignment, flEps ) )
{
bRealigned = true;
}
}
if ( m_bOptVerbose )
{
Msg( "// * %3d: %s\n", ii, pBone->pszName() );
if ( pParentBone )
{
Msg( "// + Parent: %3d: %s\n", pBone->parent, pParentBone->pszName() );
}
if ( bRealigned )
{
Msg( "// + REALIGNED\n" );
}
if ( pBone->flags & BONE_ALWAYS_PROCEDURAL )
{
static const char *s_ProcType[] = { "<ERROR", "AXISINTERP", "QUATINTERP", "AIMATBONE", "AIMATTACH", "JIGGLE" };
Msg( "// + Procedural Type: %s\n", s_ProcType[pBone->proctype] );
}
const char *pszSurfaceProp = pBone->pszSurfaceProp();
if ( pszSurfaceProp )
{
Msg( "// + Surface Prop: %s\n", pszSurfaceProp );
}
PrintBoneFlags( pBone );
}
const QAngle aRot = pBone->rot.ToQAngle();
if ( pBone->flags & BONE_ALWAYS_PROCEDURAL )
{
}
CFmtStrMax sTmp( "%s$definebone \"%s\" \"%s\" %s %s %s %s %s %s",
( pBone->flags & BONE_ALWAYS_PROCEDURAL ) ? "// procedural " : "",
pBone->pszName(),
pParentBone ? pParentBone->pszName() : "",
PrettyPrintFloat( pBone->pos.x ).Get(),
PrettyPrintFloat( pBone->pos.y ).Get(),
PrettyPrintFloat( pBone->pos.z ).Get(),
PrettyPrintFloat( aRot.x ).Get(),
PrettyPrintFloat( aRot.y ).Get(),
PrettyPrintFloat( aRot.z ).Get() );
if ( bRealigned )
{
sTmp.AppendFormat( " %s %s %s %s %s %s",
PrettyPrintFloat( vAlignment.x ).Get(),
PrettyPrintFloat( vAlignment.y ).Get(),
PrettyPrintFloat( vAlignment.z ).Get(),
PrettyPrintFloat( aAlignment.x ).Get(),
PrettyPrintFloat( aAlignment.y ).Get(),
PrettyPrintFloat( aAlignment.z ).Get() );
}
sTmp.Append( "\n" );
Msg( sTmp.Get() );
if ( m_bOptVerbose )
{
Msg( "\n" );
}
}
if ( !m_bOptVerbose )
{
Msg( "\n" );
}
bool bSaveFrame = false;
for ( int ii = 0; ii < nBoneCount; ++ii )
{
const mstudiobone_t *pBone = cStudioHdr.pBone( ii );
const bool bPosition = ( pBone->flags & BONE_HAS_SAVEFRAME_POS ) != 0;
const bool bRotation = ( pBone->flags & BONE_HAS_SAVEFRAME_POS ) != 0;
if ( bPosition || bRotation )
{
bSaveFrame = true;
CFmtStr sTmp( "$BoneSaveFrame \"%s\"", pBone->pszName() );
if ( bPosition )
{
sTmp.Append( " position" );
}
if ( bRotation )
{
sTmp.Append( " rotation" );
}
sTmp.Append( "\n" );
Msg( sTmp.Get() );
}
}
if ( bSaveFrame )
{
Msg( "\n" );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpAttachments( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptAttachments ) ) )
return;
const int nAtttachmentCount = cStudioHdr.GetNumAttachments();
Msg( "//\n" );
Msg( "// Attachment Count: %d\n", nAtttachmentCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nAtttachmentCount; ++ii )
{
const mstudioattachment_t &attachment = cStudioHdr.pAttachment( ii );
CFmtStrMax sTmp( "$attachment \"%s\"",
attachment.pszName() );
sTmp.Append( "\n" );
Msg( sTmp.Get() );
}
if ( !m_bOptVerbose )
{
Msg( "\n" );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpAnimationList( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptAnimation ) ) )
return;
int nAnimCount = 0;
virtualmodel_t *pVirtualModel = cStudioHdr.GetVirtualModel();
if ( pVirtualModel )
{
nAnimCount = pVirtualModel->m_anim.Count();
}
else
{
nAnimCount = cStudioHdr.GetRenderHdr()->numlocalanim;
}
Msg( "//\n" );
Msg( "// Animation Count: %d\n", nAnimCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nAnimCount; ++ii )
{
const mstudioanimdesc_t &animDesc = cStudioHdr.pAnimdesc( ii );
const studiohdr_t *pHdr = cStudioHdr.pAnimStudioHdr( ii );
if ( pHdr != cStudioHdr.GetRenderHdr() )
{
Msg( "// %3d: %-50s [Included From %s]\n", ii, animDesc.pszName(), pHdr->pszName() );
}
else
{
Msg( "// %3d: %-50s\n", ii, animDesc.pszName() );
}
}
Msg( "\n" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpSequenceList( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptSequence ) ) )
return;
const int nSeqCount = cStudioHdr.GetNumSeq();
Msg( "//\n" );
Msg( "// Sequence Count: %d\n", nSeqCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nSeqCount; ++ii )
{
const mstudioseqdesc_t &seqDesc = cStudioHdr.pSeqdesc( ii );
const studiohdr_t *pHdr = cStudioHdr.pSeqStudioHdr( ii );
if ( pHdr != cStudioHdr.GetRenderHdr() )
{
Msg( "// %3d: %-50s %-50s [Included From %s]\n", ii, seqDesc.pszLabel(), seqDesc.pszActivityName(), pHdr->pszName() );
}
else
{
Msg( "// %3d: %-50s %-50s\n", ii, seqDesc.pszLabel(), seqDesc.pszActivityName() );
}
}
Msg( "\n" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpMesh( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptMesh ) ) )
return;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpTexture( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptTexture ) ) )
return;
const studiohdr_t *pHdr = cStudioHdr.GetRenderHdr();
const int nTextureCount = pHdr->numtextures;
Msg( "//\n" );
Msg( "// Texture Count: %d\n", nTextureCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nTextureCount; ++ii )
{
const mstudiotexture_t *pTexture = pHdr->pTexture( ii );
Msg( "// Texture: %2d: %s\n", ii, pTexture->pszName() );
}
Msg( "\n" );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CMdlInfoApp::DumpSkin( CStudioHdr &cStudioHdr ) const
{
if ( !( m_bOptAll || CommandLineHasOpt( kOptSkin ) ) )
return;
const studiohdr_t *pHdr = cStudioHdr.GetRenderHdr();
const int nSkinCount = pHdr->numskinfamilies;
Msg( "//\n" );
Msg( "// Skin Count: %d\n", nSkinCount );
Msg( "//\n" );
Msg( "\n" );
for ( int ii = 0; ii < nSkinCount; ++ii )
{
const short *pSkinRef = pHdr->pSkinref( ii * pHdr->numskinref );
CFmtStrMax sTmp( "// Skin: %2d: [", ii );
for ( int jj = 0; jj < pHdr->numskinref; ++jj )
{
const int nTextureIndex = pSkinRef[jj];
sTmp.AppendFormat( " %3d", nTextureIndex );
}
sTmp.Append( " ]\n" );
Msg( sTmp.Get() );
}
Msg( "\n" );
}