aboutsummaryrefslogtreecommitdiff
path: root/apps/fparkan-game
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-11-01 09:15:17 +0300
committerValentin Popov <valentin@popov.link>2026-11-01 09:15:17 +0300
commit9533c1a927ec26aced3a9b80ce385c0774cbadbe (patch)
tree6dca459f1a9c7792479161bd06e33a6551b1325e /apps/fparkan-game
parent1c3b97755630ea997b9f50c974e34982fba9edf4 (diff)
downloadfparkan-9533c1a927ec26aced3a9b80ce385c0774cbadbe.tar.xz
fparkan-9533c1a927ec26aced3a9b80ce385c0774cbadbe.zip
fix(game): render terrain without placed object meshes
Diffstat (limited to 'apps/fparkan-game')
-rw-r--r--apps/fparkan-game/src/main.rs33
1 files changed, 29 insertions, 4 deletions
diff --git a/apps/fparkan-game/src/main.rs b/apps/fparkan-game/src/main.rs
index 860922b..ca8742d 100644
--- a/apps/fparkan-game/src/main.rs
+++ b/apps/fparkan-game/src/main.rs
@@ -131,7 +131,6 @@ fn run(args: &[String]) -> Result<String, String> {
.ok_or_else(|| "mission terrain is unavailable after loading".to_string())?;
let roots = loaded_mission_object_drafts(&engine)
.map(|drafts| &drafts[..args.preview_roots.get().min(drafts.len())])
- .filter(|roots| !roots.is_empty())
.ok_or_else(|| {
"selected mission object drafts are unavailable after loading".to_string()
})?;
@@ -8564,9 +8563,6 @@ fn static_preview_mesh_and_materials(
dynamic_component_geometry_by_object.push(dynamic_component_geometry);
control_animation_instances_by_object.push(control_animation_instances);
}
- if mesh_components == 0 {
- return Err("selected static preview roots have no mesh-backed visual".to_string());
- }
let free_camera = if legacy_camera.is_none() {
Some(FreeFlightCamera::from_mesh_and_terrain(&mesh, terrain)?)
} else {
@@ -13167,6 +13163,35 @@ mod tests {
#[test]
#[ignore = "requires installed GOG resources; set FPARKAN_GAME_ROOT"]
+ fn gog_static_preview_accepts_terrain_without_placed_objects() {
+ let root = std::env::var_os("FPARKAN_GAME_ROOT")
+ .map(PathBuf::from)
+ .unwrap_or_else(|| PathBuf::from(r"C:\GOG Games\Parkan - Iron Strategy"));
+ let path = "DATA/MAPS/41/Land.msh";
+ let bytes = std::fs::read(root.join(path)).expect("original map mesh");
+ let document = fparkan_assets::decode_nres_payload(Arc::from(bytes)).unwrap();
+ let land = fparkan_terrain_format::decode_land_msh(&document).unwrap();
+ let terrain = TerrainWorld::from_land_msh(&land).unwrap();
+ let preview = static_preview_mesh_and_materials(
+ &MissionAssets::default(),
+ &terrain,
+ &[],
+ None,
+ None,
+ None,
+ &root,
+ path,
+ )
+ .expect("terrain is a complete scene without object meshes");
+ assert_eq!(preview.mesh_components, 0);
+ assert_eq!(preview.terrain_components, 1);
+ assert!(!preview.mesh.vertices.is_empty());
+ assert!(!preview.mesh.indices.is_empty());
+ assert!(!preview.materials.is_empty());
+ }
+
+ #[test]
+ #[ignore = "requires installed GOG resources; set FPARKAN_GAME_ROOT"]
fn gog_terrain_detail_uses_multitexture_animation_block() {
let root = std::env::var_os("FPARKAN_GAME_ROOT")
.map(PathBuf::from)