diff options
Diffstat (limited to 'apps/fparkan-cli/src/main.rs')
| -rw-r--r-- | apps/fparkan-cli/src/main.rs | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/apps/fparkan-cli/src/main.rs b/apps/fparkan-cli/src/main.rs index e469509..d951c5e 100644 --- a/apps/fparkan-cli/src/main.rs +++ b/apps/fparkan-cli/src/main.rs @@ -27,7 +27,7 @@ use fparkan_assets::{ use fparkan_corpus::{discover, render_report_json, report, DiscoverOptions}; use fparkan_inspection::{ inspect_archive_file, inspect_land_msh_bounds_file, inspect_model_from_root, - load_land_msh_from_path, ArchiveInspection, ModelInspection, + inspect_wear_from_root, load_land_msh_from_path, ArchiveInspection, ModelInspection, }; use fparkan_path::{normalize_relative, PathPolicy}; use fparkan_prototype::build_prototype_graph_report; @@ -46,6 +46,7 @@ const MISSION_GRAPH_SCHEMA: &str = "fparkan-mission-graph-v1"; const MISSION_INSPECT_SCHEMA: &str = "fparkan-mission-inspect-v1"; const TERRAIN_INSPECT_SCHEMA: &str = "fparkan-terrain-inspect-v1"; const MODEL_INSPECT_SCHEMA: &str = "fparkan-model-inspect-v1"; +const WEAR_INSPECT_SCHEMA: &str = "fparkan-wear-inspect-v1"; #[derive(Serialize)] struct ArchiveInspectOutput<'a> { @@ -128,11 +129,11 @@ struct TerrainInspectOutput { faces: usize, slots: usize, material_tags: Vec<TerrainMaterialTagCount>, - shade_material_pairs: usize, + shade_pairs: usize, #[serde(skip_serializing_if = "Option::is_none")] - shade_material_lookup_min: Option<u16>, + shade_lookup_key_min: Option<u16>, #[serde(skip_serializing_if = "Option::is_none")] - shade_material_lookup_max: Option<u16>, + shade_lookup_key_max: Option<u16>, shade_batch_boundaries: usize, } @@ -143,6 +144,19 @@ struct TerrainMaterialTagCount { } #[derive(Serialize)] +struct WearInspectOutput { + schema_version: &'static str, + archive: String, + resource: String, + materials: usize, + lightmaps: usize, + #[serde(skip_serializing_if = "Option::is_none")] + first_material: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + last_material: Option<String>, +} + +#[derive(Serialize)] struct ModelInspectOutput<'a> { schema_version: &'static str, archive: &'a str, @@ -238,6 +252,10 @@ fn run(args: &[String]) -> Result<(), String> { let rest = strip_format_json(rest)?; inspect_terrain(&rest) } + [domain, command, rest @ ..] if domain == "wear" && command == "inspect" => { + let rest = strip_format_json(rest)?; + inspect_wear(&rest) + } [domain, command, rest @ ..] if domain == "model" && command == "inspect" => { let rest = strip_format_json(rest)?; inspect_model(&rest) @@ -479,19 +497,13 @@ fn inspect_terrain(args: &[String]) -> Result<(), String> { .map(|(tag, faces)| TerrainMaterialTagCount { tag, faces }) .collect::<Vec<_>>(); material_tags.sort_unstable_by_key(|entry| entry.tag); - let shade_material_pairs = (0..terrain.slots.slots_raw.len()) + let shade_pairs = (0..terrain.slots.slots_raw.len()) .filter_map(|slot_index| terrain.slot_material_pairs(slot_index)) .flatten() .collect::<Vec<_>>(); - let shade_material_lookup_min = shade_material_pairs - .iter() - .map(|pair| pair.shade_selection().material_index) - .min(); - let shade_material_lookup_max = shade_material_pairs - .iter() - .map(|pair| pair.shade_selection().material_index) - .max(); - let shade_batch_boundaries = shade_material_pairs + let shade_lookup_key_min = shade_pairs.iter().map(|pair| pair.shade_lookup_key()).min(); + let shade_lookup_key_max = shade_pairs.iter().map(|pair| pair.shade_lookup_key()).max(); + let shade_batch_boundaries = shade_pairs .iter() .filter(|pair| pair.flags & 0x0010 != 0) .count(); @@ -506,15 +518,35 @@ fn inspect_terrain(args: &[String]) -> Result<(), String> { faces: terrain.faces.len(), slots: terrain.slots.slots_raw.len(), material_tags, - shade_material_pairs: shade_material_pairs.len(), - shade_material_lookup_min, - shade_material_lookup_max, + shade_pairs: shade_pairs.len(), + shade_lookup_key_min, + shade_lookup_key_max, shade_batch_boundaries, })? ); Ok(()) } +fn inspect_wear(args: &[String]) -> Result<(), String> { + let root = parse_root_alias(args)?; + let archive = parse_required(args, &["--archive"], "--archive")?; + let resource = parse_required(args, &["--resource"], "--resource")?; + let inspection = inspect_wear_from_root(&root, &archive, &resource)?; + println!( + "{}", + serialize_json(&WearInspectOutput { + schema_version: WEAR_INSPECT_SCHEMA, + archive, + resource, + materials: inspection.materials, + lightmaps: inspection.lightmaps, + first_material: inspection.first_material, + last_material: inspection.last_material, + })? + ); + Ok(()) +} + fn inspect_model(args: &[String]) -> Result<(), String> { let root = parse_root_alias(args)?; let archive = parse_required(args, &["--archive"], "--archive")?; @@ -632,7 +664,7 @@ fn prototype_graph_requiredness_label( } fn usage() -> String { - "usage: fparkan corpus discover|validate --root <path> [--format json] | archive inspect <file> [--format json] | terrain inspect <Land.msh> [--format json] | model inspect --root <path> --archive <archive> --resource <model.msh> [--format json] | prototype inspect --root <path> --key <key> [--format json] | mission graph|inspect --root <path> --mission <path> [--format json]".to_string() + "usage: fparkan corpus discover|validate --root <path> [--format json] | archive inspect <file> [--format json] | terrain inspect <Land.msh> [--format json] | wear inspect --root <path> --archive <archive> --resource <wear.wea> [--format json] | model inspect --root <path> --archive <archive> --resource <model.msh> [--format json] | prototype inspect --root <path> --key <key> [--format json] | mission graph|inspect --root <path> --mission <path> [--format json]".to_string() } #[cfg(test)] @@ -759,16 +791,35 @@ mod tests { TerrainMaterialTagCount { tag: 0, faces: 1 }, TerrainMaterialTagCount { tag: 3, faces: 1 }, ], - shade_material_pairs: 2, - shade_material_lookup_min: Some(1), - shade_material_lookup_max: Some(2), + shade_pairs: 2, + shade_lookup_key_min: Some(1), + shade_lookup_key_max: Some(2), shade_batch_boundaries: 1, }) .expect("serialize terrain inspection"); assert_eq!( json, - "{\"schema_version\":\"fparkan-terrain-inspect-v1\",\"path\":\"DATA/MAPS/AutoMAP/Land.msh\",\"positions\":3,\"min\":[-1.0,-2.0,-3.0],\"max\":[4.0,5.0,6.0],\"faces\":2,\"slots\":4,\"material_tags\":[{\"tag\":0,\"faces\":1},{\"tag\":3,\"faces\":1}],\"shade_material_pairs\":2,\"shade_material_lookup_min\":1,\"shade_material_lookup_max\":2,\"shade_batch_boundaries\":1}" + "{\"schema_version\":\"fparkan-terrain-inspect-v1\",\"path\":\"DATA/MAPS/AutoMAP/Land.msh\",\"positions\":3,\"min\":[-1.0,-2.0,-3.0],\"max\":[4.0,5.0,6.0],\"faces\":2,\"slots\":4,\"material_tags\":[{\"tag\":0,\"faces\":1},{\"tag\":3,\"faces\":1}],\"shade_pairs\":2,\"shade_lookup_key_min\":1,\"shade_lookup_key_max\":2,\"shade_batch_boundaries\":1}" + ); + } + + #[test] + fn wear_inspect_output_retains_material_bounds() { + let json = serialize_json(&WearInspectOutput { + schema_version: WEAR_INSPECT_SCHEMA, + archive: "system.rlb".to_string(), + resource: "SHADE.WEA".to_string(), + materials: 1, + lightmaps: 0, + first_material: Some("LIGHT1".to_string()), + last_material: Some("LIGHT1".to_string()), + }) + .expect("serialize wear inspection"); + + assert_eq!( + json, + "{\"schema_version\":\"fparkan-wear-inspect-v1\",\"archive\":\"system.rlb\",\"resource\":\"SHADE.WEA\",\"materials\":1,\"lightmaps\":0,\"first_material\":\"LIGHT1\",\"last_material\":\"LIGHT1\"}" ); } } |
