More physics error checks, ragdoll clamps the velocity returned by PhysicsBody.CorrectPosition to prevent applying excessively high velocities to the collider if the position has changed significantly between frames
This commit is contained in:
@@ -453,7 +453,7 @@ namespace Barotrauma
|
|||||||
float newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 7);
|
float newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 7);
|
||||||
bool awake = msg.ReadBoolean();
|
bool awake = msg.ReadBoolean();
|
||||||
Vector2 newVelocity = Vector2.Zero;
|
Vector2 newVelocity = Vector2.Zero;
|
||||||
|
|
||||||
if (awake)
|
if (awake)
|
||||||
{
|
{
|
||||||
newVelocity = new Vector2(
|
newVelocity = new Vector2(
|
||||||
@@ -461,6 +461,19 @@ namespace Barotrauma
|
|||||||
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
|
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!MathUtils.IsValid(newPosition) || !MathUtils.IsValid(newRotation) || !MathUtils.IsValid(newVelocity))
|
||||||
|
{
|
||||||
|
string errorMsg = "Received invalid position data for the item \"" + Name
|
||||||
|
+ "\" (position: " + newPosition + ", rotation: " + newRotation + ", velocity: " + newVelocity + ")";
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError(errorMsg);
|
||||||
|
#endif
|
||||||
|
GameAnalyticsManager.AddErrorEventOnce("Item.ClientReadPosition:InvalidData" + ID,
|
||||||
|
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||||
|
errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (body == null)
|
if (body == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Received a position update for an item with no physics body (" + Name + ")");
|
DebugConsole.ThrowError("Received a position update for an item with no physics body (" + Name + ")");
|
||||||
@@ -470,7 +483,7 @@ namespace Barotrauma
|
|||||||
body.FarseerBody.Awake = awake;
|
body.FarseerBody.Awake = awake;
|
||||||
if (body.FarseerBody.Awake)
|
if (body.FarseerBody.Awake)
|
||||||
{
|
{
|
||||||
if ((newVelocity - body.LinearVelocity).Length() > 8.0f) body.LinearVelocity = newVelocity;
|
if ((newVelocity - body.LinearVelocity).LengthSquared() > 8.0f * 8.0f) body.LinearVelocity = newVelocity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -490,11 +503,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if ((newPosition - SimPosition).Length() > body.LinearVelocity.Length() * 2.0f)
|
if ((newPosition - SimPosition).Length() > body.LinearVelocity.Length() * 2.0f)
|
||||||
{
|
{
|
||||||
body.SetTransform(newPosition, newRotation);
|
if (body.SetTransform(newPosition, newRotation))
|
||||||
|
{
|
||||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
||||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
||||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1332,8 +1332,24 @@ namespace Barotrauma
|
|||||||
character.AnimController.Anim = AnimController.Animation.None;
|
character.AnimController.Anim = AnimController.Animation.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collider.LinearVelocity = Vector2.Zero;
|
Vector2 newVelocity = overrideTargetMovement;
|
||||||
Collider.CorrectPosition(character.MemState, deltaTime, out overrideTargetMovement);
|
Vector2 newPosition = Collider.SimPosition;
|
||||||
|
Collider.CorrectPosition(character.MemState, deltaTime, out newVelocity, out newPosition);
|
||||||
|
|
||||||
|
newVelocity = newVelocity.ClampLength(100.0f);
|
||||||
|
if (!MathUtils.IsValid(newVelocity)) newVelocity = Vector2.Zero;
|
||||||
|
|
||||||
|
Collider.LinearVelocity = newVelocity;
|
||||||
|
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||||
|
if (distSqrd > 10.0f)
|
||||||
|
{
|
||||||
|
SetPosition(newPosition);
|
||||||
|
}
|
||||||
|
else if (distSqrd > 0.1f)
|
||||||
|
{
|
||||||
|
Collider.SetTransform(newPosition, Collider.Rotation);
|
||||||
|
overrideTargetMovement = newVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
//unconscious/dead characters can't correct their position using AnimController movement
|
//unconscious/dead characters can't correct their position using AnimController movement
|
||||||
// -> we need to correct it manually
|
// -> we need to correct it manually
|
||||||
@@ -1451,10 +1467,18 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation + rotationError);
|
float errorMagnitude = positionError.Length();
|
||||||
foreach (Limb limb in Limbs)
|
if (errorMagnitude > 0.01f)
|
||||||
{
|
{
|
||||||
limb.body.SetTransform(limb.body.SimPosition + positionError, limb.body.Rotation);
|
Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation + rotationError);
|
||||||
|
if (errorMagnitude > 0.5f)
|
||||||
|
{
|
||||||
|
character.MemLocalState.Clear();
|
||||||
|
foreach (Limb limb in Limbs)
|
||||||
|
{
|
||||||
|
limb.body.SetTransform(limb.body.SimPosition + positionError, limb.body.Rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -463,30 +463,32 @@ namespace Barotrauma
|
|||||||
body.ApplyTorque(torque);
|
body.ApplyTorque(torque);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTransform(Vector2 simPosition, float rotation)
|
public bool SetTransform(Vector2 simPosition, float rotation)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
||||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
||||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
||||||
|
|
||||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return;
|
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false;
|
||||||
if (!IsValidValue(rotation, "rotation")) return;
|
if (!IsValidValue(rotation, "rotation")) return false;
|
||||||
|
|
||||||
body.SetTransform(simPosition, rotation);
|
body.SetTransform(simPosition, rotation);
|
||||||
SetPrevTransform(simPosition, rotation);
|
SetPrevTransform(simPosition, rotation);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTransformIgnoreContacts(Vector2 simPosition, float rotation)
|
public bool SetTransformIgnoreContacts(Vector2 simPosition, float rotation)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
||||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
||||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
||||||
|
|
||||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return;
|
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false;
|
||||||
if (!IsValidValue(rotation, "rotation")) return;
|
if (!IsValidValue(rotation, "rotation")) return false;
|
||||||
|
|
||||||
body.SetTransformIgnoreContacts(ref simPosition, rotation);
|
body.SetTransformIgnoreContacts(ref simPosition, rotation);
|
||||||
SetPrevTransform(simPosition, rotation);
|
SetPrevTransform(simPosition, rotation);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrevTransform(Vector2 simPosition, float rotation)
|
public void SetPrevTransform(Vector2 simPosition, float rotation)
|
||||||
|
|||||||
Reference in New Issue
Block a user