//! Do real index buffers address their whole vertex pool? //! //! `validate_block` rejects a block whose indices reach fewer than `vtx_count−4` //! vertices ("buffer not covered"). That gate is the furthest-reached rejection //! for a handful of resources that never decode — so the question is whether it //! is well founded. This measures the slack on every block that DOES decode: if //! real geometry always covers its pool, under-coverage is good evidence of a //! wrong candidate and the gate stands. use sylpheed_formats::mesh::Xbg7Model; use std::collections::BTreeMap; fn main() { let dir = std::env::args().nth(1).expect("resource3d dir"); let mut files: Vec<_> = std::fs::read_dir(&dir) .unwrap() .flatten() .map(|e| e.path()) .filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr")) .collect(); files.sort(); let mut hist: BTreeMap = BTreeMap::new(); let mut worst: Vec<(i64, String)> = Vec::new(); for f in &files { let Ok(bytes) = std::fs::read(f) else { continue }; for m in Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false) { for sub in &m.meshes { if sub.positions.is_empty() || sub.indices.is_empty() { continue; } let max_idx = *sub.indices.iter().max().unwrap() as i64; let slack = sub.positions.len() as i64 - 1 - max_idx; *hist.entry(slack.min(20)).or_default() += 1; if slack > 4 { worst.push((slack, format!("{} in {}", m.name, f.file_name().unwrap().to_string_lossy()))); } } } } println!("unreferenced tail vertices (vtx_count − 1 − max index), over decoded sub-meshes:"); for (slack, n) in &hist { println!(" {:>3}{} : {n}", slack, if *slack == 20 { "+" } else { " " }); } worst.sort_by_key(|(s, _)| std::cmp::Reverse(*s)); for (s, w) in worst.iter().take(5) { println!(" largest slack {s}: {w}"); } }