fix(runtime): preserve hidden setposition collision ownership

This commit is contained in:
Erik 2026-08-01 18:22:45 +02:00
parent 9b0f59bd1b
commit 0fbc7a1fb7
8 changed files with 343 additions and 43 deletions

View file

@ -883,23 +883,17 @@ public sealed class ShadowObjectRegistry
DataCache = DataCache,
};
staging.InstallOwnerState(source);
if (suspendOwner)
{
if (!staging.Suspend(entityId))
return false;
}
else
{
staging.CommitSetPosition(
entityId,
worldPosition,
worldRotation,
seedCellId,
worldOffsetX,
worldOffsetY,
action,
crossCellIds);
}
staging.CommitSetPosition(
entityId,
worldPosition,
worldRotation,
seedCellId,
worldOffsetX,
worldOffsetY,
action,
crossCellIds);
if (suspendOwner && !staging.Suspend(entityId))
return false;
if (!staging.TryCaptureOwnerState(
entityId,
out PreparedShadowOwnerState? replacement)

View file

@ -752,6 +752,12 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
transition = Entities.ApplyRawPhysicsState(
canonical,
update.PhysicsState);
if (canonical.Key is { } key)
{
Physics.Engine.ShadowObjects.UpdatePhysicsState(
key.LocalEntityId,
(uint)canonical.FinalPhysicsState);
}
ulong stateVersion = canonical.StateAuthorityVersion;
ulong physicsMutationVersion =
canonical.PhysicsStateMutationVersion;

View file

@ -438,6 +438,12 @@ internal sealed class RuntimeCollisionReportingState : IDisposable
bool reported = false;
for (int index = 0; index < receipt.Actions.Length; index++)
{
if (IsExactSetPositionBatchOwnerHidden(receipt))
{
return new(
SetPositionCollisionBatchDispatchStatus.Completed,
reported);
}
if (receipt.Owner.PositionAuthorityVersion
!= receipt.OwnerPositionAuthorityVersion
|| _owners.TryGetValue(
@ -463,6 +469,12 @@ internal sealed class RuntimeCollisionReportingState : IDisposable
action, receipt.PhysicsTime, receipt.BatchId);
}
if (IsExactSetPositionBatchOwnerHidden(receipt))
{
return new(
SetPositionCollisionBatchDispatchStatus.Completed,
reported);
}
if (receipt.Owner.PositionAuthorityVersion
!= receipt.OwnerPositionAuthorityVersion
|| _owners.TryGetValue(
@ -498,6 +510,14 @@ internal sealed class RuntimeCollisionReportingState : IDisposable
reported);
}
private bool IsExactSetPositionBatchOwnerHidden(
in SetPositionCollisionBatchReceipt receipt) =>
_entities.IsCurrent(receipt.Owner)
&& receipt.Owner.PositionAuthorityVersion
== receipt.OwnerPositionAuthorityVersion
&& ReferenceEquals(receipt.Owner.PhysicsBody, receipt.OwnerBody)
&& (receipt.OwnerBody.State & PhysicsStateFlags.Hidden) != 0;
internal bool DiscardSetPositionBatch(
in SetPositionCollisionBatchReceipt receipt) =>
receipt.IsValid

View file

@ -3199,8 +3199,7 @@ public sealed class RuntimePhysicsState : IDisposable
&& record.PositionAuthorityVersion == positionAuthorityVersion
&& record.SpatialAuthorityVersion == spatialAuthorityVersion
&& ReferenceEquals(record.PhysicsBody, body)
&& body.InWorld
&& (body.State & PhysicsStateFlags.Hidden) == 0;
&& body.InWorld;
}
private void OnCollisionOwnerMutated(uint ownerId, ulong version)

View file

@ -392,8 +392,7 @@ internal sealed class RuntimeSetPositionState : IDisposable
body,
placementCommitVersion,
fullCellId,
requireSpatialRoot: false)
&& owner.IsCollisionReportingEligible(record, body);
requireSpatialRoot: false);
}
private readonly RuntimePhysicsState _physics;
@ -3389,21 +3388,21 @@ internal sealed class RuntimeSetPositionState : IDisposable
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false)
|| !IsCollisionReportingEligible(record, body))
requireSpatialRoot: false))
{
return false;
}
bool reportingCurrent = _physics.HandleSetPositionCollisionReports(
record,
operation.PositionAuthorityVersion,
operation.SpatialAuthorityVersion,
operation.Command.GameTime,
operation.PreviousContact,
operation.PreviousOnWalkable,
collidedWithEnvironment,
collidedObjectIds,
out _);
bool reportingCurrent = !IsCollisionReportingEligible(record, body)
|| _physics.HandleSetPositionCollisionReports(
record,
operation.PositionAuthorityVersion,
operation.SpatialAuthorityVersion,
operation.Command.GameTime,
operation.PreviousContact,
operation.PreviousOnWalkable,
collidedWithEnvironment,
collidedObjectIds,
out _);
if (!reportingCurrent
|| !IsCanonicalPlacementCommitCurrent(
operation,
@ -3411,8 +3410,7 @@ internal sealed class RuntimeSetPositionState : IDisposable
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false)
|| !IsCollisionReportingEligible(record, body))
requireSpatialRoot: false))
return false;
body.FramesStationaryFall = result.FramesStationaryFall;
if (IsVelocityCurrent(operation))