Added a bunch of checks to make sure a normalized zero vector (= NaN, NaN) is not used in any position/velocity/movement calculations. There were at least three places where it was causing problems according to error reports: when a character that can't enter a sub spawns at the center of a hull and when using an underwater scooter or throwing something while the cursor is at the position of the character, but there were tons of other places as well where it may have potentially caused physics errors.
This commit is contained in:
@@ -180,6 +180,7 @@ namespace Barotrauma
|
||||
if (limb.WorldPosition != worldPosition && force > 0.0f)
|
||||
{
|
||||
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
||||
if (!MathUtils.IsValid(limbDiff)) limbDiff = Rand.Vector(1.0f);
|
||||
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
||||
limb.body.ApplyLinearImpulse(limbDiff * distFactor * force, impulsePoint);
|
||||
}
|
||||
|
||||
@@ -919,7 +919,7 @@ namespace Barotrauma
|
||||
ConvertUnits.ToSimUnits(endPos),
|
||||
null, Physics.CollisionLevel) != null)
|
||||
{
|
||||
position = ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition) + Vector2.Normalize(startPos - endPos)*offsetFromWall;
|
||||
position = ConvertUnits.ToDisplayUnits(Submarine.LastPickedPosition) + Vector2.Normalize(startPos - endPos) * offsetFromWall;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Barotrauma
|
||||
closestSub = Character.Controlled.Submarine;
|
||||
}
|
||||
|
||||
bool displace = moveAmount.Length() > 100.0f;
|
||||
bool displace = moveAmount.LengthSquared() > 100.0f * 100.0f;
|
||||
foreach (Submarine sub in subsToMove)
|
||||
{
|
||||
sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);
|
||||
@@ -259,7 +259,7 @@ namespace Barotrauma
|
||||
|
||||
Vector2 totalForce = CalculateBuoyancy();
|
||||
|
||||
if (Body.LinearVelocity.LengthSquared() > 0.000001f)
|
||||
if (Body.LinearVelocity.LengthSquared() > 0.0001f)
|
||||
{
|
||||
float dragCoefficient = 0.01f;
|
||||
|
||||
@@ -285,6 +285,7 @@ namespace Barotrauma
|
||||
worldBorders.Location += MathUtils.ToPoint(ConvertUnits.ToDisplayUnits(Body.SimPosition));
|
||||
|
||||
Vector2 translateDir = Vector2.Normalize(subTranslation);
|
||||
if (!MathUtils.IsValid(translateDir)) translateDir = Vector2.UnitY;
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
@@ -384,7 +385,9 @@ namespace Barotrauma
|
||||
|
||||
if (f2.UserData is VoronoiCell cell)
|
||||
{
|
||||
HandleLevelCollision(contact, Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center));
|
||||
Vector2 collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center);
|
||||
if (!MathUtils.IsValid(collisionNormal)) collisionNormal = Rand.Vector(1.0f);
|
||||
HandleLevelCollision(contact, collisionNormal);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -445,7 +448,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (limb.Mass > 100.0f)
|
||||
{
|
||||
Vector2 normal = Vector2.Normalize(Body.SimPosition - limb.SimPosition);
|
||||
Vector2 normal = Vector2.DistanceSquared(Body.SimPosition, limb.SimPosition) < 0.0001f ?
|
||||
Vector2.UnitY :
|
||||
Vector2.Normalize(Body.SimPosition - limb.SimPosition);
|
||||
|
||||
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f * Math.Min(limb.Mass / 200.0f, 1);
|
||||
|
||||
@@ -634,7 +639,10 @@ namespace Barotrauma
|
||||
float contactDot = Vector2.Dot(otherSub.PhysicsBody.LinearVelocity, -avgContactNormal);
|
||||
if (contactDot > 0.0f)
|
||||
{
|
||||
otherSub.PhysicsBody.LinearVelocity -= Vector2.Normalize(otherSub.PhysicsBody.LinearVelocity) * contactDot;
|
||||
if (otherSub.PhysicsBody.LinearVelocity.LengthSquared() > 0.0001f)
|
||||
{
|
||||
otherSub.PhysicsBody.LinearVelocity -= Vector2.Normalize(otherSub.PhysicsBody.LinearVelocity) * contactDot;
|
||||
}
|
||||
|
||||
impact = Vector2.Dot(otherSub.Velocity, normal);
|
||||
otherSub.SubBody.ApplyImpact(impact, normal, contact);
|
||||
|
||||
@@ -89,7 +89,9 @@ namespace Barotrauma
|
||||
foreach (Submarine sub in subs)
|
||||
{
|
||||
if (sub.Position == targetPos) continue;
|
||||
sub.ApplyForce((Vector2.Normalize(targetPos - sub.Position) * targetSpeed - sub.Velocity) * 500.0f);
|
||||
Vector2 dir = Vector2.Normalize(targetPos - sub.Position);
|
||||
if (!MathUtils.IsValid(dir)) continue;
|
||||
sub.ApplyForce((dir * targetSpeed - sub.Velocity) * 500.0f);
|
||||
}
|
||||
|
||||
timer += CoroutineManager.UnscaledDeltaTime;
|
||||
|
||||
Reference in New Issue
Block a user