Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-demo/tests/osm3d_shot.rs

//! Render the REAL OSM 3D tab (liechtenstein GeoParquet, not the synthetic
//! rabbit) through egui_kittest's wgpu backend and save a PNG so the agent can
//! SEE what the user sees — the starburst regression that the synthetic-only
//! render_proof never exercised. This is the "test the UI myself" path.

use egui_kittest::Harness;
#[cfg(feature = "map3d-wgpu")]
use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state, default_wgpu_setup};
use facett::Facet;
use facett_demo::osm_tabs::{self, OsmSource};

#[test]
fn osm3d_real_render_to_png() {
    let geo = osm_tabs::load();
    eprintln!(
        "osm3d_shot: source={:?}  ways_3d={}  ways_2d={}  points={}",
        geo.source, geo.ways_3d.len(), geo.ways_2d.len(), geo.points.len()
    );
    assert!(geo.source != OsmSource::Synthetic || !geo.ways_3d.is_empty(),
        "want real liechtenstein (or at least some ways)");

    // ── Height distribution EMIT + the "no insanely tall buildings" REGRESSION ──
    // Buildings must extrude to LOW, VARIED, span-scaled metric heights — not the
    // old uniform 0.22 design-unit spike. Compute the real distribution from the
    // SAME path the mesh uses and assert it on the actual liechtenstein ways.
    let stats = facett::map3d::building_height_stats(&geo.ways_3d, 0.22);
    eprintln!("osm3d_shot: [height-dist] {}", stats.to_json());
    if stats.buildings > 0 {
        let p95_frac = stats.p95 / stats.box_span;
        let max_frac = stats.max / stats.box_span;
        eprintln!(
            "osm3d_shot: buildings={} tagged={} default={} min={:.5} median={:.5} p95={:.5} ({:.2}% box) max={:.5} ({:.2}% box)",
            stats.buildings, stats.tagged, stats.defaulted, stats.min, stats.median,
            stats.p95, p95_frac * 100.0, stats.max, max_frac * 100.0
        );
        // p95 must be a low skyline — the old uniform 0.22 lift (≈11% of the box)
        // FAILS this. (The fix puts p95 well under 1% of the box for a town.)
        assert!(
            p95_frac < 0.1,
            "buildings must be a low skyline: p95={} ({:.2}% of box) — the old uniform 0.22 spike fails this",
            stats.p95, p95_frac * 100.0
        );
        // The skyline is varied (not one flat roofline).
        assert!(stats.max - stats.min > 1e-4, "the real skyline varies (min {} != max {})", stats.min, stats.max);
    }

    let mut view = osm_tabs::osm3d_view(&geo);
    let s = view.state_json();
    eprintln!("osm3d_shot: state triangles={} tiles={}", s["triangles"], s["tiles"]);

    // Install the Map3D GPU **depth** renderer so the same depth-tested path the
    // demo runs draws here — otherwise `osm3d_view`'s `with_gpu(true)` adds a
    // no-op callback (no renderer) and the CPU painter is skipped → a black PNG.
    let mut builder = Harness::builder().with_size(egui::vec2(1000.0, 1000.0));
    #[cfg(feature = "map3d-wgpu")]
    {
        let rs = create_render_state(default_wgpu_setup(), Default::default());
        facett::map3d::gpu::install_renderer(&rs);
        builder = builder.renderer(WgpuTestRenderer::from_render_state(rs));
    }
    let mut harness = builder.build_ui(move |ui| {
        facett::core::set_theme(ui.ctx(), facett::core::Theme::sci_fi());
        view.ui(ui);
    });
    harness.run_steps(8);
    let img = harness.render().expect("wgpu render produced an image");
    image::DynamicImage::ImageRgba8(img)
        .save("/tmp/osm3d_liech.png")
        .expect("save PNG");
    eprintln!("osm3d_shot: saved /tmp/osm3d_liech.png");

    // also a 2D shot for comparison
    let mut v2 = osm_tabs::osm2d_view(&geo);
    let mut h2 = Harness::builder()
        .with_size(egui::vec2(1000.0, 1000.0))
        .build_ui(move |ui| {
            facett::core::set_theme(ui.ctx(), facett::core::Theme::sci_fi());
            v2.ui(ui);
        });
    h2.run_steps(8);
    let img2 = h2.render().expect("2d render");
    image::DynamicImage::ImageRgba8(img2)
        .save("/tmp/osm2d_liech.png")
        .expect("save 2D PNG");
    eprintln!("osm3d_shot: saved /tmp/osm2d_liech.png");
}