From b595d489638697f479941668bf45786285bc3ade Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Tue, 30 Apr 2024 19:43:47 -0400 Subject: [PATCH] Add support for reading the color table from a material --- src/common_file_operations.rs | 48 ++++++++++++++++++++++++++++++++++- src/mtrl.rs | 33 ++++++++++++++++++------ src/stm.rs | 34 +------------------------ 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/src/common_file_operations.rs b/src/common_file_operations.rs index cd39d33..b2cb77f 100644 --- a/src/common_file_operations.rs +++ b/src/common_file_operations.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later use std::io::SeekFrom; -use binrw::{BinReaderExt, BinResult}; +use binrw::{binread, BinReaderExt, BinResult}; +use half::f16; pub(crate) fn read_bool_from + std::cmp::PartialEq>(x: T) -> bool { x == T::from(1u8) @@ -39,6 +40,51 @@ pub(crate) fn strings_parser(base_offset: u64, strings_offset: &Vec) -> Bin Ok(strings) } +fn read_half1(data: [u16; 1]) -> Half1 { + Half1 { + value: f16::from_bits(data[0]) + } +} + +#[binread] +#[derive(Debug, Default, Clone, Copy)] +#[br(map = read_half1)] +pub(crate) struct Half1 { + value: f16, +} + +fn read_half2(data: [u16; 2]) -> Half2 { + Half2 { + x: f16::from_bits(data[0]), + y: f16::from_bits(data[0]) + } +} + +#[binread] +#[derive(Debug, Default, Clone, Copy)] +#[br(map = read_half2)] +pub(crate) struct Half2 { + x: f16, + y: f16, +} + +fn read_half3(data: [u16; 3]) -> Half3 { + Half3 { + r: f16::from_bits(data[0]), + g: f16::from_bits(data[0]), + b: f16::from_bits(data[0]) + } +} + +#[binread] +#[derive(Debug, Default, Clone, Copy)] +#[br(map = read_half3)] +pub(crate) struct Half3 { + r: f16, + g: f16, + b: f16 +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/mtrl.rs b/src/mtrl.rs index fdfd717..f610734 100644 --- a/src/mtrl.rs +++ b/src/mtrl.rs @@ -6,7 +6,8 @@ use std::io::Cursor; use crate::ByteSpan; -use binrw::{binrw, BinRead}; +use binrw::{binrw, BinRead, binread}; +use crate::common_file_operations::{Half1, Half2, Half3}; #[binrw] #[derive(Debug)] @@ -42,19 +43,33 @@ struct ColorSet { index: u8, } -#[binrw] +#[binread] +#[derive(Debug)] +#[allow(dead_code)] +struct ColorTableRow { + diffuse_color: Half3, + specular_strength: Half1, + specular_color: Half3, + gloss_strength: Half1, + emissive_color: Half3, + tile_set: u16, + material_repeat: Half2, + material_skew: Half2, +} + +#[binread] #[br(import {set_count: usize})] #[derive(Debug)] #[allow(dead_code)] -struct ColorSetInfo { +struct ColorTable { #[br(count = set_count)] - data: Vec, + data: Vec, } #[binrw] #[derive(Debug)] #[allow(dead_code)] -struct ColorSetDyeInfo { +struct ColorDyeTable { #[br(count = 16)] data: Vec, } @@ -170,13 +185,15 @@ struct MaterialData { #[br(if(file_header.data_set_size > 0))] // Dawntrail doubled the amount of color sets. // The MTRL version is the same (why square enix?) so we check the data set size instead - #[br(args { set_count: if file_header.data_set_size < 2048 { 256 } else { 1024 } })] - color_set_info: Option, + #[br(args { set_count: if file_header.data_set_size < 2048 { 16 } else { 32 } })] + #[bw(ignore)] + color_set_info: Option, #[br(if(file_header.data_set_size > if file_header.data_set_size < 2048 { 512 } else { 2048 } ))] - color_set_due_info: Option, + #[bw(ignore)] + color_set_due_info: Option, header: MaterialHeader, diff --git a/src/stm.rs b/src/stm.rs index b588497..aa2a83b 100644 --- a/src/stm.rs +++ b/src/stm.rs @@ -8,6 +8,7 @@ use binrw::{binread, BinReaderExt, binrw}; use binrw::__private::assert; use binrw::BinRead; use half::f16; +use crate::common_file_operations::{Half1, Half3}; use crate::model_vertex_declarations::VertexType::Half2; /// Maximum number of elements in one row @@ -36,36 +37,6 @@ pub struct DyePack { specular_power: f32 } -pub(crate) fn read_half3(data: [u16; 3]) -> Half3 { - Half3 { - r: f16::from_bits(data[0]), - g: f16::from_bits(data[0]), - b: f16::from_bits(data[0]) - } -} - -#[binread] -#[derive(Debug, Default, Clone, Copy)] -#[br(map = read_half3)] -struct Half3 { - r: f16, - g: f16, - b: f16 -} - -pub(crate) fn read_half1(data: [u16; 1]) -> Half1 { - Half1 { - value: f16::from_bits(data[0]) - } -} - -#[binread] -#[derive(Debug, Default, Clone, Copy)] -#[br(map = read_half1)] -struct Half1 { - value: f16, -} - #[derive(Debug)] pub struct StainingTemplate { @@ -91,9 +62,6 @@ impl StainingTemplate { let new_offset = (offset + 10) as u64; - assert_eq!(std::mem::size_of::(), std::mem::size_of::()); - assert_eq!(std::mem::size_of::(), std::mem::size_of::() * 3); - let diffuse_entries = StainingTemplate::read_array::(&mut cursor, new_offset, ends[0] as usize); let specular_entries = StainingTemplate::read_array::(&mut cursor, new_offset + ends[0] as u64, ends[1] as usize - ends[0] as usize); let emissive_entries = StainingTemplate::read_array::(&mut cursor, new_offset + ends[1] as u64, ends[2] as usize - ends[1] as usize);