Introduction
The Source engine’s studio model is the format Valve used for Half-Life 2 and the games built on
the Source engine. It keeps the idea of the Half-Life studio
model (a skeleton of bones, meshes attached to it, animation sequences, hit boxes and
attachment points) but it is a different layout, and the vertices and triangles are no longer
inside the .mdl. The file starts with IDST like its predecessor, and the
version that follows is 44 to 49 instead of 10.
Models are compiled by Valve’s studiomdl tool from source files such as
SMD meshes and animations.
Structure
A Source model is a set of files that share one name and one checksum. The
.mdl holds the header, the skeleton, hit boxes, attachments, sequences, animation,
textures, body parts and the description of every mesh. The vertices and tangents are in a
.vvd file, and the triangle lists, split by level of detail and by bone, are in a
.vtx file. A physics description goes in a .phy file and demand-loaded
animation in a .ani file.
All numbers are little-endian. The header (studiohdr_t) is 408 bytes and gives a
count and a byte offset for each table. Almost every record holds further byte offsets (named
…index) that are relative to the record itself, so a record can be read wherever it
sits, and strings are zero-terminated and reached the same way. The checksum in the
header must be the same in the .vvd, .vtx and .phy files,
or the model does not load.
Offsets and sizes on these pages are not printed in Valve’s header. They are added up from the
declared field types for the 32-bit layout: 4-byte int and float,
12-byte Vector, 16-byte Quaternion and 48-byte matrix3x4_t.
For studiohdr_t the 64-bit build keeps the same layout by using
int placeholders for its runtime pointers.
Versions
The header file defines STUDIO_VERSION 48, and the table below is that version. What
the file says about the others:
- Before 46: some animation index data is incompatible. An
mstudioanimdesc_twhosesectionframesis not 0 (an old.anifile using sections, “v45 only”) cannot be used. - Before 47:
unused4in the header held zero-frame cache data, andzeroframeindexandzeroframespanin each animation were not valid. - Version 47:
zeroframeindexis not honoured; the converter clears it. - The comment on
mstudioeyeball_t::m_bNonFACSsays it was “never used before version 44”. - Version 49 is not mentioned in the file at all.
In this reference
- Header –
studiohdr_t,studiohdr2_t, the header flags and the limits - Skeleton – bones, bone flags, procedural bones, bone controllers, hit boxes, attachments, IK chains and the extra bone tables
- Sequences and animation – animations, sequences, events, layers, movements and the per-bone animation chain
- Textures, meshes and flexes – textures and skins, body parts, models, meshes, eyeballs, flex controllers and rules, and vertex animation
- Vertex and strip files – the
.vvdvertex file and the.vtxtriangle file
Not described
The pages follow studio.h and optimize.h in Valve’s Source SDK 2013 and nothing
else. The explorer has no viewer for this variant, so a dropped file shows as bytes.
Known, not yet covered
- Reference: version 49. The SDK header defines version 48 and does not mention 49, so what changed is not documented here.
- Reference: the exact bit layouts of
Vector48,Quaternion48,Quaternion64andfloat16, and the run-length coding of the animation value stream (mstudioanimvalue_t). They are used by the header but defined elsewhere in the SDK. See Sequences and animation. - Reference: how the vertex-animation records (
mstudiovertanim_t) are applied: the meaning ofspeedandside, and the 16-bit float form of the deltas. The record layouts are on Textures, meshes and flexes. - Reference: the
.phyphysics file. The header names it and requires its checksum to match, but its layout is not instudio.horoptimize.h. - Reference: how the
.vvdfixup records are applied to rebuild mesh order and drop culled levels of detail. The 12-byte record is on Vertex and strip files; the loader code is not in the header. - Reference: the animation block (
.ani) file. The header gives the block table and the block records, but not the file’s own layout. - Reference: the runtime structures at the end of
studio.h(virtualmodel_t,thinModelVertices_tand the hardware-data records) are memory-only and not described. - Viewer: there is no MDL plugin for this variant.
Variants
- Quake model (IDPO) – Quake’s animated model: palette skins inside the file and whole-frame animation
- Source engine model – Valve’s studio model for Source, versions 44 to 49, with vertex and strip files
- Studio model (IDST) – Valve’s skeletal model for Half-Life: bones, sequences and hit boxes
Links
Developers
- Source SDK 2013 – Valve’s engine headers and tools, including
studiomdl(C++) - Assimp – library that imports dozens of 3D formats, MDL among them (C++)
Reference
- studio.h – the SDK header that defines the model structures (version 48)
- optimize.h – the SDK header that defines the
.vtxfile