mirror of
https://github.com/redstrate/Physis.git
synced 2025-04-20 11:47:46 +00:00
Add material file parsing
This commit is contained in:
parent
6554dee2f1
commit
01717456d1
2 changed files with 147 additions and 1 deletions
|
@ -62,3 +62,6 @@ pub mod log;
|
|||
|
||||
// Reading textures (TEX).
|
||||
pub mod tex;
|
||||
|
||||
// Reading material files (MTRL)
|
||||
pub mod mtrl;
|
143
src/mtrl.rs
Normal file
143
src/mtrl.rs
Normal file
|
@ -0,0 +1,143 @@
|
|||
use std::io::Cursor;
|
||||
use crate::gamedata::MemoryBuffer;
|
||||
use binrw::{binread, BinRead};
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct MaterialFileHeader {
|
||||
version: u32,
|
||||
file_size: u16,
|
||||
data_set_size: u16,
|
||||
string_table_size: u16,
|
||||
shader_package_name_offset: u16,
|
||||
texture_count: u8,
|
||||
uv_set_count: u8,
|
||||
color_set_count: u8,
|
||||
additional_data_size: u8
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct MaterialHeader {
|
||||
shader_value_list_size: u16,
|
||||
shader_key_count: u16,
|
||||
constant_count: u16,
|
||||
#[br(pad_after = 4)]
|
||||
sampler_count: u16
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct ColorSet {
|
||||
name_offset: u16,
|
||||
#[br(pad_after = 1)]
|
||||
index: u8
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct ColorSetInfo {
|
||||
#[br(count = 256)]
|
||||
data: Vec<u16>
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct ColorSetDyeInfo {
|
||||
#[br(count = 16)]
|
||||
data: Vec<u16>
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct ShaderKey {
|
||||
category: u32,
|
||||
value: u32
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct Constant {
|
||||
constant_id: u32,
|
||||
value_offset: u16,
|
||||
value_size: u16
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct Sampler {
|
||||
sampler_id: u32,
|
||||
flags: u32, // TODO: unknown
|
||||
#[br(pad_after = 3)]
|
||||
texture_index: u8,
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
struct MaterialData {
|
||||
file_header: MaterialFileHeader,
|
||||
|
||||
#[br(count = file_header.texture_count)]
|
||||
offsets: Vec<u32>,
|
||||
|
||||
#[br(count = file_header.uv_set_count)]
|
||||
uv_color_sets: Vec<ColorSet>,
|
||||
|
||||
#[br(count = file_header.color_set_count)]
|
||||
color_sets: Vec<ColorSet>,
|
||||
|
||||
#[br(count = file_header.string_table_size)]
|
||||
strings: Vec<u8>,
|
||||
|
||||
#[br(if(file_header.data_set_size > 0))]
|
||||
#[br(pad_before = file_header.additional_data_size)]
|
||||
color_set_info: Option<ColorSetInfo>,
|
||||
|
||||
#[br(if(file_header.data_set_size > 512))]
|
||||
color_set_due_info: Option<ColorSetDyeInfo>,
|
||||
|
||||
header: MaterialHeader,
|
||||
|
||||
#[br(count = header.shader_key_count)]
|
||||
shader_keys: Vec<ShaderKey>,
|
||||
#[br(count = header.constant_count)]
|
||||
constants: Vec<Constant>,
|
||||
#[br(count = header.sampler_count)]
|
||||
samplers: Vec<Sampler>,
|
||||
#[br(count = header.shader_value_list_size / 4)]
|
||||
shader_values: Vec<f32>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Material {
|
||||
texture_paths: Vec<String>
|
||||
}
|
||||
|
||||
impl Material {
|
||||
pub fn from_existing(buffer: &MemoryBuffer) -> Option<Material> {
|
||||
let mut cursor = Cursor::new(buffer);
|
||||
let mat_data = MaterialData::read(&mut cursor).ok()?;
|
||||
|
||||
let mut texture_paths = vec![];
|
||||
|
||||
let mut offset = 0;
|
||||
for _ in 0..mat_data.file_header.texture_count {
|
||||
let mut string = String::new();
|
||||
|
||||
let mut next_char = mat_data.strings[offset as usize] as char;
|
||||
while next_char != '\0' {
|
||||
string.push(next_char);
|
||||
offset += 1;
|
||||
next_char = mat_data.strings[offset as usize] as char;
|
||||
}
|
||||
|
||||
texture_paths.push(string);
|
||||
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
Some(Material {
|
||||
texture_paths
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue