The wai-rs module behind the feature splat_exact: the asset read as a compression extension of KHR_gaussian_splatting, the decode through the envelope's pin, the fixed-point camera, projection, order and integer compositing, the identity set the corpus carries authored scenes with, the commitment and view statement records, and a float renderer of the same model for measurement. The corpus live-conformance/splat/ written by wai_splat_exact_vectors gen, and its second implementation splat_exact_verify.py with its own integer renderer. Synthesis origin claims may now name volumetric media. Co-Authored-By: Claude Opus 5.5 <[email protected]>
76 lines
3.2 KiB
Rust
76 lines
3.2 KiB
Rust
//! Exact splats (extensions/splat-exact.md): the corpus regenerates byte for byte, every case
|
|
//! gets its stated outcome, the extension's reason table lists exactly the reference's codes,
|
|
//! the renderer's frame does not depend on the tiles' order, and the extension's draft schema
|
|
//! names the members §3.2 gives the extension object.
|
|
#![cfg(feature = "splat_exact")]
|
|
|
|
use std::collections::BTreeMap;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use wai::splat_exact::{self as se, corpus, Reason};
|
|
|
|
fn wai_dir() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
|
|
}
|
|
|
|
fn walk(dir: &Path, rel: &str, out: &mut BTreeMap<String, Vec<u8>>) {
|
|
for e in std::fs::read_dir(dir).expect("the corpus") {
|
|
let e = e.unwrap();
|
|
let name = e.file_name().to_string_lossy().into_owned();
|
|
let r = if rel.is_empty() { name.clone() } else { format!("{rel}/{name}") };
|
|
if e.file_type().unwrap().is_dir() {
|
|
walk(&e.path(), &r, out);
|
|
} else if r != "README.md" {
|
|
out.insert(r, std::fs::read(e.path()).unwrap());
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn the_corpus_regenerates_and_every_case_gets_its_outcome() {
|
|
let mut files = BTreeMap::new();
|
|
walk(&wai_dir().join("live-conformance/splat"), "", &mut files);
|
|
let generated: BTreeMap<String, Vec<u8>> = corpus::generate().into_iter().collect();
|
|
let differ: Vec<&String> = files.keys().chain(generated.keys()).filter(|k| files.get(*k) != generated.get(*k)).collect();
|
|
assert!(differ.is_empty(), "files that do not regenerate: {differ:?}");
|
|
let fails = corpus::verify(&files);
|
|
assert!(fails.is_empty(), "{fails:?}");
|
|
}
|
|
|
|
#[test]
|
|
fn the_reason_table_is_the_reference_codes() {
|
|
let text = std::fs::read_to_string(wai_dir().join("extensions/splat-exact.md")).unwrap();
|
|
let start = text.find("## 10. Reasons").expect("§10");
|
|
let end = text[start..].find("\n## 11.").map(|i| start + i).unwrap();
|
|
let codes: Vec<&str> = text[start..end]
|
|
.lines()
|
|
.filter_map(|l| l.strip_prefix("| `"))
|
|
.filter_map(|l| l.split('`').next())
|
|
.collect();
|
|
let want: Vec<&str> = Reason::ALL.iter().map(|r| r.code()).collect();
|
|
assert_eq!(codes, want);
|
|
}
|
|
|
|
#[test]
|
|
fn tiles_do_not_change_a_frame() {
|
|
for (name, planes, poses) in corpus::scenes() {
|
|
let gs = se::gaussians(&planes).unwrap();
|
|
for p in &poses {
|
|
let cam = se::Camera::new(p).unwrap();
|
|
let list = se::screens(&gs, p, &cam, se::Variant::default());
|
|
assert_eq!(se::composite(&list, p.width, p.height), se::composite_tiled(&list, p.width, p.height), "{name}");
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn the_draft_schema_names_the_members() {
|
|
let path = wai_dir().join("extensions/gltf/EXT_gaussian_splatting_compression_wai.schema.json");
|
|
let s: serde_json::Value = serde_json::from_slice(&std::fs::read(path).unwrap()).unwrap();
|
|
let mut props: Vec<&str> = s["properties"].as_object().unwrap().keys().map(String::as_str).collect();
|
|
props.sort();
|
|
assert_eq!(props, ["bufferView", "capability", "commitment", "extensions", "extras", "object", "set"]);
|
|
let mut req: Vec<&str> = s["required"].as_array().unwrap().iter().map(|v| v.as_str().unwrap()).collect();
|
|
req.sort();
|
|
assert_eq!(req, ["bufferView", "capability", "object", "set"]);
|
|
}
|