Model/Legacy

From owdev
Jump to: navigation, search

WIP documentation of Model format.

Disclaimer:

Some of these things are assumptions, but generally proven or marked as unknown, unreferenced or unsafe to read from or use.


General:

coordinate system is typically y-up.

scale is assumed child metric (xD) or approx footscale = value * 4. raw model (say Model!) measures.


struct header
{
	f32	desc_bbox[16];
	u32*	data_blob;
	u32*	unk_struct1;
	u64*	eof;
	u64*	bone_desc;		// ref 'nr_bones_absolute'
	u64*	bone_matrices_1;	// [4x4] row or column major (?) translation is in the last row
	u64*	bone_matrices_2;	// [4x4] row or column major (?) translation is in the last row
	u64*	bone_matrices_3;	// [4x3] or [3x4] row or column (?)
	u64*	bone_matrices_4;	// [4x3] or [3x4] row or column (?)
	u64*	bone_small_matrix;	// ref 'nr_bones_absolute' related to bone_mappingx.
	u64*	bone_ids;		// ref 'nr_bones_absolute' u32 index
	u64*	bone_names;		// ref 'nr_bones_absolute' pointers into following encoded packet
	u64*	bone_childs_list;	// ref 'nr_bones_minus1' points to 0x1E0 eoh
	u64*	bone_id_remapping;	// ref 'nr_bones_remapped'
	u64*	bone_mappingx;		// ref 'nr_bones_absolute'
	u32	magic;			// common for static models = 554B44EC
	u16	nr_bones_absolute;	// relative count of bone_matrices_1
	u16	nr_bones_rigid;		// assumed 'rigid' part of skeleton
	u16	nr_bones_physical;	// usually number of physical bones
	u16	nr_bones_remapped;	// huh?!?
	u16	nr_bone_x1;		// counts for more bone structs or indices or something else
	u16	nr_bone_x2;		// usage scenarios range from attachements
	u16	nr_bone_x3;		// to fixed bone indices for specific reasons
	u16	nr_bone_x4;		// common match is noodle_belly (?)
	u16	nr_bones_abs_minus1;
	u16	pad;
	u8	unk3[11];		// unk3
	u8	nr_attachment_points;
	u8	unk3B[4];		// unk3
	u32	unk4;
	u32	nr_input_elements;
	u32	unk5;
	u32	unk_one;		// 1.0
	f32	unk6[4];
	f32	unk7[4];
	f32	unk8[4];
	u32	unk9[4];		// 3x 0 followed by 0xFFFF7F7F
	f32	unkA[4];
	u32	unkB[4];
	u32	unkC;
	u16	nr_materials_a;
	u16	nr_materials_b;		// commonly identical to _a
	u32	unkD;
	u32	unkE;
	u8	nr_vertex_buffer_desc;	// offset 0x150
	u8	nr_index_buffer_desc;
	u8	nr_some_flags;
	u8	nr_submesh_desc;
	u32	nr_something2;
	u64*	attachment_point;	// array of nr_attachment_points
	u64*	material_lookup;	// u64 hash array of still unknown 'filesystem' specs
	u64*	submesh_desc;		// array
	u64*	vertex_buffer_desc;	// array
	u64*	index_buffer_desc;	// array
	u64*	desc4;		
	u64*	skeleton_id_desc;	// assumed. values 102 and 101 found in a mesh with lots of bones
	u64*	desc6;
	u64*	unk_struct3;
	u64*	desc8;
	u64*	phys_ref_desc;		// assumed. found in meshes with cloth physics.
	u64*	descA;
	u64*	physics_desc;		// extend unknown. default string contained is 'cloth physics'
	u64*	unk_struct1;
	u64*	descD;
	u64*	descE;
	u64*	descF;
};

struct submesh_desc			// 'drawcall' assembly info
{
	s64	index_something;	// assumed. not found often.
	u32	unk1;
	f32	unk2[10];
	u32	vertex_id_start;	// mul vertex buffer stream stride(s) to get releative offset(s).
	u16	index_id_start;
	u16	index_id_count;
	u16	nr_indices_to_draw;	// 'draw' means div 3 -> triangles to assemble.
	u16	nr_vertices_to_draw;	// 'draw' means run thru vertex shader. index relative.
	u16	bone_id_offset;
	u8	vertex_buffer_used;	// see descriptors
	u8	index_buffer_used;	// see descriptors
	u8	flags;			// see submesh_enum
	u8	material;		// see material_lookup
	u8	LOD_flags;		// bit 1 = highest LOD
	u8	value4;			// flags, formats, enums, shader relevant (?)
};

struct vertex_buffer_desc
{
	u32	nr_input_elements;
	u32	unk1;			// some binary
	u8	stride_stream1;
	u8	stride_stream2;
	u8	nr_vertex_elements_desc;
	u8	unk1;		
	u32	unk2;			// 0x00ed
	u64	effed[2];		// 0xFFed
	u64*	vertex_elements_desc;	// array
	u64*	data_stream1;		// see vertex_element_desc - points to vertex data
	u64*	data_stream2;		// see vertex_element_desc - points to texture coordinates data
};

struct vertex_element_desc		// similarity to D3D11_INPUT_ELEMENT_DESC
{
	u8	semantic_type;		// it's called semantics.
	u8	semantic_index;		// example 1st, 2nd, 3rd pair of UVs
	u8	data_format;			
	u8	stream_number;
	u16	classification;		// assumed D3D11_INPUT_CLASSIFICATION (for now)
	u16	stride_offset;
};

enum semantic_type			// semantics names can be found in DXBC files. not relevant here.
{
	POSITION	= 0,
	NORMAL		= 1,
	COLOR		= 2,		// actually unknown, just a loud guess
	TANGENT		= 3,
	BONE_INDICES	= 4,
	BONE_WEIGHT	= 5,
	UNKNOWN1	= 6,
	UNKNOWN2	= 7,
	UNKNOWN3	= 8,
	TEXCOORD	= 9,
	VERTEX_ID	= 10
};

enum data_format			// refed as DXGI_FORMAT_s. RGBA == XYZW. known format behaviours.
{
	R32G32B32_FLOAT	= 2,
	R16G16_FLOAT	= 4,
	R8G8B8A8_UINT	= 6,
	R8G8B8A8_UNORM	= 8,
	R8G8B8A8_SNORM	= 9,
	R32_UINT	= 12
};

enum submesh_enum
{
	UNK1		= 1,	// no instance found yet
	UNK2		= 2,	// no instance found yet
	GEOMETRY	= 4,	// set when it's a draw mesh?
	MATERIAL	= 8,	// set when it's a draw mesh?
	COLLISION_MESH	= 16,	// only set when it's a collision mesh
	SKINNED		= 32,	// set when there's a skeleton?
	UNK7		= 64,	// no instance found yet
	UNK8		= 128	// no instance found yet
}

struct index_buffer_desc
{
	u32	nr_indices;		// or u64 without format (?) is uncommon
	u32	format;			// i16 or i32 is guessed 0 = i16
	u64	effed;			// 0xFFed
	u64*	data_streami;		
};

struct unk_struct1
{
	u32	unk[20];
};	

struct attachment_point		// for particles?
{
	mat44	transform;
	u32	id;
	u16	unk1;
	u8	unk2;
	u8	binary_size;
	u32	parent_bone_id;         // read as hex, so it can be mapped to the parent bone
	u16	unk4;
	u16	unk5;
	u64*	unk_binary;		// binary stream following, length of binary_size
	u32	pad[2];
};

struct unk_struct3			// more or less based on weapon model. assumed collision data.
{
	u64*	data_vec3;		// point cloud looks like something
	u64*	data_vec4;		// or 2 vec2. amount calced.
	u64*	data_unk1;		// got a pattern but looks weird
	u64*	data_unk2;
	vec3	unk1;
	u32	nr_data_vec3;
	u32	nr_data_vec4;
	f32	unkn2[2];
	u32	effed1[2];
	f32	unk3[12];
	u16	effed2;
	u8	unk4[18];
};

struct bone_desc
{
	u8	flags;			// todo
	u8	nr_children;		// no. of children
	u16	ofs_entry_child_list;	// zero-based
	s16	index_parent;		// if -1 no parent
};