feat(world): port retail portal-space viewport
Replace the opaque teleport cover with the DAT-authored CreatureMode tunnel, exact retail camera/light/animation timing and easing, and animation-hook audio routing. Compose portal and fade passes below retained UI so gameplay windows and input remain active through F751 travel. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
0eab7497c1
commit
eab23cbdd1
14 changed files with 983 additions and 45 deletions
|
|
@ -221,7 +221,8 @@ public sealed class GameWindow : IDisposable
|
|||
// each frame on an indoor root (null on the outdoor root).
|
||||
private AcDream.App.Rendering.RetailPViewRenderer? _retailPViewRenderer;
|
||||
private AcDream.App.Rendering.PortalDepthMaskRenderer? _portalDepthMask;
|
||||
private AcDream.App.Rendering.FadeOverlay? _fadeOverlay; // teleport fade cover (spec C)
|
||||
private AcDream.App.Rendering.PortalTunnelPresentation? _portalTunnel;
|
||||
private AcDream.App.Rendering.FadeOverlay? _fadeOverlay;
|
||||
private AcDream.App.Rendering.InteriorEntityPartition.Result? _interiorPartition;
|
||||
|
||||
// Phase U.3: the shared per-frame clip data (binding=2 mesh SSBO + terrain
|
||||
|
|
@ -2588,6 +2589,14 @@ public sealed class GameWindow : IDisposable
|
|||
// DrawPortalPolyInternal (Ghidra 0x0059bc90).
|
||||
_portalDepthMask = new AcDream.App.Rendering.PortalDepthMaskRenderer(_gl);
|
||||
_fadeOverlay = new AcDream.App.Rendering.FadeOverlay(_gl);
|
||||
_portalTunnel = AcDream.App.Rendering.PortalTunnelPresentation.TryCreate(
|
||||
_gl,
|
||||
_dats!,
|
||||
_animLoader!,
|
||||
_hookRouter,
|
||||
_wbDrawDispatcher,
|
||||
_sceneLightingUbo!,
|
||||
_wbMeshAdapter!);
|
||||
}
|
||||
|
||||
// Phase G.1 sky renderer — its own shader (sky.vert / sky.frag)
|
||||
|
|
@ -8872,9 +8881,9 @@ public sealed class GameWindow : IDisposable
|
|||
// destination landblock this frame) and the live-session drain, so a destination
|
||||
// that became resident this frame materializes the same frame. The TAS holds at
|
||||
// Tunnel until worldReady, fires Place (materialize, hidden), then after the min-
|
||||
// continue + fades fires FireLoginComplete (regain control + ack). The fade overlay
|
||||
// is opaque black during the tunnel states (we render a fade, not the 3D swirl) and
|
||||
// ramps the world back in on WorldFadeIn.
|
||||
// continue + fades fires FireLoginComplete (regain control + ack). PortalTunnelPresentation
|
||||
// replaces the world viewport through the tunnel-family states; FadeOverlay transitions
|
||||
// between the two viewports below the retained UI.
|
||||
if (_teleportInProgress)
|
||||
{
|
||||
bool haveDest = _pendingTeleportCell != 0u;
|
||||
|
|
@ -8889,8 +8898,14 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
var (snap, evts) = _teleportAnim.Tick((float)dt, ready);
|
||||
_teleportFadeAlpha = snap.ShowTunnel ? 1f : snap.FadeAlpha;
|
||||
int tunnelFrame = _portalTunnel?.CurrentAnimationFrame ?? 0;
|
||||
var (snap, evts) = _teleportAnim.Tick((float)dt, ready, tunnelFrame);
|
||||
// The fade is a viewport transition below retained UI. If the
|
||||
// installed DATs are corrupt and the retail portal scene could
|
||||
// not be built, retain an opaque world cover during transit.
|
||||
_teleportFadeAlpha = _portalTunnel is null && snap.ShowTunnel
|
||||
? 1f
|
||||
: snap.FadeAlpha;
|
||||
|
||||
foreach (var e in evts)
|
||||
{
|
||||
|
|
@ -8904,6 +8919,12 @@ public sealed class GameWindow : IDisposable
|
|||
_streamingController.PriorityRadius = 0;
|
||||
}
|
||||
break;
|
||||
case AcDream.Core.World.TeleportAnimEvent.EnterTunnel:
|
||||
_portalTunnel?.Enter();
|
||||
break;
|
||||
case AcDream.Core.World.TeleportAnimEvent.PlayExitSound:
|
||||
_portalTunnel?.Exit();
|
||||
break;
|
||||
case AcDream.Core.World.TeleportAnimEvent.FireLoginComplete:
|
||||
if (_playerController is not null)
|
||||
_playerController.State = AcDream.App.Input.PlayerState.InWorld;
|
||||
|
|
@ -8916,10 +8937,14 @@ public sealed class GameWindow : IDisposable
|
|||
_teleportFadeAlpha = 0f;
|
||||
break;
|
||||
default:
|
||||
// PlayEnterSound / EnterTunnel / PlayExitSound — audio polish deferred.
|
||||
// The retained audio engine does not yet own the
|
||||
// ClientUISystem sound-table enum path. Enter/exit
|
||||
// visual edges are handled above.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_portalTunnel?.Tick((float)dt);
|
||||
}
|
||||
|
||||
// Phase K.1a — tick the input dispatcher so Hold-type bindings
|
||||
|
|
@ -10455,6 +10480,16 @@ public sealed class GameWindow : IDisposable
|
|||
SkipWorldGeometry: ;
|
||||
}
|
||||
|
||||
// Retail gmSmartBoxUI swaps the world SmartBox viewport for a
|
||||
// CreatureMode portal-space viewport. This replacement scene and
|
||||
// its black transition draw BEFORE retained UI, so chat, windows,
|
||||
// cursor, and toolbar remain visible and interactive in transit.
|
||||
_portalTunnel?.Draw(
|
||||
_window!.Size.X,
|
||||
_window.Size.Y,
|
||||
_cameraController!.Active.Projection);
|
||||
_fadeOverlay?.Draw(_teleportFadeAlpha);
|
||||
|
||||
// Phase D.2b Sub-phase C Slice 2 — paperdoll 3-D doll: render the re-dressed player clone into the
|
||||
// viewport's off-screen texture BEFORE the 2-D UI pass blits it, but only when the inventory window
|
||||
// is open AND the paperdoll is in doll-view (the widget's Visible is driven by the Slots toggle).
|
||||
|
|
@ -10481,11 +10516,6 @@ public sealed class GameWindow : IDisposable
|
|||
_retailUiRuntime.Draw(new System.Numerics.Vector2(_window!.Size.X, _window.Size.Y));
|
||||
}
|
||||
|
||||
// Teleport fade cover (retail-teleport spec C). Drawn AFTER the world + retail UI so
|
||||
// it covers them during a transit; the ImGui devtools below composite on top so they
|
||||
// stay visible for debugging. Alpha is 0 outside a teleport → Draw is a no-op.
|
||||
_fadeOverlay?.Draw(_teleportFadeAlpha);
|
||||
|
||||
// Phase D.2a — end ImGui frame. Runs AFTER all scene + debug draws
|
||||
// so ImGui composites on top. ImGuiController save/restores the
|
||||
// GL state it touches (blend, scissor, VAO, shader, texture); any
|
||||
|
|
@ -14649,6 +14679,8 @@ public sealed class GameWindow : IDisposable
|
|||
_effectPoses.Clear();
|
||||
}
|
||||
_audioEngine?.Dispose(); // Phase E.2: stop all voices, close AL context
|
||||
_portalTunnel?.Dispose();
|
||||
_portalTunnel = null;
|
||||
_wbDrawDispatcher?.Dispose();
|
||||
_envCellRenderer?.Dispose(); // Phase A8
|
||||
_portalDepthMask?.Dispose(); // T1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue