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.
 
 
 
 
 
 

313 lines
9.1 KiB

//========= 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