Shadow: tag tshd proxies in the LOADER (V toggle broke the pipeline)

User report: the shadow broke MID-SESSION -- suddenly solid opaque black and
buried on any slope.  The session log pinned the trigger: pressing V.  The
view toggle (SetViewInside) RELOADS every segment mesh through the object
loader and swaps them into the render tree -- including blh_tshd.bgf -- and
the reload path never called SetIsShadow(1) (only the original tree-build
call site tagged it).  Untagged, the entire shadow pipeline disengages: no
translucent TFACTOR state block (solid black), no depth bias (buried), wrong
pass.  The damage-swap reloads had the same hole.

Fix: tag *tshd* filenames in LoadObjectBGF itself, next to the existing
all-shadow-material detector (which misses the mech proxy -- plain black
material, not shadow_mtl).  Every load path -- build, damage swap, view
toggle -- now yields a tagged object; the drawOps alphaTest routing reads
the flag downstream.  User-verified live: the shadow survives repeated V
toggles, translucent and slope-correct.

This also likely explains the RECURRING "shadow vanishes on inclines"
reports: any V toggle silently broke it; every relaunch "fixed" it.  KB
(locomotion.md): loader-level tag recorded as co-dependent part 5 of the
shadow arrangement; the vanish-diagnostic note now lists all three causes
(reload untag / gait desync / genuine burial) with check-first guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-09 17:10:33 -05:00
co-authored by Claude Fable 5
parent b6fe686b22
commit 47aede3094
2 changed files with 23 additions and 4 deletions
+12 -4
View File
@@ -102,12 +102,20 @@ co-dependent parts — change one, re-check the others:
bias can never paint the shadow OVER the feet, structurally.
4. **BIAS pairing** (L4D3D.cpp): tilt on (default) → decal epsilon 0.0008; `BT_SHADOW_TILT=0`
(flat A/B fallback) → the old 0.004 it needs to survive slope burial. `BT_SHADOW_BIAS` overrides.
5. **LOADER-LEVEL TAG** (L4D3D.cpp `LoadObjectBGF`): `*tshd*` filenames get `SetIsShadow(1)` in the
LOADER, not at call sites. The V VIEW TOGGLE (`SetViewInside`) and the damage swaps RELOAD segment
meshes; an untagged reload disengages the whole pipeline — solid opaque black, no bias, buried on
any slope ("shadow broke mid-session after pressing V", user-confirmed fixed). The all-shadow-
material detector misses the mech proxy (plain black material, not shadow_mtl). [T2]
Polar maps have STUB `*_tshd` (shadow authored-off on snow). The visual-ground conform (`btvisgnd.cpp`)
stays render-only (never touches localOrigin). [T2]
**"Shadow vanishes on inclines" can also be a GAIT-DESYNC symptom.** The first 2026-07-09 recurrence
CO-RESOLVED with the gait v5 fix (no shadow code changed): a popping root pose (out-of-phase leg
channel showing through) can push the quad past the bias margin. Check `[sync]`/`BT_SYNC_LOG` for
channel drift before touching the shadow itself. [T2 observation; mechanism T4]
**"Shadow vanishes on inclines" now has THREE confirmed/suspected causes — diagnose before fixing:**
(a) the V-toggle/reload UNTAG above (solid black + buried; broke mid-session; the likeliest cause of
the recurring reports — a relaunch always "fixed" it because the fresh build re-tagged); (b) gait
desync popping the displayed root pose past the bias margin (the first 2026-07-09 recurrence co-
resolved with gait v5, no shadow code changed — though (a) may have contributed) [T2 obs; mechanism
T4]; (c) genuine slope burial when the quad is flat/mis-tilted (the depth-bias margin is finite).
Check `[shadowobj]` tag lines and `[sync]`/`BT_SYNC_LOG` before touching bias/tilt.
## Key Relationships
- Detail: `docs/P3_LOCOMOTION.md`. Uses: [[asset-formats]] (SKL/ANI), [[decomp-reference]] (offsets).
+11
View File
@@ -331,6 +331,17 @@ d3d_OBJECT* d3d_OBJECT::LoadObjectBGF(LPDIRECT3DDEVICE9 device, char *fileName)
bool allShadow = !data.batches.empty();
for (size_t bi = 0; bi < data.batches.size() && allShadow; ++bi)
if (!data.batches[bi].shadowMat) allShadow = false;
// MECH SHADOW PROXIES (*_tshd.bgf) tag by FILENAME here in the loader
// (task #49b): the mech proxy uses a plain black material (not
// shadow_mtl), so the all-shadow-material detector above misses it.
// The render-tree build used to tag it at its own call site -- but the
// VIEW TOGGLE (SetViewInside) and the damage swaps RELOAD segment
// meshes through this loader and swapped in an UNTAGGED object: solid
// opaque black, no depth bias, buried on slopes (the "shadow broke
// mid-session after pressing V" report). Tagging at load covers every
// caller; the drawOps' alphaTest routing below reads the flag.
if (!allShadow && fileName != NULL && strstr(fileName, "tshd") != NULL)
allShadow = true;
if (allShadow)
{
object->SetIsShadow(1);