held weapons pick, book images size to their art, the panel opens again
- a unit's pick geometry is every model chained to it — body, held items, mount — one candidate per root resolving to the same unit, which is how the reference registers its pick (it walks the attachment tree and registers each model); Naxxramas' floating weapons could only be selected by their name plate before (no body, no candidate), and every armed unit gains its gear as clickable surface (our own body 12 → 21 tested parts); the broad phase stays the body's sphere, so a very long polearm on a small body is the named residual - the selection ring's writer has two branches and we had transcribed one: a model whose stand box is degenerate (zero extent in x and y) rings at the literal 1.2 × scale — 2.7 yd under a trigger creature — instead of `sqrt(0.5·sqrt(dx²+dy²))` = 0 clamped to an invented 0.05 floor; both invented fallbacks are gone - an HTML book image with no width/height is its art's texel square (one texel = one FrameXML unit, bit-for-bit the `<AbsDimension>` converter), not the rest of the page — *A Treatise on Military Ranks* drew its crest twice too big and stretched to the page's aspect; a texture-size oracle answers off the same decoder the renderer draws with, and an unfloated height-less `<IMG>` reserves its art's height in the flow; 797 shipped textures swept, exactly two zero-size axes move and neither is visible - the dev debug panel killed the client on open with "Attachments have differing sample counts": Bevy's 2-D depth texture is keyed on the render target alone, so two Camera2ds on one window at different MSAA counts cannot both be valid, and the egui overlay camera had silently kept the default 4× after the player-UI camera went to Off; it now says `Msaa::Off`, and a preflight check reports any two 2-D cameras that disagree on a shared target, every run Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -67,14 +67,21 @@ fn install_boot_vm(world: &mut World) {
|
||||
world.insert_non_send_resource(script);
|
||||
}
|
||||
|
||||
/// Wire up the two halves of `Interface\AddOns\` texture art (decision 1322): the sprite
|
||||
/// decoder's **loose-file root** (so addon-shipped BLP/TGA files render at all — the store's
|
||||
/// Wire up the halves of `Interface\AddOns\` texture art (decision 1322): the sprite decoder's
|
||||
/// **loose-file root** (so addon-shipped BLP/TGA files render at all — the store's
|
||||
/// [`benilla_assets::WorldAssets::set_loose_sprite_root`]) and the VM's **texture probe** (so the
|
||||
/// path form of `SetTexture` can answer the reference's 1|nil load verdict — Atlas picks its map
|
||||
/// art by that return). Both resolve the same one folder ([`addons::root`], hermetic-`None` under
|
||||
/// `$WOW_CAPTURE`), and the probe walks the same [`benilla_assets::sprite_candidates`] the
|
||||
/// renderer decodes with, so the verdict the Lua caller gets is the verdict the screen shows.
|
||||
///
|
||||
/// The **size probe** beside it is the same oracle answering a different question — how many texels
|
||||
/// wide and tall is the art — which is what lets a region that authored no size on an axis take
|
||||
/// that span from its content, as the client's virtual size getters do (decision 1349, the fix for
|
||||
/// B342's page-sized book crest). It goes through the decoder, so the number layout resolves with
|
||||
/// is the number the screen shows, and memoises per texture key: the ask is per zero-size region
|
||||
/// per resolve, and the answer cannot change for a key that already read.
|
||||
///
|
||||
/// No `WorldAssets` (no client data) means no backend: nothing to install, and the VM's path form
|
||||
/// keeps answering nil — the engine-less truth.
|
||||
fn install_texture_resolvers(world: &mut World, script: &mut UiScript) {
|
||||
@@ -84,6 +91,8 @@ fn install_texture_resolvers(world: &mut World, script: &mut UiScript) {
|
||||
};
|
||||
assets.set_loose_sprite_root(root.clone());
|
||||
let chain = assets.chain.clone();
|
||||
let size_chain = chain.clone();
|
||||
let size_root = root.clone();
|
||||
script.set_texture_probe(Box::new(move |path| {
|
||||
benilla_assets::sprite_candidates(path).iter().any(|c| {
|
||||
chain.lock_recover().contains(c)
|
||||
@@ -92,6 +101,21 @@ fn install_texture_resolvers(world: &mut World, script: &mut UiScript) {
|
||||
.is_some_and(|r| benilla_assets::loose_sprite_file(r, c).is_some())
|
||||
})
|
||||
}));
|
||||
// Keyed by the reference string exactly as the region carries it, so the hit path allocates
|
||||
// nothing: this is asked from inside the layout sweep, once per zero-size textured region per
|
||||
// pass. Two spellings of one file (`Foo` and `Foo.blp`) cost two entries holding the same
|
||||
// number, which is cheaper than normalising every ask to avoid it. Misses are cached too — a
|
||||
// path that resolves to nothing measures nothing however often we look.
|
||||
let sizes: std::cell::RefCell<std::collections::HashMap<String, Option<(u32, u32)>>> =
|
||||
std::cell::RefCell::new(std::collections::HashMap::new());
|
||||
script.set_texture_size_probe(Box::new(move |path| {
|
||||
if let Some(cached) = sizes.borrow().get(path) {
|
||||
return *cached;
|
||||
}
|
||||
let measured = benilla_assets::sprite_dimensions(&size_chain, size_root.as_deref(), path);
|
||||
sizes.borrow_mut().insert(path.to_string(), measured);
|
||||
measured
|
||||
}));
|
||||
}
|
||||
|
||||
/// Does this run want the player UI at all? Captures stay pristine — their baselines regression-test
|
||||
|
||||
Reference in New Issue
Block a user