CLI, along with several examples, plus model downloading
This commit is contained in:
1 parent
4f9e73a418
commit
51ace681a7
22 files changed
+1804
-18
No files matched your search
@@ -0,0 +1,130 @@
|
||||
//! Runs the `resolved` binary on the example scenes.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
fn repo() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR")).join("../..")
|
||||
}
|
||||
|
||||
fn out_dir() -> PathBuf {
|
||||
let dir = PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join("cli");
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
dir
|
||||
}
|
||||
|
||||
/// Runs the binary from the repository root with `ASTROKIT_KERNELS` cleared, so the
|
||||
/// kernel search falls back the way it does for someone who has not set it.
|
||||
fn resolved(args: &[&str]) -> std::process::Output {
|
||||
Command::new(env!("CARGO_BIN_EXE_resolved"))
|
||||
.args(args)
|
||||
.current_dir(repo())
|
||||
.env_remove("ASTROKIT_KERNELS")
|
||||
.output()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Renders `scene` on `adapter` to a 16-bit PNG and returns its pixels as DN (the
|
||||
/// file holds 12-bit DN shifted up by 4).
|
||||
fn render(scene: &str, adapter: &str) -> image::ImageBuffer<image::Rgb<u16>, Vec<u16>> {
|
||||
let out = out_dir().join(format!(
|
||||
"{}-{adapter}.png",
|
||||
Path::new(scene).file_stem().unwrap().to_str().unwrap()
|
||||
));
|
||||
let preview = out.with_extension("preview.png");
|
||||
let result = resolved(&[
|
||||
"render",
|
||||
"--scene",
|
||||
scene,
|
||||
"--adapter",
|
||||
adapter,
|
||||
"--out",
|
||||
out.to_str().unwrap(),
|
||||
"--preview",
|
||||
preview.to_str().unwrap(),
|
||||
]);
|
||||
assert!(
|
||||
result.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&result.stderr)
|
||||
);
|
||||
assert!(preview.is_file());
|
||||
let mut pixels = image::open(&out).unwrap().into_rgb16();
|
||||
for p in pixels.pixels_mut() {
|
||||
assert!(p.0.iter().all(|v| v & 0xf == 0), "low 4 bits are padding");
|
||||
p.0 = p.0.map(|v| v >> 4);
|
||||
}
|
||||
pixels
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_scene_on_gpu_and_cpu() {
|
||||
let gpu = render("examples/scenes/boxwing.toml", "gpu");
|
||||
let cpu = render("examples/scenes/boxwing.toml", "cpu");
|
||||
assert_eq!(gpu.dimensions(), (1920, 1080));
|
||||
// The image center is on the sunlit gold bus: brighter in red than in blue.
|
||||
let [r, _, b] = gpu.get_pixel(960, 540).0;
|
||||
assert!(r > 500 && r > 2 * b, "{r} {b}");
|
||||
// Above the limb is empty space, which reads the 64 DN bias; below it, Earth's
|
||||
// dayside.
|
||||
assert_eq!(gpu.get_pixel(0, 0).0, [64; 3]);
|
||||
assert!(gpu.get_pixel(0, 1079).0.iter().all(|&d| d > 300));
|
||||
let differing = gpu
|
||||
.pixels()
|
||||
.zip(cpu.pixels())
|
||||
.filter(|(a, b)| a.0.iter().zip(b.0).any(|(x, y)| x.abs_diff(y) > 1))
|
||||
.count();
|
||||
// Only pixels on silhouette edges may land differently.
|
||||
assert!(
|
||||
differing < 500,
|
||||
"{differing} pixels differ between GPU and CPU"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "astrokit")]
|
||||
#[test]
|
||||
fn epoch_scene_renders() {
|
||||
let frame = render("examples/scenes/boxwing-epoch.toml", "gpu");
|
||||
// The same view as boxwing.toml, rotated to the real Sun: the sunlit bus at the
|
||||
// center, space above the limb.
|
||||
assert!(frame.get_pixel(960, 540).0[0] > 500);
|
||||
assert_eq!(frame.get_pixel(0, 0).0, [64; 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_are_reported() {
|
||||
let missing = resolved(&["render", "--scene", "no/such.toml", "--preview", "x.png"]);
|
||||
assert!(!missing.status.success());
|
||||
assert!(String::from_utf8_lossy(&missing.stderr).contains("no/such.toml"));
|
||||
|
||||
let idle = resolved(&["render", "--scene", "examples/scenes/boxwing.toml"]);
|
||||
assert!(!idle.status.success());
|
||||
assert!(String::from_utf8_lossy(&idle.stderr).contains("nothing to do"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "astrokit")]
|
||||
#[test]
|
||||
fn missing_kernels_say_where_they_looked() {
|
||||
let result = resolved(&[
|
||||
"render",
|
||||
"--scene",
|
||||
"examples/scenes/boxwing-epoch.toml",
|
||||
"--kernels",
|
||||
"no/such/dir",
|
||||
"--preview",
|
||||
"x.png",
|
||||
]);
|
||||
assert!(!result.status.success());
|
||||
let stderr = String::from_utf8_lossy(&result.stderr);
|
||||
assert!(
|
||||
stderr.contains("--kernels") && stderr.contains("no/such/dir"),
|
||||
"{stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adapters_lists_something() {
|
||||
let result = resolved(&["adapters"]);
|
||||
assert!(result.status.success());
|
||||
assert!(!result.stdout.is_empty());
|
||||
}
|
||||
Reference in new issue
Block a user