Model3 3D Model Format - Palm-Studios/sh2_source GitHub Wiki

The Model3 format (or so it is referred to in the source of SILENT HILL 2) is the model file format used throughout SILENT HILL 2 and 3. The file type is a binary format that contains data such as the skeleton, textures etcetera. Each file has the extension .mdl.

The first block of data is the Model's file header. It is described with the following struct:

IMPORTANT NOTE! The following are revision 3 model structures. Revision 4 (the PC version) may have slightly different data (the Part structure, for example, is different)

struct sh2gfw_Model_Header
{
	unsigned char NoTextureID;
	unsigned char padc[3];
	unsigned int chara_id;
	unsigned int texnum;
	unsigned int toTexHead_offset;
	unsigned int toClutsHead_offset;
	unsigned int toModel_offset;
        unsigned int toKg1_offset;
	unsigned int pad;
	void* pTexMAN[8];
};

The offsets in this struct are absolute.

These fields have the following meaning:

Field Description
NoTextureID No Texture flag(??)
padc[3] Pad bytes (always 0)
chara_id Character ID number (used in engine to identify a character/SubCharacter). This looks like it could also be a "type" to determine if it's a drama model or not.
texnum Number of textures stored in this .mdl file
toTexHead_offset Offset to first texture (aka text block)
toClutsHead_offset Offset to cluster (animation?) data
toModel_offset Offset to model header
toKg1_offset Offset to embedded KG1 file header
pads[2] Padding words
void* pTexMAN[8] Data for texman(???)

The next struct contains information about the model data itself:

struct Model
{
	unsigned int id;
	unsigned int revision;
	unsigned int initial_matrices_offset;
	unsigned int n_skeletons;
	unsigned int skeleton_structure_offset;
	unsigned int n_skeleton_pairs;
	unsigned int skeleton_pairs_offset;
	unsigned int default_pcms_offset;
	unsigned int n_vu1_parts;
	unsigned int vu1_parts_offset;
	unsigned int n_vu0_parts;
	unsigned int vu0_parts_offset;
	unsigned int n_texture_blocks;
	unsigned int texture_blocks_offset;
	unsigned int n_text_poses;
	unsigned int text_poses_offset;
	unsigned int text_pos_params_offset;
	unsigned int n_cluster_nodes;
	unsigned int cluster_nodes_offset;
	unsigned int n_clusters;
	unsigned int clusters_offset;
	unsigned int n_func_data;
	unsigned int func_data_offset;
	unsigned int hit_offset;
	unsigned int box_offset;
	unsigned int flag;
	unsigned int relative_matrices_offset;
	unsigned int relative_transes_offset;
	unsigned int reserved_1c;
	unsigned int reserved_1d;
	unsigned int reserved_1e;
	unsigned int reserved_1f;
};

The offsets are relative to the beginning of this structure.

These fields have the following meaning:

Field Description
id Magic Number. Always 0xFFFF0003
revision Version number of this .mdl. 3 on PS2, 4 on PC
initial_matrices_offset Offset to the initi
n_skeletons Number of skeletons contained in this file. It is probably more appropriate to call this the number of bones.
skeleton_structure_offset Offset to the root shSkeleton structure
n_skeleton_pairs Number of skeletons pairs (???)
skeleton_pairs_offset Offset to the skeleton pairs
default_pcms_offset ?
n_vu1_parts Number of VU1 parts (sent to the VU1 on the PS2)
vu1_parts_offset Offset to beginning of VU1 part structures (see below)
n_vu0_parts Number of VU1 parts (sent to the VU1 on the PS2)
vu0_parts_offset Offset to beginning of VU1 part structures (see below)
n_texture_blocks Number of textures contained within this .mdl
texture_blocks_offset Offset to texture data
n_text_poses Pose data (???)
text_poses_offset Offset to pose data (???)
text_pos_params_offset
n_cluster_nodes
cluster_nodes_offset
n_clusters
clusters_offset
n_func_data
func_data_offset
hit_offset Offset to hitbox (combat hitbox?)
box_offset Offset to hitbox (movement hitbox?)
flag No idea. Some kind of information related to model in game?
relative_matrices_offset
relative_transes_offset;
reserved_1c; Reserved for future use
reserved_1d; Reserved for future use
reserved_1e; Reserved for future use

The next structure of interest is a Part header. This describes a packet of data that, on the PlayStation 2, would be sent to the VU0. The format of the actual data itself (which I assume is vertex data) is currently unknown as of now.

The structure is as follows:

struct Part
{
	unsigned int size;
	unsigned int type;
	unsigned int packet_offset;
	unsigned int packet_qwc;
	unsigned int xtop;
	unsigned int n_cluster_data;
	unsigned int cluster_data_offset;
	unsigned int n_skeletons;
	unsigned int skeletons_offset;
	unsigned int n_skeleton_pairs;
	unsigned int skeleton_pairs_offset;
	unsigned int data_skeletons_offset;
	unsigned int data_skeleton_pairs_offset;
	unsigned int n_textures;
	unsigned int text_pos_indices_offset;
	unsigned int texture_params_offset;
	unsigned char shading_type;
	unsigned char specular_pos;
	unsigned char equipment_id;
	unsigned char hoge;
	unsigned char backclip;
	unsigned char envmap_param;
	unsigned char reserved[2];
	float phong_param_a;
	float phong_param_b;
	float blinn_param;
	unsigned int padding[3];
	float diffuse[4];
	float ambient[4];
	float specular[4];
};
Field Description
size Size of the this packet, including header.
type
packet_offset
packet_qwc
xtop
n_cluster_data
cluster_data_offset
n_skeletons
skeletons_offset
n_skeleton_pairs
skeleton_pairs_offset
data_skeletons_offset
data_skeleton_pairs_offset
n_textures
text_pos_indices_offset
texture_params_offset
shading_type
specular_pos
equipment_id
hoge
backclip
envmap_param
reserved[2]
phong_param_a
phong_param_b
blinn_param
padding[3]
diffuse[4]
ambient[4]
specular[4]