@@ -4483,25 +4483,27 @@ public void RepositionRearTraveller()
44834483 car.ComputePosition(traveller, false, 0, 0, SpeedMpS);
44844484 }
44854485 else
4486- {
4486+ {
44874487 // traveller is positioned at the front of the car
44884488 // advance to the first bogie
44894489 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4490+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4491+ frontLoc += traveller.Location;
4492+
44904493 var tileX = traveller.TileX;
44914494 var tileZ = traveller.TileZ;
4492- var x = traveller.X;
4493- var y = traveller.Y;
4494- var z = traveller.Z;
44954495
44964496 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
4497- // Also determine roll angle for superelevation by averaging both bogies
4498- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
4497+ // Outputs rotation angle for superelevation, used below
44994498 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4500- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4499+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4500+ rearLoc += traveller.Location;
4501+
4502+ float roll = (rearRoll + frontRoll) / 2.0f;
45014503
45024504 // Normalize across tile boundaries
4503- x += 2048 * (tileX - traveller.TileX);
4504- z += 2048 * (tileZ - traveller.TileZ);
4505+ frontLoc.X += 2048 * (tileX - traveller.TileX);
4506+ frontLoc.Z += 2048 * (tileZ - traveller.TileZ);
45054507
45064508 car.WorldPosition.XNAMatrix = Matrix.Identity;
45074509 if (!car.Flipped)
@@ -4512,16 +4514,14 @@ public void RepositionRearTraveller()
45124514 }
45134515
45144516 // Position car based on position of the front and rear of the car
4515- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4517+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(rearLoc .X, rearLoc .Y, rearLoc .Z, frontLoc.X, frontLoc.Y, frontLoc.Z );
45164518
45174519 // Update gravity force when position is updated, but before any secondary motion is added
45184520 car.UpdateGravity();
45194521
45204522 // Apply superelevation to car
4521- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4522-
4523- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4524- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4523+ if (roll != 0)
4524+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
45254525
45264526 car.WorldPosition.TileX = traveller.TileX;
45274527 car.WorldPosition.TileZ = traveller.TileZ;
@@ -4606,21 +4606,23 @@ public void CalculatePositionOfCars(float elapsedTime, float distance)
46064606 // traveller is positioned at the back of the car
46074607 // advance to the first bogie
46084608 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4609+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4610+ rearLoc += traveller.Location;
4611+
46094612 var tileX = traveller.TileX;
46104613 var tileZ = traveller.TileZ;
4611- var x = traveller.X;
4612- var y = traveller.Y;
4613- var z = traveller.Z;
46144614
46154615 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
46164616 // Outputs rotation angle for superelevation, used below
4617- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
46184617 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4619- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4618+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4619+ frontLoc += traveller.Location;
4620+
4621+ float roll = (rearRoll + frontRoll) / 2.0f;
46204622
46214623 // Normalize across tile boundaries
4622- x += 2048 * (tileX - traveller.TileX);
4623- z += 2048 * (tileZ - traveller.TileZ);
4624+ rearLoc.X += 2048 * (tileX - traveller.TileX);
4625+ rearLoc.Z += 2048 * (tileZ - traveller.TileZ);
46244626
46254627 car.WorldPosition.XNAMatrix = Matrix.Identity;
46264628 if (car.Flipped)
@@ -4631,16 +4633,14 @@ public void CalculatePositionOfCars(float elapsedTime, float distance)
46314633 }
46324634
46334635 // Position car based on position of the front and rear of the car
4634- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4636+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(frontLoc .X, frontLoc .Y, frontLoc .Z, rearLoc.X, rearLoc.Y, rearLoc.Z );
46354637
46364638 // Update gravity force when position is updated, but before any secondary motion is added
46374639 car.UpdateGravity();
46384640
46394641 // Apply superelevation to car
4640- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4641-
4642- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4643- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4642+ if (roll != 0)
4643+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
46444644
46454645 car.WorldPosition.TileX = traveller.TileX;
46464646 car.WorldPosition.TileZ = traveller.TileZ;
@@ -4685,21 +4685,23 @@ public void CalculatePositionOfEOT()
46854685 // traveller is positioned at the back of the car
46864686 // advance to the first bogie
46874687 traveller.Move((car.CarLengthM - car.CarBogieCentreLengthM) / 2.0f);
4688+ Vector3 rearLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float rearRoll);
4689+ rearLoc += traveller.Location;
4690+
46884691 var tileX = traveller.TileX;
46894692 var tileZ = traveller.TileZ;
4690- var x = traveller.X;
4691- var y = traveller.Y;
4692- var z = traveller.Z;
46934693
46944694 // Update car's curve radius and superelevation based on bogie position and move traveller to front bogie
46954695 // Outputs rotation angle for superelevation, used below
4696- float roll = traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation);
46974696 car.UpdateCurvePhys(traveller, new[] { 0, car.CarBogieCentreLengthM });
4698- roll = (roll + traveller.GetVisualElevation(Simulator.Settings.UseSuperElevation)) / 2.0f;
4697+ Vector3 frontLoc = traveller.CalcElevationPositionOffset(0.0f, Simulator.UseSuperElevation, out float frontRoll);
4698+ frontLoc += traveller.Location;
4699+
4700+ float roll = (rearRoll + frontRoll) / 2.0f;
46994701
47004702 // Normalize across tile boundaries
4701- x += 2048 * (tileX - traveller.TileX);
4702- z += 2048 * (tileZ - traveller.TileZ);
4703+ rearLoc.X += 2048 * (tileX - traveller.TileX);
4704+ rearLoc.Z += 2048 * (tileZ - traveller.TileZ);
47034705
47044706 car.WorldPosition.XNAMatrix = Matrix.Identity;
47054707 if (car.Flipped)
@@ -4710,16 +4712,14 @@ public void CalculatePositionOfEOT()
47104712 }
47114713
47124714 // Position car based on position of the front and rear of the car
4713- car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(traveller .X, traveller .Y, traveller .Z, x, y, z );
4715+ car.WorldPosition.XNAMatrix *= Simulator.XNAMatrixFromMSTSCoordinates(frontLoc .X, frontLoc .Y, frontLoc .Z, rearLoc.X, rearLoc.Y, rearLoc.Z );
47144716
47154717 // Update gravity force when position is updated, but before any secondary motion is added
47164718 car.UpdateGravity();
47174719
47184720 // Apply superelevation to car
4719- car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
4720-
4721- // note the railcar sits 0.275meters above the track database path TODO - is this always consistent?
4722- car.WorldPosition.XNAMatrix.Translation += car.WorldPosition.XNAMatrix.Up * 0.275f;
4721+ if (roll != 0)
4722+ car.WorldPosition.XNAMatrix = Matrix.CreateRotationZ((car.Flipped ? -1.0f : 1.0f) * roll) * car.WorldPosition.XNAMatrix;
47234723
47244724 car.WorldPosition.TileX = traveller.TileX;
47254725 car.WorldPosition.TileZ = traveller.TileZ;
0 commit comments