Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Commit

Permalink
Update MoverController.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Vonsant authored May 4, 2024
1 parent d2c2ab7 commit d66812d
Showing 1 changed file with 47 additions and 112 deletions.
159 changes: 47 additions & 112 deletions Content.Server/Physics/Controllers/MoverController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,80 +270,45 @@ private static void ApplyTick(PilotComponent component, float fraction)
/// </summary>
private Vector2 ObtainMaxVel(Vector2 vel, ShuttleComponent shuttle)
{
if (vel.Length() == 0f)
// Use LengthSquared to avoid unnecessary square root computation
if (vel.LengthSquared() == 0f)
return Vector2.Zero;

// this math could PROBABLY be simplified for performance
// probably
// __________________________________
// / / __ __ \2 / __ __ \2
// O = I : _ / |I * | 1/H | | + |I * | 0 | |
// V \ |_ 0 _| / \ |_1/V_| /
// Directly extract velocity components
float velX = vel.X;
float velY = vel.Y;

var horizIndex = vel.X > 0 ? 1 : 3; // east else west
var vertIndex = vel.Y > 0 ? 2 : 0; // north else south
var horizComp = vel.X != 0 ? MathF.Pow(Vector2.Dot(vel, new Vector2(shuttle.BaseLinearThrust[horizIndex] / shuttle.LinearThrust[horizIndex], 0f)), 2) : 0;
var vertComp = vel.Y != 0 ? MathF.Pow(Vector2.Dot(vel, new Vector2(0f, shuttle.BaseLinearThrust[vertIndex] / shuttle.LinearThrust[vertIndex])), 2) : 0;
// Simplified index calculation based on the direction of velocity components
int horizIndex = velX > 0 ? 1 : 3;
int vertIndex = velY > 0 ? 2 : 0;

return shuttle.BaseMaxLinearVelocity * vel * MathF.ReciprocalSqrtEstimate(horizComp + vertComp);
}

private void HandleShuttleMovement(float frameTime)
{
var newPilots = new Dictionary<EntityUid, (ShuttleComponent Shuttle, HashSet<(EntityUid PilotUid, PilotComponent Pilot, InputMoverComponent Mover, TransformComponent ConsoleXform)>)>();

// We just mark off their movement and the shuttle itself does its own movement
var activePilotQuery = EntityQueryEnumerator<PilotComponent, InputMoverComponent>();
var shuttleQuery = GetEntityQuery<ShuttleComponent>();

while (activePilotQuery.MoveNext(out var uid, out var pilot, out var mover))
{
var consoleEnt = pilot.Console;

// TODO: This is terrible. Just make a new mover and also make it remote piloting + device networks
if (TryComp<DroneConsoleComponent>(consoleEnt, out var cargoConsole))
{
consoleEnt = cargoConsole.Entity;
}

if (!TryComp<TransformComponent>(consoleEnt, out var xform)) continue;

var gridId = xform.GridUid;
// This tries to see if the grid is a shuttle and if the console should work.
if (!TryComp<MapGridComponent>(gridId, out var _) ||
!shuttleQuery.TryGetComponent(gridId, out var shuttleComponent) ||
!shuttleComponent.Enabled)
continue;

if (!newPilots.TryGetValue(gridId!.Value, out var pilots))
{
pilots = (shuttleComponent, new HashSet<(EntityUid, PilotComponent, InputMoverComponent, TransformComponent)>());
newPilots[gridId.Value] = pilots;
}

pilots.Item2.Add((uid, pilot, mover, xform));
}
// Calculate thrust factors only if the respective velocity component is non-zero
float horizThrustRatio = velX != 0 ? shuttle.BaseLinearThrust[horizIndex] / shuttle.LinearThrust[horizIndex] : 0;
float vertThrustRatio = velY != 0 ? shuttle.BaseLinearThrust[vertIndex] / shuttle.LinearThrust[vertIndex] : 0;

// Reset inputs for non-piloted shuttles.
foreach (var (shuttleUid, (shuttle, _)) in _shuttlePilots)
{
if (newPilots.ContainsKey(shuttleUid) || CanPilot(shuttleUid))
continue;
// Calculate normalized component values
float horizNormalized = velX * horizThrustRatio;
float vertNormalized = velY * vertThrustRatio;

_thruster.DisableLinearThrusters(shuttle);
}
// Calculate the normalization factor using the squared sum of the normalized components
float normalizationFactor = 1f / MathF.Sqrt(horizNormalized * horizNormalized + vertNormalized * vertNormalized);

_shuttlePilots = newPilots;
// Apply the normalization factor to the entire vector and scale by maximum velocity
return new Vector2(velX * normalizationFactor, velY * normalizationFactor) * shuttle.BaseMaxLinearVelocity;
}

// Collate all of the linear / angular velocites for a shuttle
// then do the movement input once for it.
private void HandleShuttleMovement(float frameTime)
{
var directions = new[] { DirectionFlag.South, DirectionFlag.East, DirectionFlag.North, DirectionFlag.West };
var xformQuery = GetEntityQuery<TransformComponent>();

foreach (var (shuttleUid, (shuttle, pilots)) in _shuttlePilots)
{
if (Paused(shuttleUid) || CanPilot(shuttleUid) || !TryComp<PhysicsComponent>(shuttleUid, out var body))
continue;

var shuttleNorthAngle = _xformSystem.GetWorldRotation(shuttleUid, xformQuery);
var forceMul = frameTime * body.InvMass;

// Collate movement linear and angular inputs together
var linearInput = Vector2.Zero;
Expand All @@ -359,7 +324,7 @@ private void HandleShuttleMovement(float frameTime)
brakeInput += brakes;
}

if (strafe.Length() > 0f)
if (strafe.LengthSquared() > 0f) // Use LengthSquared to avoid sqrt calculation
{
var offsetRotation = consoleXform.LocalRotation;
linearInput += offsetRotation.RotateVec(strafe);
Expand All @@ -371,10 +336,11 @@ private void HandleShuttleMovement(float frameTime)
}
}

var count = pilots.Count;
linearInput /= count;
angularInput /= count;
brakeInput /= count;
// Normalize pilot inputs by the number of pilots
int pilotCount = pilots.Count;
linearInput /= pilotCount;
angularInput /= pilotCount;
brakeInput /= pilotCount;

// Handle shuttle movement
if (brakeInput > 0f)
Expand Down Expand Up @@ -472,67 +438,35 @@ private void HandleShuttleMovement(float frameTime)
}
}

if (linearInput.Length().Equals(0f))
{
PhysicsSystem.SetSleepingAllowed(shuttleUid, body, true);

if (brakeInput.Equals(0f))
_thruster.DisableLinearThrusters(shuttle);
}
else
if (linearInput.LengthSquared() > 0f)
{
PhysicsSystem.SetSleepingAllowed(shuttleUid, body, false);
var angle = linearInput.ToWorldAngle();
var linearDir = angle.GetDir();
var dockFlag = linearDir.AsFlag();
var totalForce = Vector2.Zero;

// Won't just do cardinal directions.
foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag)))
var totalForce = Vector2.Zero;
foreach (var dir in directions)
{
// Brain no worky but I just want cardinals
switch (dir)
{
case DirectionFlag.South:
case DirectionFlag.East:
case DirectionFlag.North:
case DirectionFlag.West:
break;
default:
continue;
}

if ((dir & dockFlag) == 0x0)
{
_thruster.DisableLinearThrustDirection(shuttle, dir);
continue;
}

var force = Vector2.Zero;
var index = (int) Math.Log2((int) dir);
int index = Array.IndexOf(directions, dir);
var thrust = shuttle.LinearThrust[index];

switch (dir)
var force = dir switch
{
case DirectionFlag.North:
force.Y += thrust;
break;
case DirectionFlag.South:
force.Y -= thrust;
break;
case DirectionFlag.East:
force.X += thrust;
break;
case DirectionFlag.West:
force.X -= thrust;
break;
default:
throw new ArgumentOutOfRangeException($"Attempted to apply thrust to shuttle {shuttleUid} along invalid dir {dir}.");
}
DirectionFlag.North => new Vector2(0, thrust),
DirectionFlag.South => new Vector2(0, -thrust),
DirectionFlag.East => new Vector2(thrust, 0),
DirectionFlag.West => new Vector2(-thrust, 0),
_ => throw new ArgumentOutOfRangeException()
};

_thruster.EnableLinearThrustDirection(shuttle, dir);
var impulse = force * linearInput.Length();
totalForce += impulse;
totalForce += force * linearInput.Length();
}

var forceMul = frameTime * body.InvMass;

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / Test Packaging

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / YAML Linter

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Check failure on line 472 in Content.Server/Physics/Controllers/MoverController.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

A local or parameter named 'forceMul' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Expand Down Expand Up @@ -566,14 +500,11 @@ private void HandleShuttleMovement(float frameTime)
_thruster.SetAngularThrust(shuttle, false);
}
else
if (!MathHelper.CloseTo(angularInput, 0f))
{
PhysicsSystem.SetSleepingAllowed(shuttleUid, body, false);
var torque = shuttle.AngularThrust * -angularInput;

// Need to cap the velocity if 1 tick of input brings us over cap so we don't continuously
// edge onto the cap over and over.
var torqueMul = body.InvI * frameTime;

torque = Math.Clamp(torque,
(-ShuttleComponent.MaxAngularVelocity - body.AngularVelocity) / torqueMul,
(ShuttleComponent.MaxAngularVelocity - body.AngularVelocity) / torqueMul);
Expand All @@ -584,6 +515,10 @@ private void HandleShuttleMovement(float frameTime)
_thruster.SetAngularThrust(shuttle, true);
}
}
else
{
_thruster.SetAngularThrust(shuttle, false);
}
}
}

Expand Down

0 comments on commit d66812d

Please sign in to comment.