2 //=======================================================================================================================
6 #define MAX_NUM_BONES_PER_VERT 3
11 float weight
[MAX_NUM_BONES_PER_VERT
];
12 char bone
[MAX_NUM_BONES_PER_VERT
];
19 boneWeight_t boneweights
;
32 int numLodVertexes
[MAX_NUM_LODS
];
42 mstudiovertex_t
*GetVertexData( vertexFileHeader_t
*t
)
44 return (mstudiovertex_t
*) ( (char *)t
+ t
->vertexDataStart
);
48 //=======================================================================================================================
54 // these index into the mesh's vert[origMeshVertID]'s bones
55 unsigned char boneWeightIndex
[3];
56 unsigned char numBones
;
58 unsigned short origMeshVertID
;
60 // for sw skinned verts, these are indices into the global list of bones
61 // for hw skinned verts, these are hardware bone indices
68 STRIPGROUP_IS_FLEXED
= 0x01,
69 STRIPGROUP_IS_HWSKINNED
= 0x02,
70 STRIPGROUP_IS_DELTA_FLEXED
= 0x04,
71 STRIPGROUP_SUPPRESS_HW_MORPH
= 0x08, // NOTE: This is a temporary flag used at run time.
74 enum StripHeaderFlags_t
{
75 STRIP_IS_TRILIST
= 0x01,
76 STRIP_IS_TRISTRIP
= 0x02
79 // A strip is a piece of a stripgroup which is divided by bones
94 int numBoneStateChanges
;
95 int boneStateChangeOffset
;
98 // Bone state change inline code ommited
101 // a single vertex buffer
102 // a single index buffer
105 // These are the arrays of all verts and indices for this mesh. strips index into this.
117 VTXStripGroupHeader_t
;
119 VTXVertex_t
*pVertexVTX( VTXStripGroupHeader_t
*t
, int i
)
121 return (VTXVertex_t
*)(((char *)t
) + t
->vertOffset
) + i
;
123 unsigned short *pIndexVTX( VTXStripGroupHeader_t
*t
, int i
)
125 return (unsigned short *)(((char *)t
) + t
->indexOffset
) + i
;
127 VTXStripHeader_t
*pStripVTX( VTXStripGroupHeader_t
*t
, int i
)
129 return (VTXStripHeader_t
*)(((char *)t
) + t
->stripOffset
) + i
;
135 int stripGroupHeaderOffset
;
140 VTXStripGroupHeader_t
*pStripGroupVTX( VTXMeshHeader_t
*t
, int i
)
142 return (VTXStripGroupHeader_t
*)(((char *)t
) + t
->stripGroupHeaderOffset
) + i
;
154 VTXMeshHeader_t
*pMeshVTX( VTXModelLODHeader_t
*t
, int i
)
156 return (VTXMeshHeader_t
*)(((char *)t
) + t
->meshOffset
) + i
;
159 // This maps one to one with models in the mdl file.
163 int numLODs
; //This is also specified in FileHeader_t
167 VTXModelLODHeader_t
*pLODVTX( VTXModelHeader_t
*t
, int i
)
169 return (VTXModelLODHeader_t
*)(((char *)t
) + t
->lodOffset
) + i
;
179 VTXModelHeader_t
*pModelVTX( VTXBodyPartHeader_t
*t
, int i
)
181 return (VTXModelHeader_t
*)(((char *)t
) + t
->modelOffset
) + i
;
186 // file version as defined by OPTIMIZED_MODEL_FILE_VERSION (currently 7)
189 // hardware params that affect how the model is to be optimized.
191 unsigned short maxBonesPerStrip
;
192 unsigned short maxBonesPerTri
;
195 // must match checkSum in the .mdl
198 int numLODs
; // Also specified in ModelHeader_t's and should match
200 // Offset to materialReplacementList Array. one of these for each LOD, 8 in total
201 int materialReplacementListOffset
;
203 //Defines the size and location of the body part array
208 VTXBodyPartHeader_t
*pBodyPartVTX( VTXFileHeader_t
*t
, int i
)
210 return (VTXBodyPartHeader_t
*)(((char *)t
) + t
->bodyPartOffset
) + i
;
215 =============================================
223 L VerticesTable[StudioMDL.Vertex]
224 L IndicesTable[UINT16]
233 u32
vtx_count_indices( VTXFileHeader_t
*t
)
237 for ( int bodyID
= 0; bodyID
< t
->numBodyParts
; ++bodyID
)
239 VTXBodyPartHeader_t
* pVtxBodyPart
= pBodyPartVTX( t
, bodyID
);
240 for ( int modelID
= 0; modelID
< pVtxBodyPart
->numModels
; ++modelID
)
242 VTXModelHeader_t
* pVtxModel
= pModelVTX( pVtxBodyPart
, modelID
);
245 VTXModelLODHeader_t
*pVtxLOD
= pLODVTX( pVtxModel
, nLod
);
247 for ( int nMesh
= 0; nMesh
< pVtxLOD
->numMeshes
; ++nMesh
)
249 VTXMeshHeader_t
* pVtxMesh
= pMeshVTX( pVtxLOD
, nMesh
);
251 for ( int nGroup
= 0; nGroup
< pVtxMesh
->numStripGroups
; ++nGroup
)
253 VTXStripGroupHeader_t
* pStripGroup
= pStripGroupVTX( pVtxMesh
, nGroup
);
255 for ( int nStrip
= 0; nStrip
< pStripGroup
->numStrips
; nStrip
++ )
257 VTXStripHeader_t
*pStrip
= pStripVTX( pStripGroup
, nStrip
);
259 if ( pStrip
->flags
& STRIP_IS_TRILIST
)
261 indices
+= pStrip
->numIndices
;
273 //=======================================================================================================================
275 #pragma pack(push, 1)
279 // base of external vertex data stores
283 mstudio_modelvertexdata_t
;
287 // indirection to this mesh's model's vertex data
288 int unused_modelvertexdata
; // 64b - Moved to follow num_LOD_Vertexes.
290 // used for fixup calcs when culling top level lods
291 // expected number of mesh verts at desired lod
292 int numLODVertexes
[MAX_NUM_LODS
];
294 mstudio_modelvertexdata_t
*_the_death_ptr
;
296 mstudio_meshvertexdata_t
;
298 typedef struct mstudiomodel_t mstudiomodel_t
;
304 int numvertices
; // number of unique vertices/normals/texcoords
305 int vertexoffset
; // vertex mstudiovertex_t
306 int numflexes
; // vertex animation
308 // special codes for material operations
311 // a unique ordinal for this mesh
314 mstudio_meshvertexdata_t vertexdata
;
316 int unused
[6]; // remove as appropriate
321 struct mstudiomodel_t
325 float boundingradius
;
330 int numvertices
; // number of unique vertices/normals/texcoords
331 int vertexindex
; // vertex Vector
332 int tangentsindex
; // tangents Vector
340 mstudio_modelvertexdata_t vertexdata
;
342 int unused
[8]; // remove as appropriate
344 mstudiomesh_t
*studiomodel_pMesh( mstudiomodel_t
*t
, int i
)
346 return (mstudiomesh_t
*)(((char *)t
) + t
->meshindex
) + i
;
354 int modelindex
; // index into models array
355 } mstudiobodyparts_t
;
357 mstudiomodel_t
*mstudiobodyparts_pModel( mstudiobodyparts_t
*t
, int i
)
359 return (mstudiomodel_t
*)(((char *)t
) + t
->modelindex
) + i
;
365 int checksum
; // this has to be the same in the phy and vtx files to load!
368 float eyeposition
[3]; // ideal eye position
369 float illumposition
[3]; // illumination center
370 float hull_min
[3]; // ideal movement hull size
372 float view_bbmin
[3]; // clipping bounding box
375 int numbones
; // bones
377 int numbonecontrollers
; // bone controllers
378 int bonecontrollerindex
;
381 int numlocalanim
; // animations/poses
382 int localanimindex
; // animation descriptions
383 int numlocalseq
; // sequences
385 int activitylistversion
;
390 // raw textures search paths
393 // replaceable textures tables
399 // queryable attachable points
400 int numlocalattachments
;
401 int localattachmentindex
;
402 // animation node to animation node transition graph
405 int localnodenameindex
;
408 int numflexcontrollers
;
409 int flexcontrollerindex
;
416 int numlocalposeparameters
;
417 int localposeparamindex
;
418 int surfacepropindex
;
422 int numlocalikautoplaylocks
;
423 int localikautoplaylockindex
;
424 // The collision model mass that jay wanted
427 // external animations, models, etc.
428 int numincludemodels
;
429 int includemodelindex
;
430 // for demand loaded animation blocks
431 int szanimblocknameindex
;
434 int bonetablebynameindex
;
435 char constdirectionallightdot
;
437 char numAllowedRootLODs
;
439 int unused4
; // zero out if version < 47
440 int numflexcontrollerui
;
441 int flexcontrolleruiindex
;
442 float flVertAnimFixedPointScale
;
449 mstudiobodyparts_t
*studiohdr_pBodypart( studiohdr_t
*t
, int i
)
451 return (mstudiobodyparts_t
*)(((char *)t
) + t
->bodypartindex
) + i
;
469 void mdl_free( mdl_mesh_t
*m
)
475 void mdl_error( mdl_mesh_t
*m
)
483 int mdl_from_find_files( const char *mdlname
, mdl_mesh_t
*ctx
)
485 // Read entire files into memory (inline functions map memory)
488 strcpy( path
, mdlname
);
489 csr_stripext( path
);
490 strcat( path
, ".dx90.vtx" );
491 VTXFileHeader_t
*pVtxHdr
= (VTXFileHeader_t
*)valve_fs_get( path
);
500 strcpy( path
, mdlname
);
501 csr_stripext( path
);
502 strcat( path
, ".vvd" );
503 vertexFileHeader_t
*pVvdHdr
= (vertexFileHeader_t
*)valve_fs_get( path
);
513 strcpy( path
, mdlname
);
514 csr_stripext( path
);
515 strcat( path
, ".mdl" );
516 studiohdr_t
*pMdl
= (studiohdr_t
*)valve_fs_get( path
);
526 ctx
->num_indices
= vtx_count_indices( pVtxHdr
);
528 // Allocate and read indices
529 ctx
->indices
= (u16
*)csr_malloc( ctx
->num_indices
* sizeof( u16
) );
530 ctx
->num_indices
= 0;
532 for ( int bodyID
= 0; bodyID
< pMdl
->numbodyparts
; ++bodyID
)
535 VTXBodyPartHeader_t
* pVtxBodyPart
= pBodyPartVTX( pVtxHdr
, bodyID
);
536 mstudiobodyparts_t
*pBodyPart
= studiohdr_pBodypart( pMdl
, bodyID
);
538 for ( int modelID
= 0; modelID
< pBodyPart
->nummodels
; ++modelID
)
541 VTXModelHeader_t
* pVtxModel
= pModelVTX( pVtxBodyPart
, modelID
);
542 mstudiomodel_t
*pStudioModel
= mstudiobodyparts_pModel( pBodyPart
, modelID
);
545 VTXModelLODHeader_t
*pVtxLOD
= pLODVTX( pVtxModel
, nLod
);
547 for ( int nMesh
= 0; nMesh
< pStudioModel
->nummeshes
; ++nMesh
)
550 VTXMeshHeader_t
* pVtxMesh
= pMeshVTX( pVtxLOD
, nMesh
);
551 mstudiomesh_t
* pMesh
= studiomodel_pMesh( pStudioModel
, nMesh
);
553 for ( int nGroup
= 0; nGroup
< pVtxMesh
->numStripGroups
; ++nGroup
)
556 VTXStripGroupHeader_t
* pStripGroup
= pStripGroupVTX( pVtxMesh
, nGroup
);
558 for ( int nStrip
= 0; nStrip
< pStripGroup
->numStrips
; nStrip
++ )
561 VTXStripHeader_t
*pStrip
= pStripVTX( pStripGroup
, nStrip
);
563 if ( pStrip
->flags
& STRIP_IS_TRILIST
)
566 for ( int i
= 0; i
< pStrip
->numIndices
; i
++ )
568 u16 i1
= *pIndexVTX( pStripGroup
, pStrip
->indexOffset
+ i
);
569 ctx
->indices
[ ctx
->num_indices
++ ] = pVertexVTX( pStripGroup
, i1
)->origMeshVertID
+ pMesh
->vertexoffset
;
578 mstudiovertex_t
*vertexData
= GetVertexData( pVvdHdr
);
580 // Allocate vertex blob (XYZ|NRM|UV)
581 ctx
->num_vertices
= pVvdHdr
->numLodVertexes
[0];
582 ctx
->vertices
= (float *)csr_malloc( ctx
->num_vertices
* 8 * sizeof( float ) );
584 for( int i
= 0; i
< ctx
->num_vertices
; i
++ )
586 mstudiovertex_t
*vert
= vertexData
+ i
;
587 memcpy( ctx
->vertices
+ i
* 8, vert
->pos
, 8 * sizeof(float) );