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

Update MoverController.cs #118

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
/// </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 @@
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 @@
}
}

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 @@ -432,7 +398,7 @@

var impulse = force * brakeInput * ShuttleComponent.BrakeCoefficient;
impulse = shuttleNorthAngle.RotateVec(impulse);
var forceMul = frameTime * body.InvMass;

Check failure on line 401 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 401 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 401 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 401 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 401 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 401 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 401 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 401 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
var maxVelocity = (-body.LinearVelocity).Length() / forceMul;

// Don't overshoot
Expand Down Expand Up @@ -472,70 +438,38 @@
}
}

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

var localVel = (-shuttleNorthAngle).RotateVec(body.LinearVelocity);
var maxVelocity = ObtainMaxVel(localVel, shuttle); // max for current travel dir
Expand Down Expand Up @@ -566,14 +500,11 @@
_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 @@
_thruster.SetAngularThrust(shuttle, true);
}
}
else
{
_thruster.SetAngularThrust(shuttle, false);
}
}
}

Expand Down
Loading