use mercs2_engine::model::Model;
use mercs2_engine::render_state::RenderState;
use mercs2_engine::wad;
use mercs2_formats::orchestrator as orch;
const MODELS: &[&str] = &[
"ch_veh_tank_ztz98",
"oc_veh_helicopter_md500",
"global_veh_klr650",
"civ_veh_car_van_crappy",
"al_veh_boat_destroyer",
"pmc_hum_mattias_v3",
];
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let names: Vec<String> =
if args.is_empty() { MODELS.iter().map(|s| s.to_string()).collect() } else { args };
let mut w = wad::resolve_vz_wad(None).and_then(|p| wad::open(&p).ok()).expect("vz.wad");
for name in &names {
let hash = mercs2_formats::hash::pandemic_hash_m2(name.trim_start_matches('_'));
let m = match Model::load(&mut w, hash) {
Ok(m) => m,
Err(e) => {
println!("{name}: {e}\n");
continue;
}
};
println!(
"{name} — {} rung(s), {} tri total, {} HIER, {} SEGM, lod_count {}",
m.rungs.len(),
m.triangles(),
m.hier.len(),
m.segm.len(),
m.lod_count()
);
for r in &m.rungs {
let (mut lo, mut hi) = ([f32::MAX; 3], [f32::MIN; 3]);
for v in &r.vertices {
for i in 0..3 {
lo[i] = lo[i].min(v.pos[i]);
hi[i] = hi[i].max(v.pos[i]);
}
}
println!(
" bbox min [{:7.2} {:7.2} {:7.2}] max [{:7.2} {:7.2} {:7.2}]",
lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]
);
println!(
" P{:03} block {:5} {:6} tri serves rungs {:?}",
r.level,
r.block,
r.triangles(),
(0..8u8).filter(|b| r.lod_bits() & (1 << b) != 0).collect::<Vec<_>>()
);
let mut hist: std::collections::BTreeMap<u8, (usize, u32, usize)> = Default::default();
for d in &r.draws {
let e = hist.entry(d.lod_mask).or_insert((0, 0, usize::MAX));
e.0 += 1;
e.1 += d.index_count / 3;
e.2 = e.2.min(d.group_index);
}
for (mask, (n, tris, _)) in &hist {
println!(" mask {mask:#04x} {n:3} draws {tris:6} tri");
}
}
print!(" {:>10}", "LOD rung");
for n in 0..m.lod_count().min(8) {
print!(" {:>8}", n);
}
println!();
for (label, health) in [("intact", 1.0f32), ("wrecked", 0.0)] {
let node_enable = match &m.machine {
Some(sm) => {
let chosen = orch::node_states_for_health(sm, health, 0.99);
orch::machine_node_enable(sm, &m.hier, &chosen)
}
None => Vec::new(),
};
print!(" {label:>10}");
for n in 0..m.lod_count().min(8) {
let rs = RenderState {
lod: n as u8,
view_state: 1u8 << (n.min(7)),
node_enable: node_enable.clone(),
};
let tris: u32 =
m.visible_draws(&rs).iter().map(|(_, d)| d.index_count / 3).sum();
print!(" {tris:>8}");
}
println!();
}
println!();
}
}