Attempt to fix "invalid force to a physics body" errors. Haven't been able to consistently reproduce the errors, but I'm pretty sure it was caused by GetCenterOfMass returning invalid values when all character's limbs are disabled (may happen for example when a character that's far away from the client's character dies).

This commit is contained in:
Joonas Rikkonen
2018-11-22 18:47:57 +02:00
parent 91a8a7e11d
commit f4a9458d66
2 changed files with 35 additions and 3 deletions
@@ -400,9 +400,27 @@ namespace Barotrauma
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
{ {
if (limb.type == LimbType.Head || limb.type == LimbType.Tail || limb.IsSevered) continue; if (limb.type == LimbType.Head || limb.type == LimbType.Tail || limb.IsSevered || !limb.body.Enabled) continue;
if (limb.Mass <= 0.0f)
{
string errorMsg = "Creature death animation error: invalid limb mass on character \"" + character.SpeciesName + "\" (type: " + limb.type + ", mass: " + limb.Mass + ")";
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("FishAnimController.UpdateDying:InvalidMass" + character.ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
deathAnimTimer = deathAnimDuration;
return;
}
limb.body.ApplyForce((centerOfMass - limb.SimPosition) * (float)(Math.Sin(walkPos) * Math.Sqrt(limb.Mass)) * 10.0f); Vector2 diff = (centerOfMass - limb.SimPosition);
if (!MathUtils.IsValid(diff))
{
string errorMsg = "Creature death animation error: invalid diff (center of mass: " + centerOfMass + ", limb position: " + limb.SimPosition + ")";
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("FishAnimController.UpdateDying:InvalidDiff" + character.ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
deathAnimTimer = deathAnimDuration;
return;
}
limb.body.ApplyForce(diff * (float)(Math.Sin(walkPos) * Math.Sqrt(limb.Mass)) * 10.0f);
} }
} }
@@ -711,6 +711,12 @@ namespace Barotrauma
public Vector2 GetCenterOfMass() public Vector2 GetCenterOfMass()
{ {
//all limbs disabled -> use the position of the collider
if (!Limbs.Any(l => !l.IsSevered && l.body.Enabled))
{
return Collider.SimPosition;
}
Vector2 centerOfMass = Vector2.Zero; Vector2 centerOfMass = Vector2.Zero;
float totalMass = 0.0f; float totalMass = 0.0f;
foreach (Limb limb in Limbs) foreach (Limb limb in Limbs)
@@ -719,9 +725,17 @@ namespace Barotrauma
centerOfMass += limb.Mass * limb.SimPosition; centerOfMass += limb.Mass * limb.SimPosition;
totalMass += limb.Mass; totalMass += limb.Mass;
} }
centerOfMass /= totalMass; centerOfMass /= totalMass;
if (!MathUtils.IsValid(centerOfMass))
{
string errorMsg = "Ragdoll.GetCenterOfMass returned an invalid value (" + centerOfMass + "). Limb positions: {"
+ string.Join(", ", limbs.Select(l => l.SimPosition)) + "}, total mass: " + totalMass + ".";
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("Ragdoll.GetCenterOfMass", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return Collider.SimPosition;
}
return centerOfMass; return centerOfMass;
} }