VTX: Difference between revisions
m (→Data Structure: Style update) |
(add header structure (and reference to header file)) |
||
| Line 2: | Line 2: | ||
[[VTX]] is the extension for Source's proprietary mesh strip format. It stores hardware optimized material, skinning and triangle strip/fan information for each [[LOD]] of each mesh in the [[MDL]]. Currently it is found in .sw.vtx (Software), .dx80.vtx (DirectX 8.0) .dx90.vtx (DirectX 9.0) and .xbox.vtx (XBox) flavours. | [[VTX]] is the extension for Source's proprietary mesh strip format. It stores hardware optimized material, skinning and triangle strip/fan information for each [[LOD]] of each mesh in the [[MDL]]. Currently it is found in .sw.vtx (Software), .dx80.vtx (DirectX 8.0) .dx90.vtx (DirectX 9.0) and .xbox.vtx (XBox) flavours. | ||
==Header== | |||
#define OPTIMIZED_MODEL_FILE_VERSION 7 | |||
// this structure is in <mod folder>/src/public/optimize.h | |||
struct FileHeader_t | |||
{ | |||
// file version as defined by OPTIMIZED_MODEL_FILE_VERSION (currently 7) | |||
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 | |||
long checkSum; | |||
int numLODs; // garymcthack - this is also specified in ModelHeader_t and should match | |||
// this is an offset to an array of 8 MaterialReplacementListHeader_t's | |||
// (one for each LOD) | |||
int materialReplacementListOffset; | |||
int numBodyParts; | |||
int bodyPartOffset; // offset to an array of BodyPartHeader_t's | |||
}; | |||
==Data Structure== | ==Data Structure== | ||
| Line 29: | Line 57: | ||
|24 || byte || 1 || Unknown | |24 || byte || 1 || Unknown | ||
|} | |} | ||
{{Note|All offsets are calculated from the position of the start of the block.}} | {{Note|All offsets are calculated from the position of the start of the block.}} | ||
Revision as of 03:59, 16 July 2011
VTX is the extension for Source's proprietary mesh strip format. It stores hardware optimized material, skinning and triangle strip/fan information for each LOD of each mesh in the MDL. Currently it is found in .sw.vtx (Software), .dx80.vtx (DirectX 8.0) .dx90.vtx (DirectX 9.0) and .xbox.vtx (XBox) flavours.
Header
#define OPTIMIZED_MODEL_FILE_VERSION 7
// this structure is in <mod folder>/src/public/optimize.h
struct FileHeader_t
{
// file version as defined by OPTIMIZED_MODEL_FILE_VERSION (currently 7)
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
long checkSum;
int numLODs; // garymcthack - this is also specified in ModelHeader_t and should match
// this is an offset to an array of 8 MaterialReplacementListHeader_t's
// (one for each LOD)
int materialReplacementListOffset;
int numBodyParts;
int bodyPartOffset; // offset to an array of BodyPartHeader_t's
};
Data Structure
Data is read through a series of offsets which vary depending on how many textures the model uses, bodygroups, submodels and LoD. Each group of offsets will lead to a 25 byte block that contains all the face/triangle information to draw the mesh. For example, if the model has 3 LoD levels and the mesh uses 2 textures per mesh then there will be 6 separate mesh references.
The 25 byte block contains the following data:
| Offset | Datatype | Size (bytes) | Description |
|---|---|---|---|
| 0 | uInt32 | 4 | Number of vertexes |
| 4 | uInt32 | 4 | Offset to vertex number table |
| 8 | uInt32 | 4 | Number of vertexes to draw faces |
| 12 | uInt32 | 4 | Offset to sequence to draw faces |
| 16 | uInt32 | 4 | Unknown offset reference (possibly related to vertex faces) |
| 20 | uInt32 | 4 | Offset to (unknown) reference |
| 24 | byte | 1 | Unknown |
Vertex Number Table
This offset will lead to a table containing 9 byte blocks which contain the ID of the vert from the VVD file. The first 4 bytes are unknown but are usually 00 01 02 00 although can be different. The next 2 bytes contain the vert number. The remaining 3 bytes are unknown (maybe LoD related). This data needs to be stored into an array with the key starting at 0 to be read correctly.
Vertex Sequence
This offset will lead to a table containing 2 byte blocks which contain the order of verts to draw the faces correctly. The 16-bit int contains the array key.
Face Draw Order
The draw sequence can be constructed with the following statement done using PHP.
//$vert_seq contains the 16-bit int keys.
//$vert_data contains the 16-bit int vert number extracted from the 9 byte block.
//$faces contains the sorted vert numbers to draw the faces.
foreach($vert_seq as $vid)
{
array_push($faces, $vert_data[$vid]);
}
The array $faces now contains the keys of the vertexes to be read from the VVD data assuming it is also stored in an array.
Decompile Example Script
Here is a link to a PHP script that will decompile a model can convert the reference mesh to SMD plain text. It will also partially re-construct a QC. It is not complete and does not work correctly on models with bodygroups, submodels and/or LoD. This script will only run on a Linux PHP server but the code can be modified to work on a Windows PHP server. Recommended for advanced users with programming/scripting knowledge only.