@@ -4490,25 +4490,27 @@ public void RepositionRearTraveller()
44904490 car.ComputePosition(traveller, false, 0, 0, SpeedMpS);
44914491 }
44924492 else
4493- {
4493+ {
44944494 // traveller is positioned at the front of the car
44954495 // advance to the first bogie
44964496 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4497+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4498+ frontLoc += traveller.Location;
4499+
44974500 var tileX = traveller.TileX;
44984501 var tileZ = traveller.TileZ;
4499- var x = traveller.X;
4500- var y = traveller.Y;
4501- var z = traveller.Z;
45024502
45034503 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
4504- // Also determine roll angle for superelevation by averaging both bogies
4505- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
4504+ // Outputs rotation angle for superelevation, used below
45064505 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4507- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4506+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4507+ rearLoc += traveller.Location;
4508+
4509+ float roll = (rearRoll + frontRoll) / 2.0f;
45084510
45094511 // Normalize across tile boundaries
4510- x += 2048 * (tileX - traveller.TileX);
4511- z += 2048 * (tileZ - traveller.TileZ);
4512+ frontLoc.X += 2048 * (tileX - traveller.TileX);
4513+ frontLoc.Z += 2048 * (tileZ - traveller.TileZ);
45124514
45134515 car.WorldPosition.XNAMatrix = Matrix.Identity;
45144516 if (!car.Flipped)
@@ -4519,16 +4521,14 @@ public void RepositionRearTraveller()
45194521 }
45204522
45214523 // Position car based on position of the front and rear of the car
4522- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4524+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(rearLoc .X, rearLoc .Y, rearLoc .Z, frontLoc.X, frontLoc.Y, frontLoc.Z );
45234525
45244526 // Update gravity force when position is updated, but before any secondary motion is added
45254527 car.UpdateGravity();
45264528
45274529 // Apply superelevation to car
4528- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4529-
4530- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4531- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4530+ if (roll != 0)
4531+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
45324532
45334533 car.WorldPosition.TileX = traveller.TileX;
45344534 car.WorldPosition.TileZ = traveller.TileZ;
@@ -4613,21 +4613,23 @@ public void CalculatePositionOfCars(float elapsedTime, float distance)
46134613 // traveller is positioned at the back of the car
46144614 // advance to the first bogie
46154615 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4616+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4617+ rearLoc += traveller.Location;
4618+
46164619 var tileX = traveller.TileX;
46174620 var tileZ = traveller.TileZ;
4618- var x = traveller.X;
4619- var y = traveller.Y;
4620- var z = traveller.Z;
46214621
46224622 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
46234623 // Outputs rotation angle for superelevation, used below
4624- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
46254624 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4626- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4625+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4626+ frontLoc += traveller.Location;
4627+
4628+ float roll = (rearRoll + frontRoll) / 2.0f;
46274629
46284630 // Normalize across tile boundaries
4629- x += 2048 * (tileX - traveller.TileX);
4630- z += 2048 * (tileZ - traveller.TileZ);
4631+ rearLoc.X += 2048 * (tileX - traveller.TileX);
4632+ rearLoc.Z += 2048 * (tileZ - traveller.TileZ);
46314633
46324634 car.WorldPosition.XNAMatrix = Matrix.Identity;
46334635 if (car.Flipped)
@@ -4638,16 +4640,14 @@ public void CalculatePositionOfCars(float elapsedTime, float distance)
46384640 }
46394641
46404642 // Position car based on position of the front and rear of the car
4641- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4643+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(frontLoc .X, frontLoc .Y, frontLoc .Z, rearLoc.X, rearLoc.Y, rearLoc.Z );
46424644
46434645 // Update gravity force when position is updated, but before any secondary motion is added
46444646 car.UpdateGravity();
46454647
46464648 // Apply superelevation to car
4647- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4648-
4649- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4650- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4649+ if (roll != 0)
4650+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
46514651
46524652 car.WorldPosition.TileX = traveller.TileX;
46534653 car.WorldPosition.TileZ = traveller.TileZ;
@@ -4692,21 +4692,23 @@ public void CalculatePositionOfEOT()
46924692 // traveller is positioned at the back of the car
46934693 // advance to the first bogie
46944694 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4695+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4696+ rearLoc += traveller.Location;
4697+
46954698 var tileX = traveller.TileX;
46964699 var tileZ = traveller.TileZ;
4697- var x = traveller.X;
4698- var y = traveller.Y;
4699- var z = traveller.Z;
47004700
47014701 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
47024702 // Outputs rotation angle for superelevation, used below
4703- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
47044703 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4705- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4704+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4705+ frontLoc += traveller.Location;
4706+
4707+ float roll = (rearRoll + frontRoll) / 2.0f;
47064708
47074709 // Normalize across tile boundaries
4708- x += 2048 * (tileX - traveller.TileX);
4709- z += 2048 * (tileZ - traveller.TileZ);
4710+ rearLoc.X += 2048 * (tileX - traveller.TileX);
4711+ rearLoc.Z += 2048 * (tileZ - traveller.TileZ);
47104712
47114713 car.WorldPosition.XNAMatrix = Matrix.Identity;
47124714 if (car.Flipped)
@@ -4717,16 +4719,14 @@ public void CalculatePositionOfEOT()
47174719 }
47184720
47194721 // Position car based on position of the front and rear of the car
4720- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4722+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(frontLoc .X, frontLoc .Y, frontLoc .Z, rearLoc.X, rearLoc.Y, rearLoc.Z );
47214723
47224724 // Update gravity force when position is updated, but before any secondary motion is added
47234725 car.UpdateGravity();
47244726
47254727 // Apply superelevation to car
4726- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4727-
4728- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4729- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4728+ if (roll != 0)
4729+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
47304730
47314731 car.WorldPosition.TileX = traveller.TileX;
47324732 car.WorldPosition.TileZ = traveller.TileZ;
0 commit comments