diff --git a/rust/Cargo.lock b/rust/Cargo.lock index ba3ddab..1bf1bbc 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -719,6 +719,9 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "renderwarelib" version = "0.1.0" +dependencies = [ + "binrw", +] [[package]] name = "rgb" diff --git a/rust/mhgd/src/lwo/material.rs b/rust/mhgd/src/lwo/material.rs index f9cf0ec..62bcc19 100644 --- a/rust/mhgd/src/lwo/material.rs +++ b/rust/mhgd/src/lwo/material.rs @@ -24,6 +24,7 @@ pub enum MaterialProjectionMode { pub struct MaterialUvInfo { pub diffuse_projection: Option, pub color_projection: Option, + pub max_smoothing_angle: Option, pub material: Gd, pub id: u16, } @@ -37,6 +38,7 @@ impl MaterialUvInfo { let mut m = MaterialUvInfo { diffuse_projection: None, color_projection: None, + max_smoothing_angle: None, material: ShaderMaterial::new(), id, }; @@ -244,6 +246,9 @@ impl MaterialUvInfo { } .to_variant(), ), + SurfaceParameterSubChunk::MaxSmoothingAngle(it) => { + m.max_smoothing_angle = Some(it.max_smoothing_angle); + } SurfaceParameterSubChunk::BaseShadingValueDiffuse(it) => { m.material .set_shader_parameter("diffuse".into(), it.value.to_variant()); diff --git a/rust/mhgd/src/lwo/surface_info.rs b/rust/mhgd/src/lwo/surface_info.rs index 86d79c5..7f1896c 100644 --- a/rust/mhgd/src/lwo/surface_info.rs +++ b/rust/mhgd/src/lwo/surface_info.rs @@ -107,21 +107,31 @@ impl SurfaceInfo { }); for (id, poly) in surface_polygons { - for index in triangulate(&poly.vert) { + let tri = triangulate(&poly.vert); + /*let edge0 = layer.points[tri[1] as usize] - layer.points[tri[0] as usize]; + let edge1 = layer.points[tri[tri.len() - 2] as usize] + - layer.points[tri[tri.len() - 1] as usize]; + let normal = edge0.cross(edge1);*/ + + for index in tri { let uv = uv_subset .iter() .map(|it| it.and_then(|(_, it)| find_mapping(it, id, index))) .collect_vec(); // TODO: let weight = find_mapping(weight_mappings, id, vert); - let vert = layer.points.get(index as usize).unwrap(); + let vert = layer.points[index as usize]; - surface_info.push_index(vert, &uv, 0f32); + surface_info.push_index(&vert, &uv, 0f32); } } surface_info } + fn surface_normals(&mut self) { + let normals: HashMap = HashMap::with_capacity(self.vertices.len()); + } + fn push_index(&mut self, vert: &Vector3, uvs: &[Option], weight: f32) { let index = *self .vertex_map diff --git a/rust/mhgd/src/starforce/mhk3_map.rs b/rust/mhgd/src/starforce/mhk3_map.rs index 9f6c6dc..5845f1e 100644 --- a/rust/mhgd/src/starforce/mhk3_map.rs +++ b/rust/mhgd/src/starforce/mhk3_map.rs @@ -1,9 +1,9 @@ -use crate::starforce::sar_archive::{sarc_path_to_gd, SarLoader, GAMES_PATH}; +use crate::starforce::sar_archive::{sarc_path_to_gd, SarLoader, INSTALL_PATH}; use godot::bind::godot_api; -use godot::builtin::GodotString; +use godot::builtin::{GodotString, ToVariant, Variant}; use godot::engine::file_access::ModeFlags; use godot::engine::global::Error; -use godot::engine::{try_load, DirAccess, FileAccess, PckPacker, Resource, ResourceLoader}; +use godot::engine::{try_load, FileAccess, PckPacker, Resource, ResourceLoader}; use godot::log::godot_print; use godot::obj::{Gd, Share}; use godot::prelude::GodotClass; @@ -11,8 +11,7 @@ use itertools::Itertools; use starforcelib::sarc::SarcArchive; use std::collections::HashSet; use std::io::Cursor; -use std::iter::{Chain, FlatMap}; -use std::path::Iter; +use std::iter::Enumerate; use std::vec::IntoIter; /// This is supposedly to be the default. @@ -20,18 +19,41 @@ const KEY: &str = "0000000000000000000000000000000000000000000000000000000000000 #[derive(GodotClass)] #[class(init)] -pub struct Mhk3Map {} +pub struct Mhk3Map { + #[export] + pub progress: f32, + pub total_files: i32, + files_to_convert: Option>>, + loader: Option>, + game: GodotString, +} #[godot_api] impl Mhk3Map { #[func] - pub fn get_available_maps() {} + pub fn tick_install(&mut self) -> Variant { + self.files_to_convert + .as_mut() + .map(|it| { + it.next() + .map(|(i, file)| { + godot_print!("Loading {}", file); + try_load::(&file); + self.progress = i as f32 / self.total_files as f32; + file.strip_prefix(INSTALL_PATH) + .unwrap() + .rsplit_once('.') + .unwrap() + .0 + .to_variant() + }) + .unwrap_or_else(Variant::nil) + }) + .unwrap_or_else(|| Error::FAILED.to_variant()) + } #[func] - pub fn test() {} - - #[func] - pub fn install(path: GodotString, game: GodotString) -> Error { + pub fn start_install(&mut self, path: GodotString, game: GodotString) -> Error { let file = if let Some(file) = FileAccess::open(path, ModeFlags::READ) { file } else { @@ -78,18 +100,34 @@ impl Mhk3Map { base, }); + self.total_files = files_to_convert.len() as i32; + self.files_to_convert = Some(files_to_convert.into_iter().sorted().enumerate()); + ResourceLoader::singleton().add_resource_format_loader(sar_loader.share().upcast(), true); - for (i, file) in files_to_convert.into_iter().sorted().enumerate() { - godot_print!("{}x Next up: {}", i, file); - try_load::(file); - } + self.loader = Some(sar_loader); + self.game = game; + Error::OK + } + + #[func] + pub fn end_install(&mut self) -> Error { + let sar_loader = if let Some(loader) = self.loader.take() { + loader + } else { + return Error::FAILED; + }; ResourceLoader::singleton().remove_resource_format_loader(sar_loader.upcast()); let mut packer = PckPacker::new(); - packer.pck_start(format!("user://{}.pck", game).into(), 32, KEY.into(), false); + packer.pck_start( + format!("user://{}.pck", self.game).into(), + 32, + KEY.into(), + false, + ); for file in SarLoader::list_installed_files() { packer.add_file( - SarLoader::resource_path_at(file.clone(), &game), + SarLoader::resource_path_at(file.clone(), &self.game), file.clone().into(), false, ); diff --git a/rust/renderwarelib/Cargo.toml b/rust/renderwarelib/Cargo.toml index 5d79978..8783e60 100644 --- a/rust/renderwarelib/Cargo.toml +++ b/rust/renderwarelib/Cargo.toml @@ -1,4 +1,7 @@ [package] name = "renderwarelib" version = "0.1.0" -edition = "2021" \ No newline at end of file +edition = "2021" + +[dependencies] +binrw = "0.11.2" diff --git a/rust/renderwarelib/src/chunks/clump.rs b/rust/renderwarelib/src/chunks/clump.rs new file mode 100644 index 0000000..ca7f114 --- /dev/null +++ b/rust/renderwarelib/src/chunks/clump.rs @@ -0,0 +1,9 @@ +use binrw::binread; + +#[binread] +#[derive(Debug)] +pub struct RpClump { + pub num_atomics: i32, + pub num_lights: i32, + pub num_cameras: i32, +} diff --git a/rust/renderwarelib/src/chunks/mod.rs b/rust/renderwarelib/src/chunks/mod.rs new file mode 100644 index 0000000..6f19695 --- /dev/null +++ b/rust/renderwarelib/src/chunks/mod.rs @@ -0,0 +1,40 @@ +use binrw::{binread, NullString}; + +pub mod clump; + +#[binread] +#[br(little)] +#[derive(Debug)] +pub struct RwStream { + pub kind: u32, + pub size: u32, + pub library_id_stamp: u32, +} + +#[binread] +#[br(little)] +#[derive(Debug)] +pub enum RwSection { + #[br(magic(0x1u32))] + Struct {}, + #[br(magic(0x2u32))] + String(#[br(align_after = 4)] NullString), + // TODO: extension + // TODO: camera + // TODO: texture + // TODO: material + // TODO: material list + // TODO: atomic section + // TODO: plane section + // TODO: world + // TODO: spline + // TODO: matrix + // TODO: frame list + // TODO: geometry + #[br(magic(0x10u32))] + Clump { + num_atomics: u32, + num_lights: u32, + num_cameras: u32, + }, +} diff --git a/rust/renderwarelib/src/lib.rs b/rust/renderwarelib/src/lib.rs index 7d12d9a..b6f2665 100644 --- a/rust/renderwarelib/src/lib.rs +++ b/rust/renderwarelib/src/lib.rs @@ -1,3 +1,5 @@ +pub mod chunks; + pub fn add(left: usize, right: usize) -> usize { left + right } diff --git a/rust/renderwarelib/src/main.rs b/rust/renderwarelib/src/main.rs new file mode 100644 index 0000000..fd1e48f --- /dev/null +++ b/rust/renderwarelib/src/main.rs @@ -0,0 +1,11 @@ +use binrw::BinRead; +use renderwarelib::chunks::RwSection; +use std::fs::File; + +pub fn main() { + let mut file = File::open("/run/media/theaninova/Heart Drive/Games/Moorhuhn Kart 2/data/data/mk2/level01/objects/collision_border.dff") + .unwrap(); + let data = RwSection::read(&mut file).unwrap(); + + println!("{:?}", data) +}