|
|
//========= Copyright c 1996-2011, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//====================================================================================//
#ifndef __MDLCOMBINE_H
#define __MDLCOMBINE_H
#ifdef _WIN32
#pragma once
#endif
#include "utlbuffer.h"
struct studiohdr2_t; struct studiodata_t; struct mstudiobone_t; struct mstudioanimdesc_t; struct mstudiomodel_t; class CModelCombine; class KeyValues;
namespace OptimizedModel { struct StripGroupHeader_t; struct StripHeader_t; struct MeshHeader_t; struct ModelLODHeader_t; struct ModelHeader_t; struct BodyPartHeader_t; }
//#define DEBUG_COMBINE 1
#define COMBINER_MAX_STRINGS 2000
#define COMBINER_MAX_BONES ( 53 * 2 )
#define COMBINER_MAX_SUB_MODELS 20
#define COMBINER_WORK_BUFFER_SIZE ( 2 * 1024 * 1024 )
#define COMBINER_MAX_MATERIALS ( COMBINER_MAX_MATERIALS_PER_INPUT_MODEL * COMBINER_MAX_MODELS )
#define COMBINER_MAX_BODYPARTS_PER_MODEL 5
typedef struct SAtlasGroup { unsigned char *m_pCombinedTextures[ COMBINER_MAX_TEXTURES_PER_MATERIAL ]; int m_nCombinedTextureSizes[ COMBINER_MAX_TEXTURES_PER_MATERIAL ]; KeyValues *m_pCombinedMaterial; char m_szCombinedMaterialName[ MAX_PATH ]; } TAtlasGroup;
typedef struct SCombinedStudioData { studiodata_t *m_pPlaceholderStudioData; MDLHandle_t m_PlaceholderHandle; studiodata_t *m_pFinalStudioData; MDLHandle_t m_FinalHandle; void *m_pCombinedUserData; unsigned int m_nReferenceFlags; CombinedModelLoadedCallback m_CallbackFunc; CModelCombine *m_pCombineData;
SCombinerModelInput_t m_ModelInputData[ COMBINER_MAX_MODELS ]; int m_nNumModels;
int m_nModelMaterialCounts[ COMBINER_MAX_MODELS ]; int m_nModelMaterialIndices[ COMBINER_MAX_MODELS ][ COMBINER_MAX_MATERIALS ];
int m_MeshToMaterialMap[ COMBINER_MAX_MODELS ][ COMBINER_MAX_BODYPARTS_PER_MODEL ][ COMBINER_MAX_MATERIALS_PER_INPUT_MODEL ]; TAtlasGroup m_AtlasGroups[ COMBINER_MAX_ATLAS_GROUPS ]; int m_nNumAtlasGroups;
char m_szNonAtlasedMaterialPaths[ COMBINER_MAX_MODELS ][ MAX_PATH ]; int m_nNumNonAtlasedMaterialPaths;
KeyValues *m_pNonAtlasedMaterialKVs[ COMBINER_MAX_MODELS ]; char m_szNonAtlasedMaterialBaseName[ COMBINER_MAX_MODELS ][ MAX_PATH ]; int m_nNumNonAtlasedMaterialBaseNames;
char m_szCombinedModelName[ MAX_PATH ];
// returned results
TCombinedResults m_Results;
} TCombinedStudioData;
enum { WRITE_AREA_MDL = 0, WRITE_AREA_VTX, WRITE_AREA_VVD, WRITE_AREA_VTF,
MAX_WRITE_AREAS };
class CCombinerMemoryWriter { public: CCombinerMemoryWriter( ); ~CCombinerMemoryWriter( );
void Init( );
void InitWriteArea( int nArea, char *pPosition ); void SetWriteArea( int nArea );
char *AllocWrite( int nSize ); char *WriteOffset( int &nOffsetIndex ); char *WriteOffset( int &nOffsetIndex, void *pBasePtr ); char *WriteOffset( short &nOffsetIndex, void *pBasePtr ); char *WriteBuffer( const void *pData, int nSize ); char *WriteBufferWithOffset( const void *pData, int nSize, int &nOffsetIndex ); char *WriteString( const char *pszString ); // adds NULL terminator
char *WriteText( const char *pszString ); // does not add NULL terminator
void AlignWrite( int nAlignSize );
char *GetSaveWritePos( int nArea ) { return m_pSaveWritePos[ nArea ]; } char *GetWritePos( ) { return m_pWritePos; } char *GetWriteArea( ) { return m_pWriteArea; }
private: char *m_pWorkBuffer; char *m_pEndBuffer; char *m_pWriteArea; char *m_pSaveWriteArea[ MAX_WRITE_AREAS ]; char *m_pWritePos; char *m_pSaveWritePos[ MAX_WRITE_AREAS ]; int m_nWriteArea; #ifdef DEBUG_COMBINE
char *m_pErrorPos; #endif
};
extern CCombinerMemoryWriter g_CombinerWriter;
class CModelCombine { public: CModelCombine( ); ~CModelCombine( );
void Init( TCombinedStudioData *pCombinedStudioData );
bool Resolve( );
void *GetCombinedMDLPtr( ) { return ( void * )m_pCombinedStudioHdr; } int GetCombinedMDLSize( ) { return g_CombinerWriter.GetSaveWritePos( WRITE_AREA_MDL ) - ( char *)m_pCombinedStudioHdr; } bool GetCombinedMDLAvailability( ) { return GetCombinedMDLSize() != 0; }
void *GetCombinedVTXPtr( ) { return ( void * )m_pCombinedHardwareHeader; } int GetCombinedVTXSize( ) { return g_CombinerWriter.GetSaveWritePos( WRITE_AREA_VTX ) - ( char *)m_pCombinedHardwareHeader; } bool GetCombinedVTXAvailability( ) { return GetCombinedVTXSize() != 0; }
void *GetCombinedVVDPtr( ) { return ( void * )m_pCombinedVertex; } int GetCombinedVVDSize( ) { return g_CombinerWriter.GetSaveWritePos( WRITE_AREA_VVD ) - ( char *)m_pCombinedVertex; } bool GetCombinedVVDAvailability( ) { return GetCombinedVVDSize() != 0; }
TCombinedResults *GetResults( ) { return &m_pCombinedStudioData->m_Results; }
static int GetNextAssetID( ) { return ++m_nNextAssetID; }
private: static int BoneNameCompare( const void *elem1, const void *elem2 );
void BeginStringTable( ); void AddToStringTable( void *base, int *ptr, const char *string ); void WriteStringTable( );
void VerifyField( int nField, const char *pszDescription ); void VerifyField2( int nField, const char *pszDescription ); void VerifyOffset( void *pPtr, const char *pszDescription, void *pWritePos = 0 );
void DetermineMasterBoneList( );
//
void CombineMDL_PreintStrings( );
void RemapBone( int nModel, int &nBone ) { nBone = m_nBoneRemap[ nModel ][ nBone ]; }
void WriteBoneProc( int nSize, int nType1, int nType2 = -999 ); void WriteBoneQuatInterp( ); void WriteBoneTwist( ); void WriteBoneConstraints( ); void WriteBoneAttachments( ); void WriteHitBoxes( ); void WriteBoneTable( ); void CombineMDL_Bones( ); void WriteAnimation( mstudioanimdesc_t *pOrigAnim, void *pAnimData, int nFrameSize ); void CombineMDL_Anims( );
void CombineMDL_SequenceInfo( );
void WriteModel( int nModel ); void CombineMDL_Model( );
void CombineMDL_Textures( );
void CombineMDL_KeyValues( );
void CombineMDL_BoneTransforms( );
void CombineMDL_BoneFlexDrivers( );
void CombineMDL_AssignMeshIDs( );
void CombineMDL( bool bNoStringTable ); #ifdef DEBUG_COMBINE
void TestCombineMDL( ); #endif // DEBUG_COMBINE
void CalcVTXInfo();
void WriteStrip( OptimizedModel::StripGroupHeader_t *pNewStripGroup, int nModel, OptimizedModel::StripGroupHeader_t *pOrigStripGroup, OptimizedModel::StripHeader_t *pOrigStrip ); void MergeStripGroup( int nLOD, OptimizedModel::StripGroupHeader_t *pNewStripGroup, int nModel, OptimizedModel::StripGroupHeader_t *pOrigStripGroup ); void WriteStripGroup( int nLOD, int nMaterialIndex, unsigned char nStripGroupFlags, OptimizedModel::MeshHeader_t *pNewMesh ); void WriteMeshes( int nLOD, int nMaterialIndex, OptimizedModel::ModelLODHeader_t *pNewModelLOD, OptimizedModel::ModelLODHeader_t *pOrigModelLOD ); void WriteModelLOD( int nLOD, OptimizedModel::ModelHeader_t *pNewModel, OptimizedModel::ModelHeader_t *pOrigModel ); void WriteModel( int nModel, OptimizedModel::BodyPartHeader_t *pNewBodyPart, OptimizedModel::BodyPartHeader_t *pOrigBodyPart ); void WriteBodyPart( int nBodyPart ); void CombineVTX( ); #ifdef DEBUG_COMBINE
void TestCombineVTX( ); #endif // DEBUG_COMBINE
//
void CombineVVD_OffsetVerts( ); void CombineVVD( );
//
void CombineTextures( ); int AddMaterialToTextureCombiner( int nTextureIndex, int nModel, int nModelMaterialIndex );
void Test( );
typedef struct SHardwareData { int m_nBodyParts; int m_nMaxBodyParts; int m_nModels; int m_nModelLODs; int m_nMeshes; int m_nStripGroups; int m_nStrips; int m_nVerts; int m_nIndices; int m_nBoneStateChanges; int m_nStringTable; int m_nTopology; int m_nMaterialReplacements; } THardwareData;
TCombinedStudioData *m_pCombinedStudioData;
CUtlBuffer *MDL_Data[ COMBINER_MAX_MODELS ]; CUtlBuffer *VTX_Data[ COMBINER_MAX_MODELS ]; CUtlBuffer *VVD_Data[ COMBINER_MAX_MODELS ];
studiohdr_t *m_pStudioHdr[ COMBINER_MAX_MODELS ]; studiohdr2_t *m_pStudioHdr2[ COMBINER_MAX_MODELS ]; vertexFileHeader_t *m_pVertexFileHeader[ COMBINER_MAX_MODELS ];
const mstudiobone_t *m_pMasterBoneList[ COMBINER_MAX_BONES ]; int m_nBoneModelOwner[ COMBINER_MAX_BONES ]; int m_nNumMasterBones; int m_nBoneRemap[ COMBINER_MAX_MODELS ][ COMBINER_MAX_BONES ]; int m_nMasterToLocalBoneRemap[ COMBINER_MAX_MODELS ][ COMBINER_MAX_BONES ]; mstudiomodel_t *m_pMasterModels[ COMBINER_MAX_MODELS ][ COMBINER_MAX_SUB_MODELS ]; mstudiomodel_t *m_pMasterFlexModels[ COMBINER_MAX_SUB_MODELS ]; int *m_nVertexRemap[ COMBINER_MAX_MODELS ]; int m_nFlexModelSource; THardwareData m_MaxHardwareData; THardwareData m_CurrentHardwareData; THardwareData m_HardwareOffsets;
studiohdr_t *m_pCombinedStudioHdr; studiohdr2_t *m_pCombinedStudioHdr2; OptimizedModel::FileHeader_t *m_pCombinedHardwareHeader; mstudiomodel_t *m_pCombinedModels; vertexFileHeader_t *m_pCombinedVertex;
struct stringtable_t { byte *base; int *ptr; const char *string; int dupindex; byte *addr; }; int numStrings; stringtable_t strings[ COMBINER_MAX_STRINGS ];
static unsigned int m_nNextAssetID; };
extern CModelCombine g_ModelCombiner;
#endif // __MDLCOMBINE_H
|