1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-06-06 14:47:46 +00:00

Add support for reading the color table from a material

This commit is contained in:
Joshua Goins 2024-04-30 19:43:47 -04:00
parent c4e9697faa
commit b595d48963
3 changed files with 73 additions and 42 deletions

View file

@ -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<T: std::convert::From<u8> + 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<u16>) -> 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::*;

View file

@ -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<u16>,
data: Vec<ColorTableRow>,
}
#[binrw]
#[derive(Debug)]
#[allow(dead_code)]
struct ColorSetDyeInfo {
struct ColorDyeTable {
#[br(count = 16)]
data: Vec<u16>,
}
@ -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<ColorSetInfo>,
#[br(args { set_count: if file_header.data_set_size < 2048 { 16 } else { 32 } })]
#[bw(ignore)]
color_set_info: Option<ColorTable>,
#[br(if(file_header.data_set_size >
if file_header.data_set_size < 2048 { 512 } else { 2048 }
))]
color_set_due_info: Option<ColorSetDyeInfo>,
#[bw(ignore)]
color_set_due_info: Option<ColorDyeTable>,
header: MaterialHeader,

View file

@ -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::<Half1>(), std::mem::size_of::<f16>());
assert_eq!(std::mem::size_of::<Half3>(), std::mem::size_of::<f16>() * 3);
let diffuse_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset, ends[0] as usize);
let specular_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[0] as u64, ends[1] as usize - ends[0] as usize);
let emissive_entries = StainingTemplate::read_array::<Half3>(&mut cursor, new_offset + ends[1] as u64, ends[2] as usize - ends[1] as usize);