Reapply "OBT1.1.0 Merge branch 'dev_pte' into dev"

This reverts commit 046483b9da.
This commit is contained in:
NotAlwaysTrue
2026-04-30 21:59:54 +08:00
parent 02689d0d86
commit 25683dcf39
85 changed files with 2413 additions and 779 deletions
@@ -73,6 +73,11 @@ namespace Barotrauma.Items.Components
public PhysicsBody PhysicsBody { get; private set; }
/// <summary>
/// Flag to prevent multiple queued refresh requests.
/// </summary>
private volatile bool physicsBodyRefreshQueued;
private float radius;
[Editable, Serialize(0.0f, IsPropertySaveable.Yes)]
public float Radius
@@ -83,7 +88,7 @@ namespace Barotrauma.Items.Components
{
if (radius == value) { return; }
radius = value;
if (PhysicsBody != null) { RefreshPhysicsBodySize(); }
if (PhysicsBody != null) { QueuePhysicsBodyRefresh(); }
}
}
@@ -97,7 +102,7 @@ namespace Barotrauma.Items.Components
{
if (width == value) { return; }
width = value;
if (PhysicsBody != null) { RefreshPhysicsBodySize(); }
if (PhysicsBody != null) { QueuePhysicsBodyRefresh(); }
}
}
@@ -111,10 +116,28 @@ namespace Barotrauma.Items.Components
{
if (height == value) { return; }
height = value;
if (PhysicsBody != null) { RefreshPhysicsBodySize(); }
if (PhysicsBody != null) { QueuePhysicsBodyRefresh(); }
}
}
/// <summary>
/// Queue the physics body refresh to be executed on the main thread.
/// This is necessary because physics body operations are not thread-safe.
/// </summary>
private void QueuePhysicsBodyRefresh()
{
if (physicsBodyRefreshQueued) { return; }
physicsBodyRefreshQueued = true;
PhysicsBodyQueue.EnqueueCreation(() =>
{
if (!item.Removed)
{
RefreshPhysicsBodySize();
}
physicsBodyRefreshQueued = false;
});
}
private float currentRadius, currentWidth, currentHeight;
private Vector2 bodyOffset;
@@ -289,13 +312,18 @@ namespace Barotrauma.Items.Components
Matrix transform = Matrix.CreateRotationZ(-item.RotationRad);
offset = Vector2.Transform(offset, transform);
}
// Defer physics operations if in parallel context (Farseer is not thread-safe)
var capturedBody = PhysicsBody;
var capturedPos = item.SimPosition + offset;
var capturedRot = -item.RotationRad;
if (ignoreContacts)
{
PhysicsBody.SetTransformIgnoreContacts(item.SimPosition + offset, -item.RotationRad);
PhysicsBodyQueue.ExecuteOrDefer(() => capturedBody.SetTransformIgnoreContacts(capturedPos, capturedRot));
}
else
{
PhysicsBody.SetTransform(item.SimPosition + offset, -item.RotationRad);
PhysicsBodyQueue.ExecuteOrDefer(() => capturedBody.SetTransform(capturedPos, capturedRot));
}
PhysicsBody.UpdateDrawPosition();
}