Files
benilla-octo/crates/benilla-formats/tests/m2_env_map.rs
T
SamandClaude Fable 5 6b980b9efb the player build: one binary that carries its content
- a player build ships beside the dev one — dev chords and probe surfaces go dark, and a gate enforces what a player can still reach, by medium not by module
- the binary carries its own shaders and its shipped UI, finds the WoW folder by itself, and keeps its local state in one benilla-config folder
- the glue screens get a capture shutter, and the engine stops depending on the protocol crate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 18:18:02 +07:00

71 lines
3.0 KiB
Rust

//! Difftest the M2 **generated-texcoord** (environment-map) detection against real art — the
//! `texCoordSet(+0x12) → texture_unit_lookup(0x9c)` two-hop the reference gates at `0x70b8bd`
//! (`<= 2` = a vertex UV channel, higher = a generated env coordinate).
//!
//! Both halves matter, and only real art proves them. The Deeprun Tram's glass tube is the
//! **positive**: it authors `texture_unit_lookup = [-1]` and, precisely because the runtime is
//! meant to supply the coordinates, leaves **every one of its 330 vertices at exactly (0,0)** — so
//! a renderer that misses the flag paints the whole tube in one corner texel of a reflection sheet
//! (`AKGNOMEREFLECT.BLP` texel 0,0 = 225,221,142, doubled by the batch's Mod2x blend: the flat
//! yellow). The weapon rack is the **discriminator**: the same model carries both kinds, so a
//! parse that simply answered "env" everywhere would pass the first assert and fail here.
//!
//! Skips (passes) when the client isn't present at `<repo>/WoW/Data`.
use benilla_formats::{load_m2_mesh, open_chain};
#[test]
fn tram_glass_batches_generate_their_texcoords() {
let data = benilla_formats::wow_data_or_skip!();
let mut chain = open_chain(&data).expect("open vanilla patch chain");
let subs = load_m2_mesh(
&mut chain,
"World\\Generic\\Gnome\\Passive Doodads\\GnomeMachine\\GnomeSubwayGlass.m2",
)
.expect("load GnomeSubwayGlass");
assert!(!subs.is_empty(), "the glass tube has render batches");
assert!(
subs.iter().all(|s| s.env_map),
"every GnomeSubwayGlass batch authors texture_unit_lookup = -1 (generated texcoords)"
);
// The half that makes the flag load-bearing rather than cosmetic: there is no fallback here,
// because the authored UVs carry no information at all.
for s in &subs {
assert!(
s.uvs.iter().all(|uv| uv[0] == 0.0 && uv[1] == 0.0),
"an env-mapped batch's authored UVs are degenerate — the runtime supplies them"
);
}
}
#[test]
fn weapon_rack_splits_env_from_uv_batches() {
let data = benilla_formats::wow_data_or_skip!();
let mut chain = open_chain(&data).expect("open vanilla patch chain");
let subs = load_m2_mesh(
&mut chain,
"World\\Generic\\Human\\Passive Doodads\\WeaponRacks\\GeneralWeaponrack01.m2",
)
.expect("load GeneralWeaponrack01");
// `texture_unit_lookup = [0, -1]`: the rack/blade batches name UV channel 0, the two
// ARMORREFLECT sheen layers (`texCoordSet 1`) generate theirs.
let env: Vec<&str> = subs
.iter()
.filter(|s| s.env_map)
.filter_map(|s| s.texture.as_deref())
.collect();
assert!(
!env.is_empty()
&& env
.iter()
.all(|t| t.to_ascii_lowercase().contains("armorreflect")),
"only the ARMORREFLECT sheen layers env-map on the rack, got {env:?}"
);
assert!(
subs.iter().any(|s| !s.env_map),
"the rack's body and blade batches read their authored UVs"
);
}