feat(runtime): own SetPosition collision reports
This commit is contained in:
parent
ec627c13a2
commit
237d1184d2
19 changed files with 3744 additions and 103 deletions
|
|
@ -23,6 +23,14 @@ public readonly record struct RuntimePhysicsOwnershipSnapshot(
|
|||
int UnboundDeferredSetPositionCellCount,
|
||||
int UnboundDeferredSetPositionCellOrderCount,
|
||||
int PreparedSetPositionMoverCount,
|
||||
int CollisionReportOwnerCount,
|
||||
int TrackedCollisionObjectCount,
|
||||
int CollisionReportReversePeerCount,
|
||||
int CollisionReportObserverCount,
|
||||
int PendingCollisionReportCount,
|
||||
int LeavingCollisionReportOwnerCount,
|
||||
int CollisionReportAdmissionBlockedOwnerCount,
|
||||
bool IsCollisionReportDispatching,
|
||||
int CollisionAdmissionCount,
|
||||
int CollisionGenerationCount,
|
||||
bool OwnsProductionDataCache,
|
||||
|
|
@ -49,6 +57,14 @@ public readonly record struct RuntimePhysicsOwnershipSnapshot(
|
|||
&& UnboundDeferredSetPositionCellCount == 0
|
||||
&& UnboundDeferredSetPositionCellOrderCount == 0
|
||||
&& PreparedSetPositionMoverCount == 0
|
||||
&& CollisionReportOwnerCount == 0
|
||||
&& TrackedCollisionObjectCount == 0
|
||||
&& CollisionReportReversePeerCount == 0
|
||||
&& CollisionReportObserverCount == 0
|
||||
&& PendingCollisionReportCount == 0
|
||||
&& LeavingCollisionReportOwnerCount == 0
|
||||
&& CollisionReportAdmissionBlockedOwnerCount == 0
|
||||
&& !IsCollisionReportDispatching
|
||||
&& CollisionAdmissionCount == 0
|
||||
&& CollisionGenerationCount == 0
|
||||
&& OwnsProductionDataCache;
|
||||
|
|
@ -1063,6 +1079,9 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
Engine.ShadowObjects.OwnerMutated += OnCollisionOwnerMutated;
|
||||
Engine.ShadowObjects.OwnerPrefixMembershipChanged +=
|
||||
OnCollisionOwnerPrefixMembershipChanged;
|
||||
CollisionReports = new RuntimeCollisionReportingState(
|
||||
Entities,
|
||||
Engine.ShadowObjects);
|
||||
SetPosition = new RuntimeSetPositionState(this, Entities);
|
||||
}
|
||||
|
||||
|
|
@ -1082,12 +1101,16 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
Engine.ShadowObjects.OwnerMutated += OnCollisionOwnerMutated;
|
||||
Engine.ShadowObjects.OwnerPrefixMembershipChanged +=
|
||||
OnCollisionOwnerPrefixMembershipChanged;
|
||||
CollisionReports = new RuntimeCollisionReportingState(
|
||||
Entities,
|
||||
Engine.ShadowObjects);
|
||||
SetPosition = new RuntimeSetPositionState(this, Entities);
|
||||
}
|
||||
|
||||
internal RuntimeEntityDirectory Entities { get; }
|
||||
public PhysicsEngine Engine { get; }
|
||||
public PhysicsDataCache DataCache { get; }
|
||||
internal RuntimeCollisionReportingState CollisionReports { get; }
|
||||
internal RuntimeSetPositionState SetPosition { get; }
|
||||
public int SpatialRootCount => _spatialRoots.Count;
|
||||
public int SpatialRemoteCount => _spatialRemotes.Count;
|
||||
|
|
@ -1107,6 +1130,8 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
{
|
||||
RuntimeSetPositionOwnershipSnapshot setPosition =
|
||||
SetPosition.CaptureOwnership();
|
||||
RuntimeCollisionReportingOwnershipSnapshot collisionReports =
|
||||
CollisionReports.CaptureOwnership();
|
||||
return new(
|
||||
Engine.LandblockCount,
|
||||
Engine.ShadowObjects.RetainedRegistrationCount,
|
||||
|
|
@ -1127,6 +1152,14 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
setPosition.UnboundDeferredCellCount,
|
||||
setPosition.UnboundDeferredCellOrderCount,
|
||||
setPosition.PreparedMoverCount,
|
||||
collisionReports.OwnerCount,
|
||||
collisionReports.TrackedObjectCount,
|
||||
collisionReports.ReversePeerCount,
|
||||
collisionReports.ObserverCount,
|
||||
collisionReports.PendingReportCount,
|
||||
collisionReports.LeavingOwnerCount,
|
||||
collisionReports.AdmissionBlockedOwnerCount,
|
||||
collisionReports.IsDispatching,
|
||||
_collisionAdmissions.Count,
|
||||
_collisionGenerations.Count,
|
||||
ReferenceEquals(Engine.DataCache, DataCache),
|
||||
|
|
@ -2303,6 +2336,7 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
}
|
||||
_preparedCollisionGenerations.Clear();
|
||||
SetPosition.Dispose();
|
||||
CollisionReports.Dispose();
|
||||
_collisionOwnerJournal.Clear();
|
||||
_collisionOwnerSubscribers.Clear();
|
||||
Engine.Clear();
|
||||
|
|
@ -2511,6 +2545,7 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
ulong positionAuthorityVersion,
|
||||
ulong spatialAuthorityVersion,
|
||||
ulong velocityAuthorityVersion,
|
||||
double physicsTime,
|
||||
bool previousContact,
|
||||
bool previousOnWalkable,
|
||||
in PhysicsSetPositionCollisionReport report)
|
||||
|
|
@ -2518,22 +2553,39 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
if (!Entities.IsCurrent(record)
|
||||
|| record.PositionAuthorityVersion != positionAuthorityVersion
|
||||
|| record.SpatialAuthorityVersion != spatialAuthorityVersion
|
||||
|| (velocityAuthorityVersion != 0UL
|
||||
&& record.VelocityAuthorityVersion
|
||||
!= velocityAuthorityVersion)
|
||||
|| record.PhysicsBody is not { } body)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_ = previousContact;
|
||||
_ = previousOnWalkable;
|
||||
bool current = HandleSetPositionCollisionReports(
|
||||
record,
|
||||
positionAuthorityVersion,
|
||||
spatialAuthorityVersion,
|
||||
physicsTime,
|
||||
previousContact: false,
|
||||
previousOnWalkable: false,
|
||||
collidedWithEnvironment: report.CollidedWithEnvironment,
|
||||
collidedObjectIds: report.CollidedObjectIds,
|
||||
collisionHandlerResult: out bool collisionHandlerResult);
|
||||
if (!current)
|
||||
return collisionHandlerResult;
|
||||
if (velocityAuthorityVersion != 0UL
|
||||
&& record.VelocityAuthorityVersion != velocityAuthorityVersion)
|
||||
{
|
||||
return collisionHandlerResult;
|
||||
}
|
||||
|
||||
body.FramesStationaryFall = report.FramesStationaryFall;
|
||||
PhysicsObjUpdate.HandleAllCollisions(
|
||||
body,
|
||||
report.CollisionNormalValid,
|
||||
report.CollisionNormal,
|
||||
previousContact,
|
||||
previousOnWalkable,
|
||||
body.OnWalkable);
|
||||
prevContact: false,
|
||||
prevOnWalkable: false,
|
||||
nowOnWalkable: body.OnWalkable);
|
||||
body.TransientState &= ~(TransientStateFlags.StationaryFall
|
||||
| TransientStateFlags.StationaryStop
|
||||
| TransientStateFlags.StationaryStuck);
|
||||
|
|
@ -2544,12 +2596,49 @@ public sealed class RuntimePhysicsState : IDisposable
|
|||
3 => TransientStateFlags.StationaryStuck,
|
||||
_ => TransientStateFlags.None,
|
||||
};
|
||||
// Retail returns the result of collision reporting, not a collision-
|
||||
// presence guess. Runtime does not yet own the per-object report/
|
||||
// tracking table required to reproduce that return value, so fail
|
||||
// closed. This preserves ordinary placement rejection and leaves the
|
||||
// already-registered reporting seam explicit for the 4B2 cutover.
|
||||
return false;
|
||||
return collisionHandlerResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs only retail's report/tracking half of handle_all_collisions. A
|
||||
/// successful SetPosition invokes this after contact/ground callbacks and
|
||||
/// before physical response and shadow reflood; invalid placement invokes
|
||||
/// it before its one response pass.
|
||||
/// </summary>
|
||||
internal bool HandleSetPositionCollisionReports(
|
||||
RuntimeEntityRecord record,
|
||||
ulong positionAuthorityVersion,
|
||||
ulong spatialAuthorityVersion,
|
||||
double physicsTime,
|
||||
bool previousContact,
|
||||
bool previousOnWalkable,
|
||||
bool collidedWithEnvironment,
|
||||
System.Collections.Immutable.ImmutableArray<uint> collidedObjectIds,
|
||||
out bool collisionHandlerResult)
|
||||
{
|
||||
collisionHandlerResult = false;
|
||||
if (!Entities.IsCurrent(record)
|
||||
|| record.PositionAuthorityVersion != positionAuthorityVersion
|
||||
|| record.SpatialAuthorityVersion != spatialAuthorityVersion
|
||||
|| record.PhysicsBody is not { } body)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
collisionHandlerResult = CollisionReports.HandleReports(
|
||||
record,
|
||||
body,
|
||||
physicsTime,
|
||||
previousContact,
|
||||
previousOnWalkable,
|
||||
collidedWithEnvironment,
|
||||
collidedObjectIds);
|
||||
return Entities.IsCurrent(record)
|
||||
&& record.PositionAuthorityVersion == positionAuthorityVersion
|
||||
&& record.SpatialAuthorityVersion == spatialAuthorityVersion
|
||||
&& ReferenceEquals(record.PhysicsBody, body)
|
||||
&& body.InWorld
|
||||
&& (body.State & PhysicsStateFlags.Hidden) == 0;
|
||||
}
|
||||
|
||||
private void OnCollisionOwnerMutated(uint ownerId, ulong version)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue