Difference between revisions of "VTX"

From Valve Developer Community
Jump to: navigation, search
(Rewrote the page with all missing information covered, and added extra clarification. Removed the dead links)
m (changed wording slightly)
 
(3 intermediate revisions by 2 users not shown)
Line 35: Line 35:
 
===Body array===
 
===Body array===
 
The body array is a list of <b>BodyPartHeader_t</b> objects.
 
The body array is a list of <b>BodyPartHeader_t</b> objects.
 
+
* Size: <b>numBodyParts</b>.
Size is specified by: <b>numBodyParts</b>.
+
* Location: <b>bodyPartOffset</b>.
 
+
{{note|Since this value is in the header it can be interpreted as an absolute location}}
Location is specified by <b>bodyPartOffset</b>. This is relative to the header, which is alwasy 0x0 and can therefore the offset can allways be treated as a static address.
 
  
 
==BodyPartHeader_t==
 
==BodyPartHeader_t==
Line 52: Line 51:
 
===Model array===
 
===Model array===
 
The model array is a list of <b>ModelHeader_t</b> objects.
 
The model array is a list of <b>ModelHeader_t</b> objects.
 
+
* Size: <b>numModels</b>.
Size is specified by: <b>numModels</b>.
+
* Location: <b>bodyPartOffset</b>.
 
 
Location is specified by <b>bodyPartOffset</b>. This is a relative offset, from the start of the <b>BodyPartHeader_t</b> object.
 
  
 
==ModelHeader_t==
 
==ModelHeader_t==
Line 70: Line 67:
 
===LOD Mesh Array===
 
===LOD Mesh Array===
 
The LOD mesh array is a list of <b>ModelLODHeader_t</b> objects.
 
The LOD mesh array is a list of <b>ModelLODHeader_t</b> objects.
 
+
* Size: <b>numLODS</b>.
Size is specified by: <b>numLODS</b>
+
* Location: <b>lodOffset</b>.
 
 
Location is specified by <b>lodOffset</b>. This is again a relative offset, from the start of the <b>Modelheader_t</b> object.
 
  
 
==ModelLODHeader_t==
 
==ModelLODHeader_t==
Line 90: Line 85:
 
===Mesh array===
 
===Mesh array===
 
The mesh array is a list of <b>MeshHeader_t</b> objects.
 
The mesh array is a list of <b>MeshHeader_t</b> objects.
 
+
* Size: <b>numMeshes</b>.
Size is specified by: <b>numMeshes</b>.
+
* Location: <b>meshOffset</b>.
 
 
Location is specified by <b>meshOffset</b>. Relative offset from the start of the <b>ModelLODHeader_t</b> object.
 
  
 
===Switch Point===
 
===Switch Point===
Line 110: Line 103:
  
 
===Strip Group Array===
 
===Strip Group Array===
The strip group array is a list of <b>StripHeader_t</b> objects.
+
The strip group array is a list of <b>StripGroupHeader_t</b> objects.
 
+
* Size: <b>numStripGroups</b>.
Size is specified by: <b>numStripGroups</b>
+
* Location: <b>stripGroupHeaderOffset</b>.
 
 
Location is specified by <b>stripGroupHeaderOffset</b>. Relative from <b>MeshHeader_t</b> object.
 
  
 
===Flags===
 
===Flags===
Line 131: Line 122:
 
|0x08 || STRIPGROUP_SUPPRESS_HW_MORPH
 
|0x08 || STRIPGROUP_SUPPRESS_HW_MORPH
 
|}
 
|}
 +
 +
==StripGroupHeader_t==
 +
<source lang="cpp">
 +
struct StripGroupHeader_t
 +
{
 +
// These are the arrays of all verts and indices for this mesh.  strips index into this.
 +
int numVerts;
 +
int vertOffset;
 +
 +
int numIndices;
 +
int indexOffset;
 +
 +
int numStrips;
 +
int stripOffset;
 +
 +
unsigned char flags;
 +
 +
//if you have problems with parsing try to skip 8 bytes here
 +
};
 +
</source>
 +
 +
===Vertex & Indices arrays===
 +
Indices Array - This is a set of unsigned short integers that index the position of the real vertex data in the .VVD's vertex array
 +
* Size: <b>numIndices</b>
 +
* Location: <b>indexOffset</b>
 +
 +
Vertex Array - The vertex array inside the .VTX file holds some extra information related to skinning
 +
* Size: <b>numVerts</b>
 +
* Location: <b>vertOffset</b>
 +
 +
===Strip Array===
 +
The strip array is a list of <b>StripHeader_T</b> objects
 +
* Size: <b>numStrips</b>
 +
* Location: <b>stripOffset</b>
  
 
==StripHeader_t==
 
==StripHeader_t==
Line 137: Line 162:
 
struct StripHeader_t
 
struct StripHeader_t
 
{
 
{
//Indices array
 
 
int numIndices;
 
int numIndices;
 
int indexOffset;
 
int indexOffset;
  
//Vertices array
 
 
int numVerts;     
 
int numVerts;     
 
int vertOffset;
 
int vertOffset;
Line 154: Line 177:
 
</source>
 
</source>
  
===Indices array===
+
===Indices & Vertex Groupings===
The indices array is a list of <b>unsigned short</b> indices.
+
Each group (Indices and Vertexes respectively), specify what position to read from the vertex pool, as well as the indices pool. These pools come from the parent StripGroupHeader object
 
 
Size is specified by: <b>numIndices</b>.
 
 
 
Location is specified by <b>indexOffset</b>. Relative from <b>StripHeader_t</b> object.
 
 
 
===Vertices array===
 
The vertex array is a list of <b>Vertex_t</b> objects.
 
 
 
Size is specified by: <b>numVerts</b>.
 
 
 
Location is specified by <b>vertOffset</b>. Relative from <b>StripHeader_t</b> object.
 
  
 
===Vertex_t===
 
===Vertex_t===
Line 185: Line 197:
  
 
<b>origMeshVertID</b> defines the index of this vertex that is to be read from the linked .VVD file's vertex array
 
<b>origMeshVertID</b> defines the index of this vertex that is to be read from the linked .VVD file's vertex array
 +
{{note|This value needs to be added to the total vertices read, since it is relative to the mesh and won't work as an absolute key.}}
  
 
==See also==
 
==See also==

Latest revision as of 07:20, 3 August 2020

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.

It is currently found in .sw.vtx (Software), .dx80.vtx (DirectX 8.0) .dx90.vtx (DirectX 9.0) and .xbox.vtx (XBox) flavors. Left 4 Dead and Left 4 Dead 2 originally used just .VTX files, as of the Sacrifice update for these two games they now use the .dx90.vtx for the Mac OSX and re-used the .VTX only for Portal 2.

File Structure

Header

// 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
	int checkSum;

	int numLODs; // Also specified in ModelHeader_t's and should match

	// Offset to materialReplacementList Array. one of these for each LOD, 8 in total
	int materialReplacementListOffset;

        //Defines the size and location of the body part array
	int numBodyParts;
	int bodyPartOffset;
};

This is the header structure for the current VERSION7 .vtx file

Body array

The body array is a list of BodyPartHeader_t objects.

  • Size: numBodyParts.
  • Location: bodyPartOffset.
Note.png Note: Since this value is in the header it can be interpreted as an absolute location

BodyPartHeader_t

struct BodyPartHeader_t
{
	//Model array
	int numModels;
	int modelOffset;
};

Model array

The model array is a list of ModelHeader_t objects.

  • Size: numModels.
  • Location: bodyPartOffset.

ModelHeader_t

// This maps one to one with models in the mdl file.
struct ModelHeader_t
{
	//LOD mesh array
	int numLODs;   //This is also specified in FileHeader_t
	int lodOffset;
};

LOD Mesh Array

The LOD mesh array is a list of ModelLODHeader_t objects.

  • Size: numLODS.
  • Location: lodOffset.

ModelLODHeader_t

struct ModelLODHeader_t
{
    //Mesh array
	int numMeshes;
	int meshOffset;

	float switchPoint;
};

Mesh array

The mesh array is a list of MeshHeader_t objects.

  • Size: numMeshes.
  • Location: meshOffset.

Switch Point

The point at which the engine should switch to this LOD mesh is defined by switchPoint.

MeshHeader_t

struct MeshHeader_t
{
	int numStripGroups;
	int stripGroupHeaderOffset;

	unsigned char flags;
};

Strip Group Array

The strip group array is a list of StripGroupHeader_t objects.

  • Size: numStripGroups.
  • Location: stripGroupHeaderOffset.

Flags

The unsigned char flags value can be read from this table:

Value Meaning
0x01 STRIPGROUP_IS_FLEXED
0x02 STRIPGROUP_IS_HWSKINNED
0x04 STRIPGROUP_IS_DELTA_FLEXED
0x08 STRIPGROUP_SUPPRESS_HW_MORPH

StripGroupHeader_t

struct StripGroupHeader_t
{
	// These are the arrays of all verts and indices for this mesh.  strips index into this.
	int numVerts;
	int vertOffset;

	int numIndices;
	int indexOffset;

	int numStrips;
	int stripOffset;

	unsigned char flags;

	//if you have problems with parsing try to skip 8 bytes here
};

Vertex & Indices arrays

Indices Array - This is a set of unsigned short integers that index the position of the real vertex data in the .VVD's vertex array

  • Size: numIndices
  • Location: indexOffset

Vertex Array - The vertex array inside the .VTX file holds some extra information related to skinning

  • Size: numVerts
  • Location: vertOffset

Strip Array

The strip array is a list of StripHeader_T objects

  • Size: numStrips
  • Location: stripOffset

StripHeader_t

// A strip is a piece of a stripgroup which is divided by bones 
struct StripHeader_t
{
	int numIndices;
	int indexOffset;

	int numVerts;    
	int vertOffset;

	short numBones;

	unsigned char flags;

	int numBoneStateChanges;
	int boneStateChangeOffset;
};

Indices & Vertex Groupings

Each group (Indices and Vertexes respectively), specify what position to read from the vertex pool, as well as the indices pool. These pools come from the parent StripGroupHeader object

Vertex_t

struct Vertex_t
{
	// these index into the mesh's vert[origMeshVertID]'s bones
	unsigned char boneWeightIndex[3];
	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
	char boneID[3];
};

origMeshVertID defines the index of this vertex that is to be read from the linked .VVD file's vertex array

Note.png Note: This value needs to be added to the total vertices read, since it is relative to the mesh and won't work as an absolute key.

See also