feat(#188): fading-wall + sliding-door translucency; hold open past animation settle
Lands the fading-secret-door feature and fixes the door "flip-back" that surfaced while testing it. #188 — fading-wall doors (e.g. "Pedestal Weak Spot") fade their wall part out via TransparentPartHook instead of swinging: - TranslucencyHookSink consumes TransparentPartHook -> TranslucencyFadeManager (per-(entity,part) linear translucency ramp; holds at End frame). - WbDrawDispatcher: new per-instance alpha SSBO (binding 7); ClassifyBatches takes opacityMultiplier (1 - translucency, per CMaterial::SetTranslucencySimple 0x005396f0) forcing AlphaBlend; fully-invisible parts skipped. - mesh_modern.vert/.frag: binding-7 InstanceAlphaBuf -> vOpacityMultiplier -> FragColor.a *= vOpacityMultiplier. - Register AP-89: the fade multiplies sampled texture alpha, not a separate D3D9 material alpha channel (observably identical for texture-alpha==1 surfaces). Door flip-back fix (affected BOTH #188 fading walls AND #187 sliding doors): a door/wall that finished opening holds a single unchanging frame, so the uncommitted IsEntityCurrentlyMoving cache-bypass narrowing dropped it onto the Tier-1 static cache -- which only remembers the REST pose + opacity 1.0 -- snapping it visually shut/opaque while physics stayed open. Reverted that narrowing: every Sequencer entity stays on the per-frame path (live pose + live fade opacity), the known-good pre-optimization behavior. The per-frame CPU cost that narrowing chased was a Debug-build artifact -- Release is GPU-bound (~200 fps in Sawato, measured), so the unconditional add is free where it matters. Left a code comment barring re-introduction. Tests: full Core suite green (2649 passed, 2 skipped). Live visual gate PASSED -- both fading-wall and sliding doors hold open. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e2e285b855
commit
3284dd0aed
12 changed files with 625 additions and 14 deletions
|
|
@ -48,8 +48,10 @@ public class Issue188FadingDoorMotionTableInspectionTests
|
|||
foreach (var t in asm.GetTypes().Where(t => t.Name.Contains("Hook", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
_out.WriteLine($"=== type {t.FullName} (base={t.BaseType?.Name}) ===");
|
||||
foreach (var p in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
_out.WriteLine($" {p.PropertyType.Name} {p.Name}");
|
||||
foreach (var p in t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
|
||||
_out.WriteLine($" [prop] {p.PropertyType.Name} {p.Name}");
|
||||
foreach (var f in t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
|
||||
_out.WriteLine($" [field] {f.FieldType.Name} {f.Name}");
|
||||
}
|
||||
|
||||
void DumpMembers(Type t, string label)
|
||||
|
|
@ -107,6 +109,7 @@ public class Issue188FadingDoorMotionTableInspectionTests
|
|||
if (anim is null) { _out.WriteLine($" [{source}] anim 0x{animId:X8} NOT FOUND"); continue; }
|
||||
|
||||
int frameCount = 0, hookCount = 0;
|
||||
int frameIdx = 0;
|
||||
foreach (var frame in GetFrames(anim))
|
||||
{
|
||||
frameCount++;
|
||||
|
|
@ -114,7 +117,14 @@ public class Issue188FadingDoorMotionTableInspectionTests
|
|||
{
|
||||
hookCount++;
|
||||
hookTypesSeen.Add(hook.GetType().Name);
|
||||
// Dump every field's actual VALUE for this specific hook instance
|
||||
// (not just the type) -- what alpha/duration retail authored.
|
||||
var fieldDump = string.Join(" ", hook.GetType()
|
||||
.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
|
||||
.Select(f => $"{f.Name}={f.GetValue(hook)}"));
|
||||
_out.WriteLine($" frame[{frameIdx}] {hook.GetType().Name}: {fieldDump}");
|
||||
}
|
||||
frameIdx++;
|
||||
}
|
||||
_out.WriteLine($" [{source}] anim 0x{animId:X8}: frames={frameCount} hooks={hookCount}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue