facett-graphview/examples/world_still.rs
//! **world_still** — converge the galaxy layout at a target size and render it once,
//! headless, on the GPU into a PNG (the "mega tier": one nicely-spread still of the whole
//! universe at 100k+). Reuses the shared instanced cloud renderer + the world graph's own
//! galaxy layout + categorical colour. Run:
//!
//! ```bash
//! cargo run -p facett-graphview --features gpu --example world_still --release -- 100000 out.png
//! ```
use std::time::Instant;
use facett_graphview::world::{layout_world, LayoutBudget, Lod, WorldGraph};
use facett_graphview::world_still::{galaxy_3d, render_world_still, render_world_still_3d};
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let target: usize = args.first().and_then(|s| s.parse().ok()).unwrap_or(100_000);
let out = args.get(1).cloned().unwrap_or_else(|| format!("world_still_{target}.png"));
let dark = !args.iter().any(|a| a == "light");
let three_d = args.iter().any(|a| a == "3d");
// The shared offscreen cloud renders under wgpu downlevel limits (max texture 2048).
let dim: u32 = 2048;
let edge_cap = 250_000;
let t0 = Instant::now();
let w = WorldGraph::synthetic(target, Lod::Functions, true);
let build_ms = t0.elapsed().as_secs_f64() * 1e3;
let (rendered, layout_ms, render_ms, lane) = if three_d {
let t1 = Instant::now();
let pos3 = galaxy_3d(&w);
let layout_ms = t1.elapsed().as_secs_f64() * 1e3;
let t2 = Instant::now();
// A three-quarter orbit so the 3D shells read as depth.
let r = render_world_still_3d(&w, &pos3, dim, dim, dark, 0.7, 0.5, edge_cap);
(r, layout_ms, t2.elapsed().as_secs_f64() * 1e3, "galaxy_3d")
} else {
let t1 = Instant::now();
let (pos, lane) = layout_world(&w, &LayoutBudget::default());
let layout_ms = t1.elapsed().as_secs_f64() * 1e3;
let t2 = Instant::now();
let r = render_world_still(&w, &pos, dim, dim, dark, edge_cap);
(r, layout_ms, t2.elapsed().as_secs_f64() * 1e3, lane.key())
};
match rendered {
Some(r) => {
image::save_buffer(&out, &r.rgba, r.width, r.height, image::ColorType::Rgba8)
.expect("write PNG");
println!(
"world_still{}: target={target} nodes={} edges={} lane={lane}\n build={build_ms:.1}ms layout={layout_ms:.1}ms render={render_ms:.1}ms\n drew {} node instances + {} edge instances → {out} ({}x{})",
if three_d { " (3D)" } else { "" },
w.n, w.edges.len(), r.node_instances, r.edge_instances, r.width, r.height
);
}
None => {
eprintln!("world_still: NO usable GPU adapter — 3D/still path builds but needs a device here");
std::process::exit(2);
}
}
}