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.
886 lines
24 KiB
886 lines
24 KiB
//============ 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" ); |
|
} |