Skip to content

Commit 248b8d5

Browse files
committed
Clean up gravity calculations and fix gradient display in rear cab
1 parent 92c74ef commit 248b8d5

File tree

3 files changed

+38
-36
lines changed

3 files changed

+38
-36
lines changed

Source/Orts.Simulation/Simulation/AIs/AITrain.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,8 @@ public override void InitializeMoving() // TODO
375375
float initialThrottlepercent = InitialThrottlepercent;
376376
MUDynamicBrakePercent = -1;
377377
AITrainBrakePercent = 0;
378-
// Percent slope = rise / run -> the Y position of the forward vector gives us the 'rise'
379-
// Derive the 'run' by assuming a hypotenuse length of 1, so run = sqrt(1 - rise^2)
380-
float rise = FirstCar.WorldPosition.XNAMatrix.M32;
381-
FirstCar.CurrentElevationPercent = 100f * (rise / (float)Math.Sqrt(1 - rise * rise));
378+
// Force calculate gradient at the front of the train
379+
FirstCar.UpdateGravity();
382380
// Give it a bit more gas if it is uphill
383381
if (FirstCar.CurrentElevationPercent < -2.0) initialThrottlepercent = 40f;
384382
// Better block gas if it is downhill

Source/Orts.Simulation/Simulation/Physics/Train.cs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,18 +1861,8 @@ public virtual void InitializeMoving()
18611861
MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
18621862
if (lead is MSTSSteamLocomotive) MUReverserPercent = 25;
18631863

1864-
// Percent slope = rise / run -> the Y position of the forward vector gives us the 'rise'
1865-
// Derive the 'run' by assuming a hypotenuse length of 1, so run = sqrt(1 - rise^2)
1866-
float rise = lead.WorldPosition.XNAMatrix.M32;
1867-
lead.CurrentElevationPercent = 100f * (rise / (float)Math.Sqrt(1 - rise * rise));
1868-
1869-
//TODO: next if block has been inserted to flip trainset physics in order to get viewing direction coincident with loco direction when using rear cab.
1870-
// To achieve the same result with other means, without flipping trainset physics, the block should be deleted
1871-
//
1872-
if (lead.IsDriveable && (lead as MSTSLocomotive).UsingRearCab)
1873-
{
1874-
lead.CurrentElevationPercent = -lead.CurrentElevationPercent;
1875-
}
1864+
// Force calculate gradient at the lead locomotive
1865+
lead.UpdateGravity();
18761866
// give it a bit more gas if it is uphill
18771867
if (lead.CurrentElevationPercent < -2.0) initialThrottlepercent = 40f;
18781868
// better block gas if it is downhill
@@ -4532,9 +4522,7 @@ public void RepositionRearTraveller()
45324522
car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller.X, traveller.Y, traveller.Z, x, y, z);
45334523

45344524
// Update gravity force when position is updated, but before any secondary motion is added
4535-
Vector3 fwd = car.WorldPosition.XNAMatrix.Backward;
4536-
car.GravityForceN = car.MassKG * TrainCar.GravitationalAccelerationMpS2 * fwd.Y;
4537-
car.CurrentElevationPercent = 100f * (fwd.Y / (float)Math.Sqrt(1 - fwd.Y * fwd.Y));
4525+
car.UpdateGravity();
45384526

45394527
// Apply superelevation to car
45404528
car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
@@ -4653,9 +4641,7 @@ public void CalculatePositionOfCars(float elapsedTime, float distance)
46534641
car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller.X, traveller.Y, traveller.Z, x, y, z);
46544642

46554643
// Update gravity force when position is updated, but before any secondary motion is added
4656-
Vector3 fwd = car.WorldPosition.XNAMatrix.Backward;
4657-
car.GravityForceN = car.MassKG * TrainCar.GravitationalAccelerationMpS2 * fwd.Y;
4658-
car.CurrentElevationPercent = 100f * (fwd.Y / (float)Math.Sqrt(1 - fwd.Y * fwd.Y));
4644+
car.UpdateGravity();
46594645

46604646
// Apply superelevation to car
46614647
car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
@@ -4734,9 +4720,7 @@ public void CalculatePositionOfEOT()
47344720
car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller.X, traveller.Y, traveller.Z, x, y, z);
47354721

47364722
// Update gravity force when position is updated, but before any secondary motion is added
4737-
Vector3 fwd = car.WorldPosition.XNAMatrix.Backward;
4738-
car.GravityForceN = car.MassKG * TrainCar.GravitationalAccelerationMpS2 * fwd.Y;
4739-
car.CurrentElevationPercent = 100f * (fwd.Y / (float)Math.Sqrt(1 - fwd.Y * fwd.Y));
4723+
car.UpdateGravity();
47404724

47414725
// Apply superelevation to car
47424726
car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -974,15 +974,6 @@ public virtual void Update(float elapsedClockSeconds)
974974

975975
AbsSpeedMpS = Math.Abs(_SpeedMpS);
976976

977-
//TODO: next if block has been inserted to flip trainset physics in order to get viewing direction coincident with loco direction when using rear cab.
978-
// To achieve the same result with other means, without flipping trainset physics, the block should be deleted
979-
//
980-
if (IsDriveable && Train != null & Train.IsPlayerDriven && (this as MSTSLocomotive).UsingRearCab)
981-
{
982-
GravityForceN = -GravityForceN;
983-
CurrentElevationPercent = -CurrentElevationPercent;
984-
}
985-
986977
UpdateCurveSpeedLimit(elapsedClockSeconds);
987978
UpdateCurveForce(elapsedClockSeconds);
988979
UpdateTunnelForce();
@@ -2824,8 +2815,7 @@ public void ComputePosition(Traveller traveler, bool backToFront, float elapsedT
28242815
m.Backward = fwd;
28252816

28262817
// Update gravity force when position is updated, but before any secondary motion is added
2827-
GravityForceN = MassKG * GravitationalAccelerationMpS2 * fwd.Y;
2828-
CurrentElevationPercent = 100f * (fwd.Y / (float)Math.Sqrt(1 - fwd.Y * fwd.Y));
2818+
UpdateGravity(m);
28292819

28302820
// Consider body roll from superelevation and from tilting.
28312821
UpdateTilting(traveler, elapsedTimeS, speed, direction);
@@ -3528,6 +3518,36 @@ public LatLonDirection GetLatLonDirection()
35283518

35293519
return new LatLonDirection(latLon, directionDeg); ;
35303520
}
3521+
3522+
/// <summary>
3523+
/// Update the gravity force and % gradient of this train car at the current position
3524+
/// </summary>
3525+
public void UpdateGravity()
3526+
{
3527+
UpdateGravity(WorldPosition.XNAMatrix);
3528+
}
3529+
3530+
/// <summary>
3531+
/// Update the gravity force and % gradient of this train car at an arbitrary position
3532+
/// </summary>
3533+
/// <param name="orientation">Matrix giving the train car orientation used to determine gravity.</param>
3534+
public void UpdateGravity(Matrix orientation)
3535+
{
3536+
// Percent slope = 100 * rise / run -> the Y component of the forward vector gives us the 'rise'
3537+
// Derive the 'run' by assuming a hypotenuse length of 1, so per Pythagoras run = sqrt(1 - rise^2)
3538+
float rise = orientation.Backward.Y;
3539+
3540+
GravityForceN = MassKG * GravitationalAccelerationMpS2 * rise;
3541+
CurrentElevationPercent = 100f * (rise / (float)Math.Sqrt(1 - rise * rise));
3542+
3543+
// Reverse gravity force and % gradient on locomotives operated from the rear cab
3544+
// FUTURE: Change rear cabs to not require such forbidden manipulations of physics
3545+
if (IsDriveable && Train != null & Train.IsPlayerDriven && (this as MSTSLocomotive).UsingRearCab)
3546+
{
3547+
GravityForceN = -GravityForceN;
3548+
CurrentElevationPercent = -CurrentElevationPercent;
3549+
}
3550+
}
35313551
}
35323552

35333553
public class WheelAxle : IComparer<WheelAxle>

0 commit comments

Comments
 (0)