From 774740c470e666917e2bca84b9e34e7b0f43fdf5 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Wed, 17 Apr 2024 21:26:50 -0400 Subject: [PATCH] Remove temporary padding "fixes" for Dawntrail models According to https://github.com/TexTools/xivModdingFramework/pull/60 the bone table structure changed. Now the correct bone table is loaded for Dawntrail. --- src/model.rs | 51 ++++++++++++++++++++++++++++-------- src/model_file_operations.rs | 4 +++ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/model.rs b/src/model.rs index 8d44355..625d60e 100755 --- a/src/model.rs +++ b/src/model.rs @@ -206,6 +206,22 @@ struct BoneTable { bone_count: u8, } +#[binrw] +#[derive(Debug, Clone, PartialEq)] +#[allow(dead_code)] +struct BoneTableV2 { + #[br(pad_before = 2)] + bone_count: u16, + + #[br(count = bone_count)] + bone_indices: Vec, + + // align to 4 bytes + // TODO: use br align_to? + #[br(if(bone_count % 2 == 0))] + padding: u16 +} + #[binrw] #[derive(Debug, Clone, PartialEq)] #[allow(dead_code)] @@ -301,8 +317,13 @@ struct ModelData { bone_name_offsets: Vec, #[br(count = header.bone_table_count)] + #[br(if(file_header.version <= 0x1000005))] bone_tables: Vec, + #[br(count = header.bone_table_count)] + #[br(if(file_header.version >= 0x1000005))] + bone_tables_v2: Vec, + #[br(count = header.shape_count)] shapes: Vec, @@ -312,12 +333,7 @@ struct ModelData { #[br(count = header.shape_value_count)] shape_values: Vec, - // TODO: Dawntrail mysteries - #[br(if(file_header.version >= 0x01000006))] - #[br(count = 24)] - _padding1: Vec, - - submesh_bone_map_size: u32, + submesh_bone_map_size: u16, #[br(count = submesh_bone_map_size / 2)] submesh_bone_map: Vec, @@ -326,11 +342,6 @@ struct ModelData { #[br(count = padding_amount)] unknown_padding: Vec, - // TODO: Dawntrail mysteries - #[br(if(file_header.version >= 0x01000006))] - #[br(count = 385)] - _padding2: Vec, - bounding_box: BoundingBox, model_bounding_box: BoundingBox, water_bounding_box: BoundingBox, @@ -528,6 +539,15 @@ impl MDL { f32::from(bytes[3]) ]; } + VertexType::UnsignedShort4 => { + let bytes = MDL::read_unsigned_short4(&mut cursor).unwrap(); + vertices[k as usize].bone_weight = [ + f32::from(bytes[0]), + f32::from(bytes[1]), + f32::from(bytes[2]), + f32::from(bytes[3]) + ]; + } _ => { panic!("Unexpected vertex type for blendweight: {:#?}", element.vertex_type); } @@ -538,6 +558,15 @@ impl MDL { VertexType::Byte4 => { vertices[k as usize].bone_id = MDL::read_byte4(&mut cursor).unwrap(); } + VertexType::UnsignedShort4 => { + let shorts = MDL::read_unsigned_short4(&mut cursor).unwrap(); + vertices[k as usize].bone_id = [ + shorts[0] as u8, + shorts[1] as u8, + shorts[2] as u8, + shorts[3] as u8 + ]; + } _ => { panic!("Unexpected vertex type for blendindice: {:#?}", element.vertex_type); } diff --git a/src/model_file_operations.rs b/src/model_file_operations.rs index a3ce043..16eda4c 100644 --- a/src/model_file_operations.rs +++ b/src/model_file_operations.rs @@ -99,6 +99,10 @@ impl MDL { cursor.write_le::<[f32; 4]>(vec) } + pub(crate) fn read_unsigned_short4(cursor: &mut Cursor) -> BinResult<[u16; 4]> { + cursor.read_le::<[u16; 4]>() + } + pub(crate) fn pad_slice(small_slice: &[f32; N], fill: f32) -> [f32; 4] { let mut bigger_slice: [f32; 4] = [fill, fill, fill, fill]; bigger_slice[..N].copy_from_slice(&small_slice[..N]);