checkpoint: preserve user-gated FW closeout fixes
This commit is contained in:
parent
a2f2eb7d78
commit
b8befded8b
22 changed files with 1005 additions and 198 deletions
|
|
@ -25,8 +25,9 @@ namespace AcDream.App.Rendering.Walk;
|
|||
/// true eye ray (near/far unprojection) are observably equivalent to
|
||||
/// retail's exact construction for this contract.
|
||||
///
|
||||
/// One instance is a per-frame value (like <c>WalkTraceReplayContext</c>):
|
||||
/// construct fresh each frame with that frame's camera pose.
|
||||
/// Production retains one instance per renderer and rebinds its frame-local
|
||||
/// camera values through <see cref="Reset"/>. The registries and grow-only
|
||||
/// active-view scratch remain renderer-lifetime owners.
|
||||
/// </summary>
|
||||
public sealed class WalkProductionFrameContext : IWalkFrameContext, IRetailFrameWalkContext
|
||||
{
|
||||
|
|
@ -35,19 +36,28 @@ public sealed class WalkProductionFrameContext : IWalkFrameContext, IRetailFrame
|
|||
|
||||
private sealed class InverseViewProjectionRayCaster : IWalkRayCaster
|
||||
{
|
||||
private readonly Matrix4x4 _inverseViewProjection;
|
||||
private readonly float _viewportWidth;
|
||||
private readonly float _viewportHeight;
|
||||
private Matrix4x4 _inverseViewProjection;
|
||||
private float _viewportWidth;
|
||||
private float _viewportHeight;
|
||||
|
||||
public InverseViewProjectionRayCaster(
|
||||
Matrix4x4 viewProjection, float viewportWidth, float viewportHeight)
|
||||
=> Reset(viewProjection, viewportWidth, viewportHeight);
|
||||
|
||||
internal void Reset(
|
||||
Matrix4x4 viewProjection, float viewportWidth, float viewportHeight)
|
||||
{
|
||||
if (!Matrix4x4.Invert(viewProjection, out _inverseViewProjection))
|
||||
if (!Matrix4x4.Invert(viewProjection, out Matrix4x4 inverseViewProjection))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The walk's view-projection matrix must be invertible.",
|
||||
nameof(viewProjection));
|
||||
}
|
||||
// Publish only after validation succeeds. Matrix4x4.Invert writes
|
||||
// its out value even on failure; assigning the field directly
|
||||
// would silently corrupt the retained ray caster for the next
|
||||
// report-and-continue frame.
|
||||
_inverseViewProjection = inverseViewProjection;
|
||||
_viewportWidth = viewportWidth;
|
||||
_viewportHeight = viewportHeight;
|
||||
}
|
||||
|
|
@ -72,8 +82,8 @@ public sealed class WalkProductionFrameContext : IWalkFrameContext, IRetailFrame
|
|||
|
||||
private readonly CellVisibility _cells;
|
||||
private readonly WalkBuildingRegistry _buildings;
|
||||
private readonly Matrix4x4 _viewProjection;
|
||||
private readonly IWalkRayCaster _rays;
|
||||
private Matrix4x4 _viewProjection;
|
||||
private readonly InverseViewProjectionRayCaster _rays;
|
||||
|
||||
private Vector2[] _activeViewVerts = new Vector2[32];
|
||||
private int _activeViewVertCount;
|
||||
|
|
@ -89,19 +99,39 @@ public sealed class WalkProductionFrameContext : IWalkFrameContext, IRetailFrame
|
|||
{
|
||||
_cells = cells ?? throw new ArgumentNullException(nameof(cells));
|
||||
_buildings = buildings ?? throw new ArgumentNullException(nameof(buildings));
|
||||
_rays = new InverseViewProjectionRayCaster(
|
||||
viewProjection, viewportWidth, viewportHeight);
|
||||
Reset(worldViewpoint, forward, viewProjection, viewportWidth, viewportHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// FW6 allocation closeout: rebind this retained context to one frame's
|
||||
/// camera values while preserving its active-view scratch. The cell and
|
||||
/// building registries are lifetime owners and therefore never change.
|
||||
/// </summary>
|
||||
internal void Reset(
|
||||
Vector3 worldViewpoint,
|
||||
Vector3 forward,
|
||||
Matrix4x4 viewProjection,
|
||||
float viewportWidth,
|
||||
float viewportHeight)
|
||||
{
|
||||
// Validate/invert before publishing any new frame value so a bad
|
||||
// camera matrix leaves the previous usable binding intact.
|
||||
_rays.Reset(viewProjection, viewportWidth, viewportHeight);
|
||||
WorldViewpoint = worldViewpoint;
|
||||
_viewProjection = viewProjection;
|
||||
ViewportWidth = viewportWidth;
|
||||
ViewportHeight = viewportHeight;
|
||||
_rays = new InverseViewProjectionRayCaster(viewProjection, viewportWidth, viewportHeight);
|
||||
_activeViewVertCount = 0;
|
||||
// The retail CY near plane: N = forward, d = -dot(eye, forward) - znear.
|
||||
CyPlane = new WalkPlane(forward, -Vector3.Dot(worldViewpoint, forward) - ZNear);
|
||||
}
|
||||
|
||||
public Vector3 WorldViewpoint { get; }
|
||||
public float ViewportWidth { get; }
|
||||
public float ViewportHeight { get; }
|
||||
public WalkPlane CyPlane { get; }
|
||||
public Vector3 WorldViewpoint { get; private set; }
|
||||
public float ViewportWidth { get; private set; }
|
||||
public float ViewportHeight { get; private set; }
|
||||
public WalkPlane CyPlane { get; private set; }
|
||||
public IWalkRayCaster Rays => _rays;
|
||||
public IWalkFrameContext CellContext => this;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue