MDL: Difference between revisions
mNo edit summary |
m (more header data) |
||
Line 13: | Line 13: | ||
// Typically "my_model.mdl" will have an internal name of "my_model" | // Typically "my_model.mdl" will have an internal name of "my_model" | ||
int dataLength; // ?? | int dataLength; // ?? | ||
// A vector is 12 bytes, three 4-byte float-values in a row. | // A vector is 12 bytes, three 4-byte float-values in a row. | ||
Vector eyeposition; // Position of player viewpoint relative to model origin | Vector eyeposition; // Position of player viewpoint relative to model origin | ||
Line 21: | Line 21: | ||
Vector view_bbmin; | Vector view_bbmin; | ||
Vector view_bbmax; | Vector view_bbmax; | ||
int flags; // ?? | int flags; // ?? | ||
/* | /* | ||
* After this point, the header contains many references to offsets | * After this point, the header contains many references to offsets | ||
Line 32: | Line 32: | ||
* Note that indexes/counts are not always paired and ordered consistently. | * Note that indexes/counts are not always paired and ordered consistently. | ||
*/ | */ | ||
// mstudiobone_t | // mstudiobone_t | ||
int bone_count; // Number of data sections (of type mstudiobone_t) | int bone_count; // Number of data sections (of type mstudiobone_t) | ||
int bone_offset; // Offset of first data section | int bone_offset; // Offset of first data section | ||
// mstudiobonecontroller_t | // mstudiobonecontroller_t | ||
int bonecontroller_count; | int bonecontroller_count; | ||
int bonecontroller_offset; | int bonecontroller_offset; | ||
// mstudiohitboxset_t | // mstudiohitboxset_t | ||
int hitbox_count; | int hitbox_count; | ||
int hitbox_offset; | int hitbox_offset; | ||
// mstudioanimdesc_t | // mstudioanimdesc_t | ||
int localanim_count; | int localanim_count; | ||
int localanim_offset; | int localanim_offset; | ||
// mstudioseqdesc_t | // mstudioseqdesc_t | ||
int localseq_count; | int localseq_count; | ||
int localseq_offset; | int localseq_offset; | ||
int activitylistversion; // ?? | int activitylistversion; // ?? | ||
int eventsindexed; // ?? | int eventsindexed; // ?? | ||
// VMT texture filenames | // VMT texture filenames | ||
// (A series of null-terminated strings) | // (A series of null-terminated strings) | ||
int texture_count; | int texture_count; | ||
int texture_offset; | int texture_offset; | ||
// Relative paths to search for textures | // Relative paths to search for textures | ||
// (A series of null-terminated strings) | // (A series of null-terminated strings) | ||
int texturedir_count; | int texturedir_count; | ||
int texturedir_offset; | int texturedir_offset; | ||
// Skin family information for replaceable textures | // Skin family information for replaceable textures | ||
int skinreference_count; | int skinreference_count; | ||
int skinrfamily_count; | int skinrfamily_count; | ||
int skinreference_index; | int skinreference_index; | ||
// mstudiobodyparts_t | // mstudiobodyparts_t | ||
int bodypart_count; | int bodypart_count; | ||
int bodypart_offset; | int bodypart_offset; | ||
// Local attachment points | // Local attachment points | ||
// mstudioattachment_t | // mstudioattachment_t | ||
int attachment_count; | int attachment_count; | ||
int attachment_offset; | int attachment_offset; | ||
// Node values appear to be single bytes, while their names are null-terminated strings. | // Node values appear to be single bytes, while their names are null-terminated strings. | ||
int localnode_count; | int localnode_count; | ||
int localnode_index; | int localnode_index; | ||
int localnode_name_index; | int localnode_name_index; | ||
// mstudioflexdesc_t | // mstudioflexdesc_t | ||
int flexdesc_count; | int flexdesc_count; | ||
int flexdesc_index; | int flexdesc_index; | ||
// mstudioflexcontroller_t | // mstudioflexcontroller_t | ||
int flexcontroller_count; | int flexcontroller_count; | ||
int flexcontroller_index; | int flexcontroller_index; | ||
// mstudioflexrule_t | // mstudioflexrule_t | ||
int flexrules_count; | int flexrules_count; | ||
int flexrules_index; | int flexrules_index; | ||
// IK probably referse to inverse kinematics | // IK probably referse to inverse kinematics | ||
// mstudioikchain_t | // mstudioikchain_t | ||
int ikchain_count; | int ikchain_count; | ||
int ikchain_index; | int ikchain_index; | ||
// Information about any "mouth" on the model for speech animation | // Information about any "mouth" on the model for speech animation | ||
// More than one sounds pretty creepy. | // More than one sounds pretty creepy. | ||
Line 107: | Line 107: | ||
int mouths_count; | int mouths_count; | ||
int mouths_index; | int mouths_index; | ||
// mstudioposeparamdesc_t | // mstudioposeparamdesc_t | ||
int localposeparam_count; | int localposeparam_count; | ||
int localposeparam_index; | int localposeparam_index; | ||
/* | /* | ||
* For anyone trying to follow along, as of this writing, | * For anyone trying to follow along, as of this writing, | ||
Line 117: | Line 117: | ||
* from the start of the file. | * from the start of the file. | ||
*/ | */ | ||
// Surface property value (single null-terminated string) | // Surface property value (single null-terminated string) | ||
int surfaceprop_index; | int surfaceprop_index; | ||
// Unusual: In this one index comes first, then count. | // Unusual: In this one index comes first, then count. | ||
// Key-value data is a series of strings. If you can't find | // Key-value data is a series of strings. If you can't find | ||
Line 126: | Line 126: | ||
int keyvalue_index; | int keyvalue_index; | ||
int keyvalue_count; | int keyvalue_count; | ||
// More inverse-kinematics | // More inverse-kinematics | ||
// mstudioiklock_t | // mstudioiklock_t | ||
int iklock_count; | int iklock_count; | ||
int iklock_index; | int iklock_index; | ||
float mass; // Mass of object (4-bytes) | float mass; // Mass of object (4-bytes) | ||
int contents; // ?? | int contents; // ?? | ||
// Other models can be referenced for re-used sequences and animations | // Other models can be referenced for re-used sequences and animations | ||
// (See also: The $includemodel QC option.) | // (See also: The $includemodel QC option.) | ||
// mstudiomodelgroup_t | // mstudiomodelgroup_t | ||
int includemodel_count; | int includemodel_count; | ||
int includemodel_index | int includemodel_index | ||
// | int virtualModel; // Placeholder for mutable-void* | ||
// mstudioanimblock_t | |||
int animblocks_name_index; | |||
int animblocks_count; | |||
int animblocks_index; | |||
int animblockModel; // Placeholder for mutable-void* | |||
// Points to a series of bytes? | |||
int bonetablename_index; | |||
int vertex_base; // Placeholder for void* | |||
int offset_base; // Placeholder for void* | |||
// Used with $constantdirectionallight from the QC | |||
// Model should have flag #13 set if enabled | |||
byte directionaldotproduct; | |||
byte rootLod; // Preferred rather than clamped | |||
// 0 means any allowed, N means Lod 0 -> (N-1) | |||
byte numAllowedRootLods; | |||
byte unused; // ?? | |||
int unused; // ?? | |||
// mstudioflexcontrollerui_t | |||
int flexcontrollerui_count; | |||
int flexcontrollerui_index; | |||
} | } | ||
</source> | </source> |
Revision as of 20:16, 21 August 2010
MDL is the extension for Source's proprietary model format. It defines the structure of the model along with animation, bounding box, hit box, material, mesh and LOD information. It does not, however, contain all the information needed for the model. Additional data is stored in PHY, ANI, VTX and VVD files, and sometimes, usually for shared animations, other .mdl files.
File format
Some details of the file format may be gleaned from the source code in Valve's studio.h
, specifically the struct studiohdr_t
. The early header defines a series of offsets and lengths for various sub-sections within the file, along with some key scalar information. The MDL also contains the names of materials (VMT) which are used as the numerically-defined swappable skins.
Main header
struct studiohdr_t
{
int id; // Model format ID, such as "IDST" (0x49 0x44 0x53 0x54)
int version; // Format version number, such as 48 (0x30,0x00,0x00,0x00)
char[64] name; // The internal name of the model, padding with null bytes.
// Typically "my_model.mdl" will have an internal name of "my_model"
int dataLength; // ??
// A vector is 12 bytes, three 4-byte float-values in a row.
Vector eyeposition; // Position of player viewpoint relative to model origin
Vector illumposition; // ?? Presumably the point used for lighting when per-vertex lighting is not enabled.
Vector hull_min; // Corner of model hull box with the least X/Y/Z values
Vector hull_max; // Opposite corner of model hull box
Vector view_bbmin;
Vector view_bbmax;
int flags; // ??
/*
* After this point, the header contains many references to offsets
* within the MDL file and the number of items at those offsets.
*
* Offsets are from the very beginning of the file.
*
* Note that indexes/counts are not always paired and ordered consistently.
*/
// mstudiobone_t
int bone_count; // Number of data sections (of type mstudiobone_t)
int bone_offset; // Offset of first data section
// mstudiobonecontroller_t
int bonecontroller_count;
int bonecontroller_offset;
// mstudiohitboxset_t
int hitbox_count;
int hitbox_offset;
// mstudioanimdesc_t
int localanim_count;
int localanim_offset;
// mstudioseqdesc_t
int localseq_count;
int localseq_offset;
int activitylistversion; // ??
int eventsindexed; // ??
// VMT texture filenames
// (A series of null-terminated strings)
int texture_count;
int texture_offset;
// Relative paths to search for textures
// (A series of null-terminated strings)
int texturedir_count;
int texturedir_offset;
// Skin family information for replaceable textures
int skinreference_count;
int skinrfamily_count;
int skinreference_index;
// mstudiobodyparts_t
int bodypart_count;
int bodypart_offset;
// Local attachment points
// mstudioattachment_t
int attachment_count;
int attachment_offset;
// Node values appear to be single bytes, while their names are null-terminated strings.
int localnode_count;
int localnode_index;
int localnode_name_index;
// mstudioflexdesc_t
int flexdesc_count;
int flexdesc_index;
// mstudioflexcontroller_t
int flexcontroller_count;
int flexcontroller_index;
// mstudioflexrule_t
int flexrules_count;
int flexrules_index;
// IK probably referse to inverse kinematics
// mstudioikchain_t
int ikchain_count;
int ikchain_index;
// Information about any "mouth" on the model for speech animation
// More than one sounds pretty creepy.
// mstudiomouth_t
int mouths_count;
int mouths_index;
// mstudioposeparamdesc_t
int localposeparam_count;
int localposeparam_index;
/*
* For anyone trying to follow along, as of this writing,
* the next "surfaceprop_index" value is at position 0x0134 (308)
* from the start of the file.
*/
// Surface property value (single null-terminated string)
int surfaceprop_index;
// Unusual: In this one index comes first, then count.
// Key-value data is a series of strings. If you can't find
// what you're interested in, check the associated PHY file as well.
int keyvalue_index;
int keyvalue_count;
// More inverse-kinematics
// mstudioiklock_t
int iklock_count;
int iklock_index;
float mass; // Mass of object (4-bytes)
int contents; // ??
// Other models can be referenced for re-used sequences and animations
// (See also: The $includemodel QC option.)
// mstudiomodelgroup_t
int includemodel_count;
int includemodel_index
int virtualModel; // Placeholder for mutable-void*
// mstudioanimblock_t
int animblocks_name_index;
int animblocks_count;
int animblocks_index;
int animblockModel; // Placeholder for mutable-void*
// Points to a series of bytes?
int bonetablename_index;
int vertex_base; // Placeholder for void*
int offset_base; // Placeholder for void*
// Used with $constantdirectionallight from the QC
// Model should have flag #13 set if enabled
byte directionaldotproduct;
byte rootLod; // Preferred rather than clamped
// 0 means any allowed, N means Lod 0 -> (N-1)
byte numAllowedRootLods;
byte unused; // ??
int unused; // ??
// mstudioflexcontrollerui_t
int flexcontrollerui_count;
int flexcontrollerui_index;
}