source-engine/public/optimize.h
2022-11-29 18:49:29 +03:00

323 lines
7.6 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef OPTIMIZE_H
#define OPTIMIZE_H
#ifdef _WIN32
#pragma once
#endif
#include "studio.h"
// NOTE: You can change this without affecting the vtx file format.
#define MAX_NUM_BONES_PER_TRI ( MAX_NUM_BONES_PER_VERT * 3 )
#define MAX_NUM_BONES_PER_STRIP 512
#define OPTIMIZED_MODEL_FILE_VERSION 7
extern bool g_bDumpGLViewFiles;
struct s_bodypart_t;
namespace OptimizedModel
{
#pragma pack(1)
struct BoneStateChangeHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int hardwareID;
int newBoneID;
};
struct Vertex_t
{
DECLARE_BYTESWAP_DATADESC();
// these index into the mesh's vert[origMeshVertID]'s bones
unsigned char boneWeightIndex[MAX_NUM_BONES_PER_VERT];
unsigned char numBones;
unsigned short origMeshVertID;
// for sw skinned verts, these are indices into the global list of bones
// for hw skinned verts, these are hardware bone indices
byte boneID[MAX_NUM_BONES_PER_VERT];
};
enum StripHeaderFlags_t {
STRIP_IS_TRILIST = 0x01,
STRIP_IS_TRISTRIP = 0x02
};
struct StripHeader_t
{
DECLARE_BYTESWAP_DATADESC();
// indexOffset offsets into the mesh's index array.
int numIndices;
int indexOffset;
// vertexOffset offsets into the mesh's vert array.
int numVerts;
int vertOffset;
// use this to enable/disable skinning.
// May decide (in optimize.cpp) to put all with 1 bone in a different strip
// than those that need skinning.
short numBones;
unsigned char flags;
int numBoneStateChanges;
int boneStateChangeOffset;
inline BoneStateChangeHeader_t *pBoneStateChange( int i ) const
{
return (BoneStateChangeHeader_t *)(((byte *)this) + boneStateChangeOffset) + i;
};
};
struct StripHeader_v49_t
{
DECLARE_BYTESWAP_DATADESC();
// indexOffset offsets into the mesh's index array.
int numIndices;
int indexOffset;
// vertexOffset offsets into the mesh's vert array.
int numVerts;
int vertOffset;
// use this to enable/disable skinning.
// May decide (in optimize.cpp) to put all with 1 bone in a different strip
// than those that need skinning.
short numBones;
unsigned char flags;
int numBoneStateChanges;
int boneStateChangeOffset;
inline BoneStateChangeHeader_t *pBoneStateChange( int i ) const
{
return (BoneStateChangeHeader_t *)(((byte *)this) + boneStateChangeOffset) + i;
};
int numTopologyIndices;
int topologyOffset;
};
enum StripGroupFlags_t
{
STRIPGROUP_IS_FLEXED = 0x01,
STRIPGROUP_IS_HWSKINNED = 0x02,
STRIPGROUP_IS_DELTA_FLEXED = 0x04,
STRIPGROUP_SUPPRESS_HW_MORPH = 0x08, // NOTE: This is a temporary flag used at run time.
STRIPGROUP_IS_MDL49 = 0x80
};
// a locking group
// a single vertex buffer
// a single index buffer
struct StripGroupHeader_t
{
DECLARE_BYTESWAP_DATADESC();
// These are the arrays of all verts and indices for this mesh. strips index into this.
int numVerts;
int vertOffset;
inline Vertex_t *pVertex( int i ) const
{
return (Vertex_t *)(((byte *)this) + vertOffset) + i;
};
int numIndices;
int indexOffset;
inline unsigned short *pIndex( int i ) const
{
return (unsigned short *)(((byte *)this) + indexOffset) + i;
};
int numStrips;
int stripOffset;
inline StripHeader_t *pStrip( int i ) const
{
if( flags & STRIPGROUP_IS_MDL49 )
return (StripHeader_t *)((StripHeader_v49_t *)(((byte *)this) + stripOffset) + i);
else
return (StripHeader_t *)(((byte *)this) + stripOffset) + i;
};
unsigned char flags;
};
struct StripGroupHeader_v49_t
{
DECLARE_BYTESWAP_DATADESC();
// These are the arrays of all verts and indices for this mesh. strips index into this.
int numVerts;
int vertOffset;
inline Vertex_t *pVertex( int i ) const
{
return (Vertex_t *)(((byte *)this) + vertOffset) + i;
};
int numIndices;
int indexOffset;
inline unsigned short *pIndex( int i ) const
{
return (unsigned short *)(((byte *)this) + indexOffset) + i;
};
int numStrips;
int stripOffset;
inline StripHeader_v49_t *pStrip( int i ) const
{
return (StripHeader_v49_t *)(((byte *)this) + stripOffset) + i;
};
unsigned char flags;
int numTopologyIndices;
int topologyOffset;
};
enum MeshFlags_t {
// these are both material properties, and a mesh has a single material.
MESH_IS_TEETH = 0x01,
MESH_IS_EYES = 0x02,
MESH_IS_MDL49 = 0x80
};
// a collection of locking groups:
// up to 4:
// non-flexed, hardware skinned
// flexed, hardware skinned
// non-flexed, software skinned
// flexed, software skinned
//
// A mesh has a material associated with it.
struct MeshHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int numStripGroups;
int stripGroupHeaderOffset;
inline StripGroupHeader_t *pStripGroup( int i ) const
{
if( flags & STRIPGROUP_IS_MDL49 )
return (StripGroupHeader_t *)((StripGroupHeader_v49_t *)(((byte *)this) + stripGroupHeaderOffset) + i);
else
return (StripGroupHeader_t *)(((byte *)this) + stripGroupHeaderOffset) + i;
};
unsigned char flags;
};
struct ModelLODHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int numMeshes;
int meshOffset;
float switchPoint;
inline MeshHeader_t *pMesh( int i ) const
{
MeshHeader_t *pDebug = (MeshHeader_t *)(((byte *)this) + meshOffset) + i;
return pDebug;
};
};
// This maps one to one with models in the mdl file.
// There are a bunch of model LODs stored inside potentially due to the qc $lod command
struct ModelHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int numLODs; // garymcthack - this is also specified in FileHeader_t
int lodOffset;
inline ModelLODHeader_t *pLOD( int i ) const
{
ModelLODHeader_t *pDebug = ( ModelLODHeader_t *)(((byte *)this) + lodOffset) + i;
return pDebug;
};
};
struct BodyPartHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int numModels;
int modelOffset;
inline ModelHeader_t *pModel( int i ) const
{
ModelHeader_t *pDebug = (ModelHeader_t *)(((byte *)this) + modelOffset) + i;
return pDebug;
};
};
struct MaterialReplacementHeader_t
{
DECLARE_BYTESWAP_DATADESC();
short materialID;
int replacementMaterialNameOffset;
inline const char *pMaterialReplacementName( void )
{
const char *pDebug = (const char *)(((byte *)this) + replacementMaterialNameOffset);
return pDebug;
}
};
struct MaterialReplacementListHeader_t
{
DECLARE_BYTESWAP_DATADESC();
int numReplacements;
int replacementOffset;
inline MaterialReplacementHeader_t *pMaterialReplacement( int i ) const
{
MaterialReplacementHeader_t *pDebug = ( MaterialReplacementHeader_t *)(((byte *)this) + replacementOffset) + i;
return pDebug;
}
};
struct FileHeader_t
{
DECLARE_BYTESWAP_DATADESC();
// file version as defined by OPTIMIZED_MODEL_FILE_VERSION
int version;
// hardware params that affect how the model is to be optimized.
int vertCacheSize;
unsigned short maxBonesPerStrip;
unsigned short maxBonesPerTri;
int maxBonesPerVert;
// must match checkSum in the .mdl
int checkSum;
int numLODs; // garymcthack - this is also specified in ModelHeader_t and should match
// one of these for each LOD
int materialReplacementListOffset;
MaterialReplacementListHeader_t *pMaterialReplacementList( int lodID ) const
{
MaterialReplacementListHeader_t *pDebug =
(MaterialReplacementListHeader_t *)(((byte *)this) + materialReplacementListOffset) + lodID;
return pDebug;
}
int numBodyParts;
int bodyPartOffset;
inline BodyPartHeader_t *pBodyPart( int i ) const
{
BodyPartHeader_t *pDebug = (BodyPartHeader_t *)(((byte *)this) + bodyPartOffset) + i;
return pDebug;
};
};
#pragma pack()
void WriteOptimizedFiles( studiohdr_t *phdr, s_bodypart_t *pSrcBodyParts );
}; // namespace OptimizedModel
#endif // OPTIMIZE_H