diff options
| author | Valentin Popov <valentin@popov.link> | 2026-07-18 16:39:52 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-07-18 16:39:52 +0300 |
| commit | e9c1a83c51070c4f8da76540c17c2393922b6fcc (patch) | |
| tree | 5cf115fc25aa4df24848e9488bdaa919890bf7f7 /crates | |
| parent | 575124830b678d0c4d5b37a708bba9692a4e47ef (diff) | |
| download | fparkan-e9c1a83c51070c4f8da76540c17c2393922b6fcc.tar.xz fparkan-e9c1a83c51070c4f8da76540c17c2393922b6fcc.zip | |
fix(terrain): preserve opaque shade lookup keys
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/fparkan-inspection/src/lib.rs | 41 | ||||
| -rw-r--r-- | crates/fparkan-terrain-format/src/lib.rs | 24 | ||||
| -rw-r--r-- | crates/fparkan-terrain/src/lib.rs | 4 |
3 files changed, 51 insertions, 18 deletions
diff --git a/crates/fparkan-inspection/src/lib.rs b/crates/fparkan-inspection/src/lib.rs index e2b9068..be1f098 100644 --- a/crates/fparkan-inspection/src/lib.rs +++ b/crates/fparkan-inspection/src/lib.rs @@ -146,6 +146,19 @@ pub struct WearMaterialTexture { pub image: fparkan_texm::RgbaImage, } +/// Compact inspection summary of a WEAR resource stored in an archive. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct WearInspection { + /// Number of material rows. + pub materials: usize, + /// Number of lightmap rows. + pub lightmaps: usize, + /// First material resource name, when present. + pub first_material: Option<String>, + /// Last material resource name, when present. + pub last_material: Option<String>, +} + /// Land map/msh inspection payload. #[derive(Clone, Debug, Eq, PartialEq)] pub struct MapInspection { @@ -374,6 +387,34 @@ pub fn inspect_model_from_root( }) } +/// Inspects a WEAR resource through repository-backed lookup. +/// +/// # Errors +/// +/// Returns a string error when the resource cannot be resolved or parsed as a +/// valid WEAR payload. +pub fn inspect_wear_from_root( + root: &Path, + archive: &str, + resource: &str, +) -> Result<WearInspection, String> { + let bytes = read_resource_bytes_diagnostic(root, archive, resource) + .map_err(|err| render_human(&err))?; + let wear = decode_wear(&bytes).map_err(|err| err.to_string())?; + Ok(WearInspection { + materials: wear.entries.len(), + lightmaps: wear.lightmaps.len(), + first_material: wear + .entries + .first() + .map(|entry| String::from_utf8_lossy(&entry.material.0).into_owned()), + last_material: wear + .entries + .last() + .map(|entry| String::from_utf8_lossy(&entry.material.0).into_owned()), + }) +} + /// Loads and validates a model resource through repository-backed lookup. /// /// # Errors diff --git a/crates/fparkan-terrain-format/src/lib.rs b/crates/fparkan-terrain-format/src/lib.rs index 764de09..54bd3f4 100644 --- a/crates/fparkan-terrain-format/src/lib.rs +++ b/crates/fparkan-terrain-format/src/lib.rs @@ -212,18 +212,15 @@ pub struct TerrainMaterialPair { } impl TerrainMaterialPair { - /// Returns the material-manager selection used by `GetShade`. + /// Returns the opaque lookup key supplied to `GetShade`. /// - /// `GetShade` owns a manager loaded only with `Shade.wea`, so its - /// 16-bit lookup occupies row bits of that manager's table zero. It is - /// deliberately separate from the `Land1.wea`/`Land2.wea` selections - /// carried by [`TerrainMaterialLayers`]. + /// This is deliberately separate from the `Land1.wea`/`Land2.wea` + /// selectors carried by [`TerrainMaterialLayers`]. Although `GetShade` + /// owns a manager loaded from `Shade.wea`, this key is not a WEAR row: + /// observed map values exceed that table's row count. #[must_use] - pub const fn shade_selection(self) -> TerrainMaterialSelection { - TerrainMaterialSelection { - table_index: 0, - material_index: self.material_lookup, - } + pub const fn shade_lookup_key(self) -> u16 { + self.material_lookup } } @@ -1586,11 +1583,8 @@ mod tests { ]) ); assert_eq!( - document.slot_material_pairs(0).expect("material pairs")[0].shade_selection(), - TerrainMaterialSelection { - table_index: 0, - material_index: 0x0102, - } + document.slot_material_pairs(0).expect("material pairs")[0].shade_lookup_key(), + 0x0102 ); assert_eq!(document.slot_material_pairs(1), None); diff --git a/crates/fparkan-terrain/src/lib.rs b/crates/fparkan-terrain/src/lib.rs index a69df2a..4eef871 100644 --- a/crates/fparkan-terrain/src/lib.rs +++ b/crates/fparkan-terrain/src/lib.rs @@ -27,9 +27,7 @@ use std::collections::VecDeque; /// /// Applications access this semantic terrain API through this terrain crate /// rather than taking a direct dependency on the binary-format parser. -pub use fparkan_terrain_format::{ - TerrainMaterialLayers, TerrainMaterialPair, TerrainMaterialSelection, -}; +pub use fparkan_terrain_format::{TerrainMaterialLayers, TerrainMaterialSelection}; /// Terrain world. #[derive(Clone, Debug, Default)] |
