feat(runtime): seal dormant SetPosition evaluations
This commit is contained in:
parent
22651c823d
commit
99f867f053
16 changed files with 2298 additions and 62 deletions
|
|
@ -224,7 +224,22 @@ public sealed class PhysicsEngine
|
|||
/// when the restriction weenie can't be resolved — so production MUST
|
||||
/// wire this to the live table for the fix to actually admit anyone.
|
||||
/// </summary>
|
||||
public ClientObjectTable? Objects { get; set; }
|
||||
private ClientObjectTable? _objects;
|
||||
private ulong _objectsBindingRevision;
|
||||
|
||||
public ClientObjectTable? Objects
|
||||
{
|
||||
get => _objects;
|
||||
set
|
||||
{
|
||||
if (ReferenceEquals(_objects, value))
|
||||
return;
|
||||
_objects = value;
|
||||
_objectsBindingRevision = checked(_objectsBindingRevision + 1UL);
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong ObjectsBindingRevision => _objectsBindingRevision;
|
||||
|
||||
internal sealed record LandblockPhysics(
|
||||
TerrainSurface Terrain,
|
||||
|
|
@ -1553,8 +1568,10 @@ public sealed class PhysicsEngine
|
|||
private AdjustedSetPosition AdjustSetPosition(
|
||||
uint seedCellId,
|
||||
Vector3 cellLocalPosition,
|
||||
Vector3 firstWorldSphereCenter)
|
||||
Vector3 firstWorldSphereCenter,
|
||||
CellArray queryFootprint)
|
||||
{
|
||||
queryFootprint.Add(seedCellId);
|
||||
uint low = seedCellId & 0xFFFFu;
|
||||
bool lowInRange = low is (>= 1u and <= 0x40u)
|
||||
or (>= 0x0100u and <= 0xFFFDu)
|
||||
|
|
@ -1582,7 +1599,8 @@ public sealed class PhysicsEngine
|
|||
cache,
|
||||
seedCellId,
|
||||
firstWorldSphereCenter,
|
||||
useStabList: true);
|
||||
useStabList: true,
|
||||
queryFootprint);
|
||||
if (child != 0u)
|
||||
{
|
||||
return new AdjustedSetPosition(
|
||||
|
|
@ -1606,6 +1624,7 @@ public sealed class PhysicsEngine
|
|||
bool adjusted = LandDefs.AdjustToOutside(
|
||||
ref adjustedCell,
|
||||
ref adjustedLocal);
|
||||
queryFootprint.Add(adjustedCell);
|
||||
bool resident = adjusted
|
||||
&& IsLandblockTerrainResident(adjustedCell);
|
||||
return new AdjustedSetPosition(
|
||||
|
|
@ -1635,33 +1654,54 @@ public sealed class PhysicsEngine
|
|||
}
|
||||
|
||||
Transition transition = RentTransition();
|
||||
CellArray queryFootprint =
|
||||
transition.SpherePath.SetPositionQueryFootprint;
|
||||
try
|
||||
{
|
||||
queryFootprint.Clear();
|
||||
transition.SpherePath.CellCandidates.UnionTarget = queryFootprint;
|
||||
InitializeSetPositionTransition(transition, request);
|
||||
bool randomOnly = request.Flags.HasFlag(
|
||||
PhysicsSetPositionFlags.RandomScatter);
|
||||
PhysicsSetPositionResult result;
|
||||
if (randomOnly)
|
||||
{
|
||||
return SetScatterPositionInternal(
|
||||
result = SetScatterPositionInternal(
|
||||
transition,
|
||||
request,
|
||||
handleCollisions);
|
||||
handleCollisions,
|
||||
queryFootprint);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SetPositionInternal(
|
||||
transition,
|
||||
request,
|
||||
handleCollisions,
|
||||
queryFootprint);
|
||||
if (result.Error != PhysicsSetPositionError.Ok
|
||||
&& request.Flags.HasFlag(PhysicsSetPositionFlags.Scatter))
|
||||
{
|
||||
result = SetScatterPositionInternal(
|
||||
transition,
|
||||
request,
|
||||
handleCollisions,
|
||||
queryFootprint);
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsSetPositionResult result =
|
||||
SetPositionInternal(transition, request, handleCollisions);
|
||||
if (result.Error != PhysicsSetPositionError.Ok
|
||||
&& request.Flags.HasFlag(PhysicsSetPositionFlags.Scatter))
|
||||
// Scatter retains one append-only query union across every inner
|
||||
// attempt. Materialize it exactly once at the public transaction
|
||||
// boundary; copying it per attempt is quadratic at retail's
|
||||
// maximum retry count.
|
||||
return result with
|
||||
{
|
||||
return SetScatterPositionInternal(
|
||||
transition,
|
||||
request,
|
||||
handleCollisions);
|
||||
}
|
||||
return result;
|
||||
QueriedCellIds = queryFootprint.OrderedIds.ToImmutableArray(),
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
transition.SpherePath.CellCandidates.UnionTarget = null;
|
||||
ReturnTransition(transition);
|
||||
}
|
||||
}
|
||||
|
|
@ -1686,7 +1726,8 @@ public sealed class PhysicsEngine
|
|||
private PhysicsSetPositionResult SetScatterPositionInternal(
|
||||
Transition transition,
|
||||
in PhysicsSetPositionRequest request,
|
||||
Func<PhysicsSetPositionCollisionReport, bool>? handleCollisions)
|
||||
Func<PhysicsSetPositionCollisionReport, bool>? handleCollisions,
|
||||
CellArray queryFootprint)
|
||||
{
|
||||
PhysicsSetPositionResult result = ErrorResult(
|
||||
request,
|
||||
|
|
@ -1706,7 +1747,8 @@ public sealed class PhysicsEngine
|
|||
result = SetPositionInternal(
|
||||
transition,
|
||||
scattered,
|
||||
handleCollisions);
|
||||
handleCollisions,
|
||||
queryFootprint);
|
||||
if (result.Error == PhysicsSetPositionError.Ok)
|
||||
break;
|
||||
}
|
||||
|
|
@ -1716,7 +1758,8 @@ public sealed class PhysicsEngine
|
|||
private PhysicsSetPositionResult SetPositionInternal(
|
||||
Transition transition,
|
||||
in PhysicsSetPositionRequest request,
|
||||
Func<PhysicsSetPositionCollisionReport, bool>? handleCollisions)
|
||||
Func<PhysicsSetPositionCollisionReport, bool>? handleCollisions,
|
||||
CellArray queryFootprint)
|
||||
{
|
||||
transition.SpherePath.CellCandidates.Clear();
|
||||
transition.SpherePath.ClearWalkable();
|
||||
|
|
@ -1731,7 +1774,8 @@ public sealed class PhysicsEngine
|
|||
AdjustedSetPosition adjusted = AdjustSetPosition(
|
||||
request.CellId,
|
||||
request.CellLocalPosition,
|
||||
firstWorldCenter);
|
||||
firstWorldCenter,
|
||||
queryFootprint);
|
||||
if (!adjusted.Resident)
|
||||
{
|
||||
return new PhysicsSetPositionResult(
|
||||
|
|
@ -1849,7 +1893,9 @@ public sealed class PhysicsEngine
|
|||
}
|
||||
if (spherePath.CurCellId == 0u)
|
||||
{
|
||||
return ErrorResult(request, PhysicsSetPositionError.NoCell);
|
||||
return ErrorResult(
|
||||
request,
|
||||
PhysicsSetPositionError.NoCell);
|
||||
}
|
||||
|
||||
bool inContact = collision.ContactPlaneValid;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue