Files
benilla-octo/crates/benilla-m2/examples/dump_skin.rs
T
SamandClaude Fable 5.1 00150c55b5 a crash leaves a report, and the wire's counts are capped
- a panic writes benilla-config/Diagnostics/crash-<time>.txt with the build id, the location, a backtrace and the last 200 log lines, and names the file as its last line, so a bug report can attach it (2266)
- every wire-count allocation hint is capped and the compressed update object reads through the cursor, so a malformed packet can no longer ask for gigabytes (2266)
- the 23 in-world run conditions are one set, the 45 probe variables one registry, the install-gated tests say when they skip, and every gate is timed (2266)
- one workspace-level lint allowance replaces 413 per-site attributes, and the decision corpus gets a lint in the gate (2266)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 16:38:59 +07:00

71 lines
2.5 KiB
Rust

//! Session probe: dump an M2's skin-0 sections/batches with material + texture resolution —
//! `cargo run -p benilla-m2 --example dump_skin <file.m2>`. Extract the file first via `mpqx`
//! (benilla-mpq). Built for the bowstring round (decision 2273 follow-up), kept because "why is
//! this submesh (not) rendering" keeps coming up.
use std::io::Cursor;
fn main() {
let path = std::env::args().nth(1).expect("usage: dump_skin <file.m2>");
let data = std::fs::read(&path).expect("read m2");
let m2 = benilla_m2::parse_m2(&mut Cursor::new(data.as_slice())).expect("parse m2");
let model = m2.model();
println!("textures: {}", model.textures.len());
for (i, t) in model.textures.iter().enumerate() {
use benilla_m2::M2TextureType as T;
let ty = match t.texture_type {
T::Hardcoded => "hardcoded".to_string(),
T::Monster1 => "monster1".to_string(),
T::Monster2 => "monster2".to_string(),
T::Monster3 => "monster3".to_string(),
T::Other(v) => format!("other({v})"),
};
println!(
" tex {i}: type {ty} file {:?}",
t.filename.string.to_string_lossy()
);
}
println!("materials: {}", model.materials.len());
for (i, m) in model.materials.iter().enumerate() {
println!(
" mat {i}: flags {:#06x} blend {}",
m.flags.bits(),
m.blend_mode.bits()
);
}
println!(
"colors: {} transparency tracks: {} (lookup {:?})",
model.color_alpha_tracks.len(),
model.transparency_tracks.len(),
model.transparency_lookup
);
println!(
"texture_lookup_table: {:?}",
model.raw_data.texture_lookup_table
);
let skin = model.parse_embedded_skin(&data, 0).expect("skin 0");
println!(
"skin 0: {} sections, {} batches",
skin.submeshes().len(),
skin.batches().len()
);
for (i, s) in skin.submeshes().iter().enumerate() {
println!(
" section {i}: id {} tri_start {} tri_count {}",
s.id, s.triangle_start, s.triangle_count
);
}
for (i, b) in skin.batches().iter().enumerate() {
println!(
" batch {i}: section {} tex_combo {} mat {} color {} weight_combo {} tex_count {} uvanim {}",
b.skin_section_index,
b.texture_combo_index,
b.material_index,
b.color_index,
b.weight_combo_index,
b.texture_count,
b.texture_transform_combo_index
);
}
}