Ejemplo n.º 1
0
        private void UpdateAnimation(RenderFrame frame, ElapsedTime elapsedTime)
        {
            float distanceTravelledM         = 0.0f; // Distance travelled by non-driven wheels
            float distanceTravelledDrivenM   = 0.0f; // Distance travelled by driven wheels
            float AnimationWheelRadiusM      = 0.0f; // Radius of non driven wheels
            float AnimationDriveWheelRadiusM = 0.0f; // Radius of driven wheels

            if (MSTSWagon.IsDriveable && MSTSWagon.Simulator.UseAdvancedAdhesion)
            {
                //TODO: next code line has been modified to flip trainset physics in order to get viewing direction coincident with loco direction when using rear cab.
                // To achieve the same result with other means, without flipping trainset physics, the line should be changed as follows:
                //                                distanceTravelledM = MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;

                if (Car.EngineType == Orts.Simulation.RollingStocks.TrainCar.EngineTypes.Steam) // Steam locomotive so set up different speeds for different driver and non-driver wheels
                {
                    distanceTravelledM       = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    distanceTravelledDrivenM = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedSlipMpS * elapsedTime.ClockSeconds;
                    // Set values of wheel radius - assume that drive wheel and non driven wheel are different sizes
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.DriverWheelRadiusM;
                }
                else  // Other driveable rolling stock - all wheels have same speed.
                {
                    distanceTravelledM       = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    distanceTravelledDrivenM = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    // Set values of wheel radius - assume that drive wheel and non driven wheel are same sizes
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.WheelRadiusM;
                }
            }
            else // set values for simple adhesion
            {
                distanceTravelledM       = MSTSWagon.SpeedMpS * elapsedTime.ClockSeconds;
                distanceTravelledDrivenM = MSTSWagon.SpeedMpS * elapsedTime.ClockSeconds;
                // Set values of wheel radius - assume that drive wheel and non driven wheel are same sizes
                if (Car.EngineType == Orts.Simulation.RollingStocks.TrainCar.EngineTypes.Steam) // set values for steam stock
                {
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.DriverWheelRadiusM;
                }
                else // set values for non-driveable stock, eg wagons, and driveable stock such as diesels, electric locomotives
                {
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.WheelRadiusM;
                }
            }

            if (Car.BrakeSkid) // if car wheels are skidding because of brakes lockin wheels up then stop wheels rotating.
            {
                distanceTravelledM       = 0.0f;
                distanceTravelledDrivenM = 0.0f;
            }

            // Running gear and drive wheel rotation (animation) in steam locomotives
            if (!RunningGear.Empty() && AnimationDriveWheelRadiusM > 0.001)
            {
                RunningGear.UpdateLoop(distanceTravelledDrivenM / MathHelper.TwoPi / AnimationDriveWheelRadiusM);
            }


            // Wheel rotation (animation) - for non-drive wheels in steam locomotives and all wheels in other stock
            if (WheelPartIndexes.Count > 0)
            {
                var wheelCircumferenceM = MathHelper.TwoPi * AnimationWheelRadiusM;
                var rotationalDistanceR = MathHelper.TwoPi * distanceTravelledM / wheelCircumferenceM;  // in radians
                WheelRotationR = MathHelper.WrapAngle(WheelRotationR - rotationalDistanceR);
                var wheelRotationMatrix = Matrix.CreateRotationX(WheelRotationR);
                foreach (var iMatrix in WheelPartIndexes)
                {
                    TrainCarShape.XNAMatrices[iMatrix] = wheelRotationMatrix * TrainCarShape.SharedShape.Matrices[iMatrix];
                }
            }

#if DEBUG_WHEEL_ANIMATION
            Trace.TraceInformation("========================== Debug Animation in MSTSWagonViewer.cs ==========================================");
            Trace.TraceInformation("Slip speed - Car ID: {0} WheelDistance: {1} SlipWheelDistance: {2}", Car.CarID, distanceTravelledM, distanceTravelledDrivenM);
            Trace.TraceInformation("Wag Speed - Wheelspeed: {0} Slip: {1} Train: {2}", MSTSWagon.WheelSpeedMpS, MSTSWagon.WheelSpeedSlipMpS, MSTSWagon.SpeedMpS);
            Trace.TraceInformation("Wheel Radius - DriveWheel: {0} NonDriveWheel: {1}", AnimationDriveWheelRadiusM, AnimationWheelRadiusM);
#endif

            // truck angle animation
            foreach (var p in Car.Parts)
            {
                if (p.iMatrix <= 0)
                {
                    continue;
                }
                Matrix m = Matrix.Identity;
                m.Translation = TrainCarShape.SharedShape.Matrices[p.iMatrix].Translation;
                m.M11         = p.Cos;
                m.M13         = p.Sin;
                m.M31         = -p.Sin;
                m.M33         = p.Cos;

                // To cancel out any vibration, apply the inverse here. If no vibration is present, this matrix will be Matrix.Identity.
                TrainCarShape.XNAMatrices[p.iMatrix] = Car.VibrationInverseMatrix * m;
            }

            if (FreightShape != null)
            {
                FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                FreightShape.Location.TileX     = Car.WorldPosition.TileX; FreightShape.Location.TileZ = Car.WorldPosition.TileZ;

                if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender)
                {
                    if (MSTSWagon.TendersSteamLocomotive == null)
                    {
                        MSTSWagon.FindTendersSteamLocomotive();
                    }
                    if (FreightShape.XNAMatrices.Length > 0 && MSTSWagon.TendersSteamLocomotive != null)
                    {
                        if (MSTSWagon.FreightAnimFlag > 0 && MSTSWagon.FreightAnimMaxLevelM > MSTSWagon.FreightAnimMinLevelM)
                        {
                            FreightShape.XNAMatrices[0].M42 = MSTSWagon.FreightAnimMinLevelM + MSTSWagon.TendersSteamLocomotive.FuelController.CurrentValue * (MSTSWagon.FreightAnimMaxLevelM - MSTSWagon.FreightAnimMinLevelM);
                        }
                        else
                        // reproducing MSTS strange behavior; used to display loco crew
                        {
                            FreightShape.Location.XNAMatrix.M42 += MSTSWagon.FreightAnimMaxLevelM;
                        }
                    }
                }
                FreightShape.PrepareFrame(frame, elapsedTime);
            }

            if (FreightAnimations != null)
            {
                foreach (var freightAnim in FreightAnimations.Animations)
                {
                    if (freightAnim.FreightShape != null && !((freightAnim.Animation is FreightAnimationContinuous) && (freightAnim.Animation as FreightAnimationContinuous).LoadPerCent == 0))
                    {
                        freightAnim.FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                        freightAnim.FreightShape.Location.TileX     = Car.WorldPosition.TileX; freightAnim.FreightShape.Location.TileZ = Car.WorldPosition.TileZ;
                        if (freightAnim.FreightShape.XNAMatrices.Length > 0)
                        {
                            if (freightAnim.Animation is FreightAnimationContinuous)
                            {
                                var continuousFreightAnim = freightAnim.Animation as FreightAnimationContinuous;
                                if (MSTSWagon.FreightAnimations.IsGondola)
                                {
                                    freightAnim.FreightShape.XNAMatrices[0] = TrainCarShape.XNAMatrices[1];
                                }
                                freightAnim.FreightShape.XNAMatrices[0].M42 = continuousFreightAnim.MinHeight +
                                                                              continuousFreightAnim.LoadPerCent / 100 * (continuousFreightAnim.MaxHeight - continuousFreightAnim.MinHeight);
                            }
                            if (freightAnim.Animation is FreightAnimationStatic)
                            {
                                var staticFreightAnim = freightAnim.Animation as FreightAnimationStatic;
                                freightAnim.FreightShape.XNAMatrices[0].M41 = staticFreightAnim.XOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M42 = staticFreightAnim.YOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M43 = staticFreightAnim.ZOffset;
                            }
                        }
                        // Forcing rotation of freight shape
                        freightAnim.FreightShape.PrepareFrame(frame, elapsedTime);
                    }
                }
            }



            // Control visibility of passenger cabin when inside it
            if (Viewer.Camera.AttachedCar == this.MSTSWagon
                &&  //( Viewer.ViewPoint == Viewer.ViewPoints.Cab ||  // TODO, restore when we complete cab views -
                Viewer.Camera.Style == Camera.Styles.Passenger)
            {
                // We are in the passenger cabin
                if (InteriorShape != null)
                {
                    InteriorShape.PrepareFrame(frame, elapsedTime);
                }
                else
                {
                    TrainCarShape.PrepareFrame(frame, elapsedTime);
                }
            }
            else
            {
                // Skip drawing if CAB view - draw 2D view instead - by GeorgeS
                if (Viewer.Camera.AttachedCar == this.MSTSWagon &&
                    Viewer.Camera.Style == Camera.Styles.Cab)
                {
                    return;
                }

                // We are outside the passenger cabin
                TrainCarShape.PrepareFrame(frame, elapsedTime);
            }
        }
Ejemplo n.º 2
0
        private void UpdateAnimation(RenderFrame frame, ElapsedTime elapsedTime)
        {
            float distanceTravelledM         = 0.0f; // Distance travelled by non-driven wheels
            float distanceTravelledDrivenM   = 0.0f; // Distance travelled by driven wheels
            float AnimationWheelRadiusM      = 0.0f; // Radius of non driven wheels
            float AnimationDriveWheelRadiusM = 0.0f; // Radius of driven wheels

            if (MSTSWagon.IsDriveable && MSTSWagon.Simulator.UseAdvancedAdhesion)
            {
                //TODO: next code line has been modified to flip trainset physics in order to get viewing direction coincident with loco direction when using rear cab.
                // To achieve the same result with other means, without flipping trainset physics, the line should be changed as follows:
                //                                distanceTravelledM = MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;

                if (Car.EngineType == Orts.Simulation.RollingStocks.TrainCar.EngineTypes.Steam) // Steam locomotive so set up different speeds for different driver and non-driver wheels
                {
                    distanceTravelledM       = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    distanceTravelledDrivenM = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedSlipMpS * elapsedTime.ClockSeconds;
                    // Set values of wheel radius - assume that drive wheel and non driven wheel are different sizes
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.DriverWheelRadiusM;
                }
                else  // Other driveable rolling stock - all wheels have same speed.
                {
                    distanceTravelledM       = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    distanceTravelledDrivenM = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                    // Set values of wheel radius - assume that drive wheel and non driven wheel are same sizes
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.WheelRadiusM;
                }
            }
            else // set values for simple adhesion
            {
                distanceTravelledM       = ((MSTSWagon.IsDriveable && MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.SpeedMpS * elapsedTime.ClockSeconds;
                distanceTravelledDrivenM = ((MSTSWagon.IsDriveable && MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.SpeedMpS * elapsedTime.ClockSeconds;
                // Set values of wheel radius - assume that drive wheel and non driven wheel are same sizes
                if (Car.EngineType == Orts.Simulation.RollingStocks.TrainCar.EngineTypes.Steam) // set values for steam stock
                {
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.DriverWheelRadiusM;
                }
                else // set values for non-driveable stock, eg wagons, and driveable stock such as diesels, electric locomotives
                {
                    AnimationWheelRadiusM      = MSTSWagon.WheelRadiusM;
                    AnimationDriveWheelRadiusM = MSTSWagon.WheelRadiusM;
                }
            }

            if (Car.BrakeSkid) // if car wheels are skidding because of brakes lockin wheels up then stop wheels rotating.
            {
                distanceTravelledM       = 0.0f;
                distanceTravelledDrivenM = 0.0f;
            }

            // Running gear and drive wheel rotation (animation) in steam locomotives
            if (!RunningGear.Empty() && AnimationDriveWheelRadiusM > 0.001)
            {
                RunningGear.UpdateLoop(distanceTravelledDrivenM / MathHelper.TwoPi / AnimationDriveWheelRadiusM);
            }


            // Wheel rotation (animation) - for non-drive wheels in steam locomotives and all wheels in other stock
            if (WheelPartIndexes.Count > 0)
            {
                var wheelCircumferenceM = MathHelper.TwoPi * AnimationWheelRadiusM;
                var rotationalDistanceR = MathHelper.TwoPi * distanceTravelledM / wheelCircumferenceM;  // in radians
                WheelRotationR = MathHelper.WrapAngle(WheelRotationR - rotationalDistanceR);
                var wheelRotationMatrix = Matrix.CreateRotationX(WheelRotationR);
                foreach (var iMatrix in WheelPartIndexes)
                {
                    TrainCarShape.XNAMatrices[iMatrix] = wheelRotationMatrix * TrainCarShape.SharedShape.Matrices[iMatrix];
                }
            }

#if DEBUG_WHEEL_ANIMATION
            Trace.TraceInformation("========================== Debug Animation in MSTSWagonViewer.cs ==========================================");
            Trace.TraceInformation("Slip speed - Car ID: {0} WheelDistance: {1} SlipWheelDistance: {2}", Car.CarID, distanceTravelledM, distanceTravelledDrivenM);
            Trace.TraceInformation("Wag Speed - Wheelspeed: {0} Slip: {1} Train: {2}", MSTSWagon.WheelSpeedMpS, MSTSWagon.WheelSpeedSlipMpS, MSTSWagon.SpeedMpS);
            Trace.TraceInformation("Wheel Radius - DriveWheel: {0} NonDriveWheel: {1}", AnimationDriveWheelRadiusM, AnimationWheelRadiusM);
#endif

            // truck angle animation
            foreach (var p in Car.Parts)
            {
                if (p.iMatrix <= 0)
                {
                    continue;
                }
                Matrix m = Matrix.Identity;
                m.Translation = TrainCarShape.SharedShape.Matrices[p.iMatrix].Translation;
                m.M11         = p.Cos;
                m.M13         = p.Sin;
                m.M31         = -p.Sin;
                m.M33         = p.Cos;

                // To cancel out any vibration, apply the inverse here. If no vibration is present, this matrix will be Matrix.Identity.
                TrainCarShape.XNAMatrices[p.iMatrix] = Car.VibrationInverseMatrix * m;
            }


            // Applies MSTS style freight animation for coal load on the locomotive, crews, and other static animations.
            // Takes the form of FreightAnim ( A B C )
            // MSTS allowed crew figures to be inserted into the tender WAG file and thus be displayed on the locomotive.
            // It appears that only one MSTS type FA can be used per vehicle (to be confirmed?)
            // For coal load variation, C should be absent (set to 1 when read in WAG file) or >0 - sets FreightAnimFlag; and A > B
            // To disable coal load variation and insert a static (crew) shape on the tender breech, one of the conditions indicated above
            if (FreightShape != null && !(Viewer.Camera.AttachedCar == this.MSTSWagon && Viewer.Camera.Style == Camera.Styles.ThreeDimCab))
            {
                // Define default position of shape
                FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                FreightShape.Location.TileX     = Car.WorldPosition.TileX;
                FreightShape.Location.TileZ     = Car.WorldPosition.TileZ;

                bool  SteamAnimShape      = false;
                float FuelControllerLevel = 0.0f;

                // For coal load variation on locomotives determine the current fuel level - and whether locomotive is a tender or tank type locomotive.
                if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender || MSTSWagon is MSTSSteamLocomotive)
                {
                    var NonTenderSteamLocomotive = MSTSWagon as MSTSSteamLocomotive;

                    if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender || MSTSWagon is MSTSLocomotive && (MSTSWagon.EngineType == TrainCar.EngineTypes.Steam && NonTenderSteamLocomotive.IsTenderRequired == 0.0))
                    {
                        if (MSTSWagon.TendersSteamLocomotive == null)
                        {
                            MSTSWagon.FindTendersSteamLocomotive();
                        }

                        if (MSTSWagon.TendersSteamLocomotive != null)
                        {
                            FuelControllerLevel = MSTSWagon.TendersSteamLocomotive.FuelController.CurrentValue;
                            SteamAnimShape      = true;
                        }
                        else if (NonTenderSteamLocomotive != null)
                        {
                            FuelControllerLevel = NonTenderSteamLocomotive.FuelController.CurrentValue;
                            SteamAnimShape      = true;
                        }
                    }
                }

                // Set height of FAs - if relevant conditions met, use default position co-ords defined above
                if (FreightShape.XNAMatrices.Length > 0)
                {
                    // For tender coal load animation
                    if (MSTSWagon.FreightAnimFlag > 0 && MSTSWagon.FreightAnimMaxLevelM > MSTSWagon.FreightAnimMinLevelM && SteamAnimShape)
                    {
                        FreightShape.XNAMatrices[0].M42 = MSTSWagon.FreightAnimMinLevelM + FuelControllerLevel * (MSTSWagon.FreightAnimMaxLevelM - MSTSWagon.FreightAnimMinLevelM);
                    }
                    // reproducing MSTS strange behavior; used to display loco crew when attached to tender
                    else if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender)
                    {
                        FreightShape.Location.XNAMatrix.M42 += MSTSWagon.FreightAnimMaxLevelM;
                    }
                }
                // Display Animation Shape
                FreightShape.PrepareFrame(frame, elapsedTime);
            }

            if (FreightAnimations != null)
            {
                foreach (var freightAnim in FreightAnimations.Animations)
                {
                    if (freightAnim.Animation is FreightAnimationStatic)
                    {
                        var animation = freightAnim.Animation as FreightAnimationStatic;
                        if (!((animation.Visibility[(int)FreightAnimationStatic.VisibleFrom.Cab3D] &&
                               Viewer.Camera.AttachedCar == this.MSTSWagon && Viewer.Camera.Style == Camera.Styles.ThreeDimCab) ||
                              (animation.Visibility[(int)FreightAnimationStatic.VisibleFrom.Cab2D] &&
                               Viewer.Camera.AttachedCar == this.MSTSWagon && Viewer.Camera.Style == Camera.Styles.Cab) ||
                              (animation.Visibility[(int)FreightAnimationStatic.VisibleFrom.Outside] && (Viewer.Camera.AttachedCar != this.MSTSWagon ||
                                                                                                         (Viewer.Camera.Style != Camera.Styles.ThreeDimCab && Viewer.Camera.Style != Camera.Styles.Cab)))))
                        {
                            continue;
                        }
                    }
                    if (freightAnim.FreightShape != null && !((freightAnim.Animation is FreightAnimationContinuous) && (freightAnim.Animation as FreightAnimationContinuous).LoadPerCent == 0))
                    {
                        freightAnim.FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                        freightAnim.FreightShape.Location.TileX     = Car.WorldPosition.TileX; freightAnim.FreightShape.Location.TileZ = Car.WorldPosition.TileZ;
                        if (freightAnim.FreightShape.XNAMatrices.Length > 0)
                        {
                            if (freightAnim.Animation is FreightAnimationContinuous)
                            {
                                var continuousFreightAnim = freightAnim.Animation as FreightAnimationContinuous;
                                if (MSTSWagon.FreightAnimations.IsGondola)
                                {
                                    freightAnim.FreightShape.XNAMatrices[0] = TrainCarShape.XNAMatrices[1];
                                }
                                freightAnim.FreightShape.XNAMatrices[0].M42 = continuousFreightAnim.MinHeight +
                                                                              continuousFreightAnim.LoadPerCent / 100 * (continuousFreightAnim.MaxHeight - continuousFreightAnim.MinHeight);
                            }
                            if (freightAnim.Animation is FreightAnimationStatic)
                            {
                                var staticFreightAnim = freightAnim.Animation as FreightAnimationStatic;
                                freightAnim.FreightShape.XNAMatrices[0].M41 = staticFreightAnim.XOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M42 = staticFreightAnim.YOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M43 = staticFreightAnim.ZOffset;
                            }
                        }
                        // Forcing rotation of freight shape
                        freightAnim.FreightShape.PrepareFrame(frame, elapsedTime);
                    }
                }
            }



            // Control visibility of passenger cabin when inside it
            if (Viewer.Camera.AttachedCar == this.MSTSWagon
                &&  //( Viewer.ViewPoint == Viewer.ViewPoints.Cab ||  // TODO, restore when we complete cab views -
                Viewer.Camera.Style == Camera.Styles.Passenger)
            {
                // We are in the passenger cabin
                if (InteriorShape != null)
                {
                    InteriorShape.PrepareFrame(frame, elapsedTime);
                }
                else
                {
                    TrainCarShape.PrepareFrame(frame, elapsedTime);
                }
            }
            else
            {
                // Skip drawing if 2D or 3D Cab view - Cab view already drawn - by GeorgeS changed by DennisAT
                if (Viewer.Camera.AttachedCar == this.MSTSWagon &&
                    (Viewer.Camera.Style == Camera.Styles.Cab || Viewer.Camera.Style == Camera.Styles.ThreeDimCab))
                {
                    return;
                }

                // We are outside the passenger cabin
                TrainCarShape.PrepareFrame(frame, elapsedTime);
            }
        }
Ejemplo n.º 3
0
        private void UpdateAnimation(RenderFrame frame, ElapsedTime elapsedTime)
        {
            float distanceTravelledM;

            if (MSTSWagon.IsDriveable && MSTSWagon.Simulator.UseAdvancedAdhesion)
            {
                //TODO: next code line has been modified to flip trainset physics in order to get viewing direction coincident with loco direction when using rear cab.
                // To achieve the same result with other means, without flipping trainset physics, the line should be changed as follows:
                //                                distanceTravelledM = MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
                distanceTravelledM = ((MSTSWagon.Train != null && MSTSWagon.Train.IsPlayerDriven && ((MSTSLocomotive)MSTSWagon).UsingRearCab) ? -1 : 1) * MSTSWagon.WheelSpeedMpS * elapsedTime.ClockSeconds;
            }
            else
            {
                distanceTravelledM = MSTSWagon.SpeedMpS * elapsedTime.ClockSeconds;
            }

            // Running gear animation
            if (!RunningGear.Empty() && MSTSWagon.DriverWheelRadiusM > 0.001)
            {
                RunningGear.UpdateLoop(distanceTravelledM / MathHelper.TwoPi / MSTSWagon.DriverWheelRadiusM);
            }

            // Wheel animation
            if (WheelPartIndexes.Count > 0)
            {
                var wheelCircumferenceM = MathHelper.TwoPi * MSTSWagon.WheelRadiusM;
                var rotationalDistanceR = MathHelper.TwoPi * distanceTravelledM / wheelCircumferenceM;  // in radians
                WheelRotationR = MathHelper.WrapAngle(WheelRotationR - rotationalDistanceR);
                var wheelRotationMatrix = Matrix.CreateRotationX(WheelRotationR);
                foreach (var iMatrix in WheelPartIndexes)
                {
                    TrainCarShape.XNAMatrices[iMatrix] = wheelRotationMatrix * TrainCarShape.SharedShape.Matrices[iMatrix];
                }
            }

            // truck angle animation
            foreach (var p in Car.Parts)
            {
                if (p.iMatrix <= 0)
                {
                    continue;
                }
                Matrix m = Matrix.Identity;
                m.Translation = TrainCarShape.SharedShape.Matrices[p.iMatrix].Translation;
                m.M11         = p.Cos;
                m.M13         = p.Sin;
                m.M31         = -p.Sin;
                m.M33         = p.Cos;

                // To cancel out any vibration, apply the inverse here. If no vibration is present, this matrix will be Matrix.Identity.
                TrainCarShape.XNAMatrices[p.iMatrix] = Car.VibrationInverseMatrix * m;
            }

            if (FreightShape != null)
            {
                FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                FreightShape.Location.TileX     = Car.WorldPosition.TileX; FreightShape.Location.TileZ = Car.WorldPosition.TileZ;

                if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender)
                {
                    if (MSTSWagon.TendersSteamLocomotive == null)
                    {
                        MSTSWagon.FindTendersSteamLocomotive();
                    }
                    if (FreightShape.XNAMatrices.Length > 0 && MSTSWagon.TendersSteamLocomotive != null)
                    {
                        if (MSTSWagon.FreightAnimFlag > 0 && MSTSWagon.FreightAnimMaxLevelM > MSTSWagon.FreightAnimMinLevelM)
                        {
                            FreightShape.XNAMatrices[0].M42 = MSTSWagon.FreightAnimMinLevelM + MSTSWagon.TendersSteamLocomotive.FuelController.CurrentValue * (MSTSWagon.FreightAnimMaxLevelM - MSTSWagon.FreightAnimMinLevelM);
                        }
                        else
                        // reproducing MSTS strange behavior; used to display loco crew
                        {
                            FreightShape.Location.XNAMatrix.M42 += MSTSWagon.FreightAnimMaxLevelM;
                        }
                    }
                }
                FreightShape.PrepareFrame(frame, elapsedTime);
            }

            if (FreightAnimations != null)
            {
                foreach (var freightAnim in FreightAnimations.Animations)
                {
                    if (freightAnim.FreightShape != null && !((freightAnim.Animation is FreightAnimationContinuous) && (freightAnim.Animation as FreightAnimationContinuous).LoadPerCent == 0))
                    {
                        freightAnim.FreightShape.Location.XNAMatrix = Car.WorldPosition.XNAMatrix;
                        freightAnim.FreightShape.Location.TileX     = Car.WorldPosition.TileX; freightAnim.FreightShape.Location.TileZ = Car.WorldPosition.TileZ;
                        if (freightAnim.FreightShape.XNAMatrices.Length > 0)
                        {
                            if (freightAnim.Animation is FreightAnimationContinuous)
                            {
                                var continuousFreightAnim = freightAnim.Animation as FreightAnimationContinuous;
                                if (MSTSWagon.FreightAnimations.IsGondola)
                                {
                                    freightAnim.FreightShape.XNAMatrices[0] = TrainCarShape.XNAMatrices[1];
                                }
                                freightAnim.FreightShape.XNAMatrices[0].M42 = continuousFreightAnim.MinHeight +
                                                                              continuousFreightAnim.LoadPerCent / 100 * (continuousFreightAnim.MaxHeight - continuousFreightAnim.MinHeight);
                            }
                            if (freightAnim.Animation is FreightAnimationStatic)
                            {
                                var staticFreightAnim = freightAnim.Animation as FreightAnimationStatic;
                                freightAnim.FreightShape.XNAMatrices[0].M41 = staticFreightAnim.XOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M42 = staticFreightAnim.YOffset;
                                freightAnim.FreightShape.XNAMatrices[0].M43 = staticFreightAnim.ZOffset;
                            }
                        }
                        // Forcing rotation of freight shape
                        freightAnim.FreightShape.PrepareFrame(frame, elapsedTime);
                    }
                }
            }



            // Control visibility of passenger cabin when inside it
            if (Viewer.Camera.AttachedCar == this.MSTSWagon
                &&  //( Viewer.ViewPoint == Viewer.ViewPoints.Cab ||  // TODO, restore when we complete cab views -
                Viewer.Camera.Style == Camera.Styles.Passenger)
            {
                // We are in the passenger cabin
                if (InteriorShape != null)
                {
                    InteriorShape.PrepareFrame(frame, elapsedTime);
                }
                else
                {
                    TrainCarShape.PrepareFrame(frame, elapsedTime);
                }
            }
            else
            {
                // Skip drawing if CAB view - draw 2D view instead - by GeorgeS
                if (Viewer.Camera.AttachedCar == this.MSTSWagon &&
                    Viewer.Camera.Style == Camera.Styles.Cab)
                {
                    return;
                }

                // We are outside the passenger cabin
                TrainCarShape.PrepareFrame(frame, elapsedTime);
            }
        }