facett-demo/tests/sigtuna_tour.rs
//! **Sigtuna 3D-navigator demo proof** (headless — real embedded OSM, no window).
//!
//! The `sigtuna_demo` bin flies the cinematic tour over the **embedded Sigtuna** clip
//! (a real slice of Sweden). This proves, as DATA, that the demo's ingredients are
//! real and wired:
//! 1. the embedded Sigtuna clip extrudes real buildings into 3D prisms (SEE THE
//! HOUSES — the mesh rises off the ground plane),
//! 2. a real Sigtuna STREET is found + projected into a followable route,
//! 3. attaching the tour walks the camera Circle → Descend → Drive across the loop
//! and genuinely DESCENDS (air ≫ street camera distance), and
//! 4. it's deterministic under a pinned clock.
//!
//! No GPU, no window — drives `Map3D` through `set_clock` + `render_camera`.
#![cfg(not(target_arch = "wasm32"))]
use facett::map::Way;
use facett_map3d::{Map3D, TourPhase};
/// The longest road (line) way in the town, downsampled to a waypoint chain — the same
/// street picker the `sigtuna_demo` bin uses (kept tiny + duplicated here so the proof
/// is self-contained; the bin is the human-runnable twin).
fn street_route(ways: &[Way]) -> Vec<(f32, f32)> {
let seg_len = |w: &Way| -> f32 {
w.points
.windows(2)
.map(|s| ((s[1].0 - s[0].0).powi(2) + (s[1].1 - s[0].1).powi(2)).sqrt())
.sum()
};
let Some(longest) = ways
.iter()
.filter(|w| w.fill.is_none() && w.height_m.is_none() && w.points.len() >= 2)
.max_by(|a, b| seg_len(a).partial_cmp(&seg_len(b)).unwrap_or(std::cmp::Ordering::Equal))
else {
return Vec::new();
};
let pts = &longest.points;
let stride = (pts.len() / 48).max(1);
pts.iter().step_by(stride).copied().collect()
}
#[test]
fn sigtuna_demo_extrudes_houses_and_tours_the_streets() {
// The embedded Sigtuna clip must decode (the real-OSM source the demo flies).
let geo = facett_demo::osm_tabs::load_sigtuna().expect("embedded Sigtuna decodes");
// Crop to the dense TOWN CORE so the extruded scene is house-scale (SEE THE HOUSES)
// — the raw 16 km clip normalises houses to invisible slivers.
let ways = facett_demo::osm_tabs::crop_to_town_core(&geo.ways_3d, 400.0);
assert!(!ways.is_empty(), "the cropped Sigtuna core carries ways");
assert!(ways.len() < geo.ways_3d.len(), "the crop actually narrows the regional clip to the core");
// (2) A real street is found + projectable.
let wps = street_route(&ways);
assert!(wps.len() >= 2, "a real Sigtuna street yields a followable route ({} waypoints)", wps.len());
// Round-2: build with REAL pitched roofs + OSM colours so the houses read as
// buildings (gabled/hipped roofs, coloured facades/roofs) — not flat massing.
let mut map = Map3D::from_geometry_roofed("Sigtuna navigator", &ways).with_route(&ways, &wps).with_tour(true);
let mpu = map.metres_per_design_unit(); // real metres per design unit for the cropped core
// The real Sigtuna core grows real pitched roofs + coloured buildings (round-2
// "houses read as real buildings"), and the flat-cap default grows NEITHER — the
// RED gate. Neither regresses the houses-in-frame oracle (asserted below).
let flat = Map3D::from_geometry("Sigtuna flat", &ways);
assert_eq!(flat.pitched_roofs(), 0, "the flat-cap default grows no pitched roofs (RED gate)");
assert_eq!(flat.coloured_buildings(), 0, "the flat-cap default is monochrome (RED gate)");
let pitched = map.pitched_roofs();
let coloured = map.coloured_buildings();
assert!(pitched > 0, "the real Sigtuna core grows real pitched roofs ({pitched})");
assert!(coloured > 0, "the real Sigtuna core carries coloured buildings ({coloured})");
// (1) The houses extrude — thousands of mesh vertices rose off the flat ground
// plane (SEE THE HOUSES: the real Sigtuna footprints became 3D prisms).
let raised_verts = map.mesh().positions.iter().filter(|p| p[1] > 0.0).count();
let max_h_m = map.mesh().positions.iter().map(|p| p[1]).fold(0.0f32, f32::max) * mpu;
assert!(raised_verts > 1000, "the real Sigtuna footprints extrude into 3D prisms ({raised_verts} raised verts)");
assert!(max_h_m > 3.0, "the extruded buildings have real height ({max_h_m:.1} m tall)");
assert!(map.has_route(), "the drive phase has a real street route");
assert!(map.tour_active(), "the tour is flying");
// (3) Walk the loop: Circle → Descend → Drive, and it descends bird → street.
let total = 18.0 + 8.0 + 26.0;
let (mut circle, mut descend, mut drive) = (false, false, false);
let mut air_dist = 0.0f32;
let mut street_dist = f32::INFINITY;
let mut circle_houses = 0usize; // risen houses in frame at the air-circle altitude
for i in 0..=120 {
let t = i as f64 * total / 120.0;
map.set_clock(t);
match map.tour_phase().expect("active tour → phase") {
TourPhase::Circle => {
circle = true;
circle_houses = circle_houses.max(map.buildings_visible());
if (t - 10.0).abs() < 1.5 {
air_dist = air_dist.max(map.render_camera().distance);
}
}
TourPhase::Descend => descend = true,
TourPhase::Drive => {
drive = true;
street_dist = street_dist.min(map.render_camera().distance);
}
}
}
assert!(circle && descend && drive, "the tour walks circle → descend → drive over Sigtuna");
// The drive genuinely sits at STREET LEVEL (a real ~30 m car-nav distance), and the
// air circle is a true bird height far above it — a real bird → street descent.
let street_m = street_dist * mpu;
let air_m = air_dist * mpu;
eprintln!("[diag] mpu={mpu:.0} max_h_m={max_h_m:.1} raised={raised_verts} street_dist={street_dist:.4} street_m={street_m:.0} air_m={air_m:.0} circle_houses={circle_houses} pitched={pitched} coloured={coloured}");
assert!(street_m < 90.0, "the drive rides the streets at street level ({street_m:.0} m from the road)");
assert!(air_m > street_m * 3.0, "the tour descends bird → street (air {air_m:.0} m ≫ street {street_m:.0} m)");
// The REAL Sigtuna houses are in frame at the air-circle altitude — "we want to
// SEE THE HOUSES", read as DATA off the live render camera's frustum.
assert!(circle_houses > 0, "the real Sigtuna houses are visible circling from the air ({circle_houses} risen verts in frame)");
// (4) Determinism under a pinned clock.
map.set_clock(15.0);
let a = map.render_camera().eye();
map.set_clock(15.0);
let b = map.render_camera().eye();
let deterministic = a == b;
assert!(deterministic, "the tour pose is a pure function of the clock");
#[cfg(feature = "testmatrix")]
{
let ok = raised_verts > 1000 && max_h_m > 3.0 && circle && descend && drive && street_m < 80.0 && air_m > street_m * 3.0 && deterministic && circle_houses > 0 && pitched > 0 && coloured > 0;
facett_core::testmatrix::emit(
"facett-demo",
"sigtuna_navigator_tour",
ok,
&format!(
"raised={raised_verts} max_h_m={max_h_m:.1} waypoints={} circle={circle} descend={descend} \
drive={drive} air_m={air_m:.0} street_m={street_m:.0} circle_houses={circle_houses} \
pitched={pitched} coloured={coloured} det={deterministic}",
wps.len()
),
);
}
}