Vvd (Where the vertices are)¶
- class valvemdl.Vvd(path=None)[source]¶
Contains the data from a vvd file.
An mdl carries no vertex positions; they all live here, in one flat pool shared by every mesh in the model. The header is parsed when the file is opened; the pools are large, so they are parsed on first access and cached.
The pools are stored exactly as they sit on disk, which for a model with fixups means LOD-sorted rather than mesh-sorted.
mesh_vertices()replays the fixups to hand back the mesh order thatmstudiomodel_t.vertexindexexpects. Keeping the raw order is what lets a vvd be written back byte for byte.- __init__(path=None)[source]¶
Creates an empty instance of Vvd.
- Parameters:
path (str, optional) – A path to an existing vvd file.
- header¶
- Type:
(construct.Container) - The parsed vertexFileHeader_t.
- property vertices¶
The vertex pool, in the order it is stored.
That order is LOD-sorted when
header.numFixupsis non-zero. Usemesh_vertices()for the order a mesh indexes.- Type:
(list[construct.Container]) -
numLODVertexes[0]vertices.
- property tangents¶
The tangent pool, parallel to
vertices.Tangents are kept in their own pool rather than inside the vertex, which is what holds
mstudiovertex_tat 48 bytes. Empty whentangentDataStartis 0.- Type:
(list[construct.Container]) - One
Vector4Dper vertex.
- property fixups¶
The fixup table.
Empty unless the pool is LOD-sorted. Each entry names a run of the pool and the LOD it belongs to; replaying them rebuilds mesh order.
- Type:
(list[construct.Container]) -
numFixupsfixups.
- mesh_vertices(root_lod=0)[source]¶
The vertices in mesh order, for a given root LOD.
When the pool is LOD-sorted (
numFixupsnon-zero), a mesh’svertexoffsetindexes an order that only exists once the fixup table has been replayed. This does that, followingStudio_LoadVertexes: each fixup at or below the requested LOD copies a run of the stored pool into the next free slot, and the runs land consecutively.With no fixups the pool is already in mesh order and this returns it unchanged.
- mesh_tangents(root_lod=0)[source]¶
The tangents in mesh order, for a given root LOD.
Tangents run parallel to vertices, so they take the identical fixup replay – reordering one without the other would pair each vertex with the wrong tangent.
- Parameters:
root_lod (int, optional) – The most detailed LOD to include; 0 is full detail.
- Returns:
The tangents, in the same order as
mesh_vertices().- Return type:
list[construct.Container]
- validate()[source]¶
Checks the vvd’s internal invariants.
Like
Mdl.validatethis reports rather than raises: a vvd that fails one of these is the interesting one. It is deliberately cheap – every check reads the header and the small fixup table, never the vertex pool – so the corpus sweep can run it on every file without parsing a quarter megabyte of vertices each time.
- save(destination=None)[source]¶
Writes the vvd back out, rebuilt from its pools.
- Parameters:
destination (str, optional) – Where to write. Overwrites the original when not given.
- coverage()[source]¶
How much of the vvd ValveMDL can account for.
A vvd has no compressed regions, so a sound one comes back essentially all
struct– every byte regenerated from the object graph, none merely copied. SeeMdl.coverage.- Returns:
Byte counts, plus
differ: bytes the rebuild got wrong.- Return type: