Ejemplo n.º 1
0
        /// <summary>Parses a base track following object node</summary>
        /// <param name="ObjectPath">Absolute path to the object folder of route data</param>
        /// <param name="FileName">The filename of the containing XML file</param>
        /// <param name="SectionElement">The XElement to parse</param>
        /// <param name="Train">The track following object to parse this node into</param>
        private static void ParseTrackFollowingObjectNode(string ObjectPath, string FileName, XElement SectionElement, TrackFollowingObject Train)
        {
            string Section = SectionElement.Name.LocalName;

            string            TrainDirectory  = string.Empty;
            bool              ConsistReversed = false;
            List <TravelData> Data            = new List <TravelData>();

            foreach (XElement KeyNode in SectionElement.Elements())
            {
                string Key        = KeyNode.Name.LocalName;
                int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                switch (Key.ToLowerInvariant())
                {
                case "definition":
                    ParseDefinitionNode(FileName, KeyNode, Train);
                    break;

                case "train":
                    ParseTrainNode(ObjectPath, FileName, KeyNode, ref TrainDirectory, ref ConsistReversed);
                    break;

                case "points":
                case "stops":
                    ParseTravelDataNodes(FileName, KeyNode, Data);
                    break;

                default:
                    Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}");
                    break;
                }
            }

            if (Data.Count < 2)
            {
                Interface.AddMessage(MessageType.Error, false, $"There must be at least two points to go through in {FileName}");
                return;
            }

            if (!(Data.First() is TravelStopData) || !(Data.Last() is TravelStopData))
            {
                Interface.AddMessage(MessageType.Error, false, $"The first and the last point to go through must be the \"Stop\" node in {FileName}");
                return;
            }

            if (string.IsNullOrEmpty(TrainDirectory))
            {
                Interface.AddMessage(MessageType.Error, false, $"No train has been specified in {FileName}");
                return;
            }

            /*
             * First check for a train.ai file- Functionally identical, but allows for differently configured AI
             * trains not to show up as drivable
             */
            string TrainData = OpenBveApi.Path.CombineFile(TrainDirectory, "train.ai");

            if (!File.Exists(TrainData))
            {
                // Check for the standard drivable train.dat
                TrainData = OpenBveApi.Path.CombineFile(TrainDirectory, "train.dat");
            }
            string ExteriorFile = OpenBveApi.Path.CombineFile(TrainDirectory, "extensions.cfg");

            if (!File.Exists(TrainData) || !File.Exists(ExteriorFile))
            {
                Interface.AddMessage(MessageType.Error, true, $"The supplied train folder in TrackFollowingObject {FileName} did not contain a complete set of data.");
                return;
            }
            AbstractTrain currentTrain = Train;

            for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++)
            {
                if (Program.CurrentHost.Plugins[i].Train != null && Program.CurrentHost.Plugins[i].Train.CanLoadTrain(TrainData))
                {
                    Program.CurrentHost.Plugins[i].Train.LoadTrain(Encoding.UTF8, TrainDirectory, ref currentTrain, ref Interface.CurrentControls);
                }
            }

            if (!Train.Cars.Any())
            {
                Interface.AddMessage(MessageType.Error, false, $"Failed to load the specified train in {FileName}");
                return;
            }

            Train.AI = new TrackFollowingObjectAI(Train, Data.ToArray());
            foreach (var Car in Train.Cars)
            {
                Car.FrontAxle.Follower.TrackIndex            = Data[0].RailIndex;
                Car.RearAxle.Follower.TrackIndex             = Data[0].RailIndex;
                Car.FrontBogie.FrontAxle.Follower.TrackIndex = Data[0].RailIndex;
                Car.FrontBogie.RearAxle.Follower.TrackIndex  = Data[0].RailIndex;
                Car.RearBogie.FrontAxle.Follower.TrackIndex  = Data[0].RailIndex;
                Car.RearBogie.RearAxle.Follower.TrackIndex   = Data[0].RailIndex;
            }

            if (ConsistReversed)
            {
                Train.Reverse();
            }
            Train.PlaceCars(Data[0].Position);
        }
Ejemplo n.º 2
0
        /// <summary> Updates the position and state of the animated object</summary>
        /// <param name="IsPartOfTrain">Whether this object forms part of a train</param>
        /// <param name="Train">The train, or a null reference otherwise</param>
        /// <param name="CarIndex">If this object forms part of a train, the car index it refers to</param>
        /// <param name="SectionIndex">If this object has been placed via Track.Sig, the index of the section it is attached to</param>
        /// <param name="TrackPosition"></param>
        /// <param name="Position"></param>
        /// <param name="Direction"></param>
        /// <param name="Up"></param>
        /// <param name="Side"></param>
        /// <param name="UpdateFunctions">Whether the functions associated with this object should be re-evaluated</param>
        /// <param name="Show"></param>
        /// <param name="TimeElapsed">The time elapsed since this object was last updated</param>
        /// <param name="EnableDamping">Whether damping is to be applied for this call</param>
        /// <param name="IsTouch">Whether Animated Object belonging to TouchElement class.</param>
        /// <param name="Camera"></param>
        public void Update(bool IsPartOfTrain, AbstractTrain Train, int CarIndex, int SectionIndex, double TrackPosition, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, bool UpdateFunctions, bool Show, double TimeElapsed, bool EnableDamping, bool IsTouch = false, dynamic Camera = null)
        {
            // state change
            if (StateFunction != null & UpdateFunctions)
            {
                double sd = StateFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                int    si = (int)System.Math.Round(sd);
                if (si < 0 | si >= States.Length)
                {
                    si = -1;
                }
                if (CurrentState != si)
                {
                    ObjectType type = ObjectType.Dynamic;
                    if (Camera != null)
                    {
                        type = ObjectType.Overlay;
                    }
                    Initialize(si, type, Show);
                    CurrentState = si;
                }
            }

            if (CurrentState == -1)
            {
                return;                                 //not visible state, so don't bother updating
            }
            // translation
            if (TranslateXFunction != null)
            {
                double x = TranslateXFunction.LastResult;
                if (UpdateFunctions)
                {
                    x = TranslateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                Vector3 translationVector = new Vector3(TranslateXDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= x;
                Position          += translationVector;
            }
            else if (TranslateXScriptFile != null)
            {
                //Translate X Script
                if (TranslateXAnimationScript == null)
                {
                    //Load the script if required
                    try
                    {
                        CSScript.GlobalSettings.TargetFramework = "v4.0";
                        TranslateXAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateXScriptFile))
                                                    .CreateObject("OpenBVEScript")
                                                    .AlignToInterface <AnimationScript>(true);
                    }
                    catch
                    {
                        currentHost.AddMessage(MessageType.Error, false,
                                               "An error occcured whilst parsing script " + TranslateXScriptFile);
                        TranslateXScriptFile = null;
                        return;
                    }
                }

                double x = TranslateXAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                   IsPartOfTrain, TimeElapsed);
                Vector3 translationVector = new Vector3(TranslateXDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= x;
                Position          += translationVector;
            }


            if (TranslateYFunction != null)
            {
                double y = TranslateYFunction.LastResult;
                if (UpdateFunctions)
                {
                    y = TranslateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                Vector3 translationVector = new Vector3(TranslateYDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= y;
                Position          += translationVector;
            }
            else if (TranslateYScriptFile != null)
            {
                //Translate X Script
                if (TranslateYAnimationScript == null)
                {
                    //Load the script if required
                    try
                    {
                        CSScript.GlobalSettings.TargetFramework = "v4.0";
                        TranslateYAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateYScriptFile))
                                                    .CreateObject("OpenBVEScript")
                                                    .AlignToInterface <AnimationScript>(true);
                    }
                    catch
                    {
                        currentHost.AddMessage(MessageType.Error, false,
                                               "An error occcured whilst parsing script " + TranslateYScriptFile);
                        TranslateYScriptFile = null;
                        return;
                    }
                }

                double y = TranslateYAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                   IsPartOfTrain, TimeElapsed);
                Vector3 translationVector = new Vector3(TranslateYDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= y;
                Position          += translationVector;
            }

            if (TranslateZFunction != null)
            {
                double z = TranslateZFunction.LastResult;
                if (UpdateFunctions)
                {
                    z = TranslateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                Vector3 translationVector = new Vector3(TranslateZDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= z;
                Position          += translationVector;
            }
            else if (TranslateZScriptFile != null)
            {
                //Translate X Script
                if (TranslateZAnimationScript == null)
                {
                    //Load the script if required
                    try
                    {
                        CSScript.GlobalSettings.TargetFramework = "v4.0";
                        TranslateZAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateZScriptFile))
                                                    .CreateObject("OpenBVEScript")
                                                    .AlignToInterface <AnimationScript>(true);
                    }
                    catch
                    {
                        currentHost.AddMessage(MessageType.Error, false,
                                               "An error occcured whilst parsing script " + TranslateZScriptFile);
                        TranslateZScriptFile = null;
                        return;
                    }
                }

                double z = TranslateZAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                   IsPartOfTrain, TimeElapsed);
                Vector3 translationVector = new Vector3(TranslateZDirection);                 //Must clone
                translationVector.Rotate(Direction, Up, Side);
                translationVector *= z;
                Position          += translationVector;
            }

            // rotation
            bool   rotateX = RotateXFunction != null;
            bool   rotateY = RotateYFunction != null;
            bool   rotateZ = RotateZFunction != null;
            double radianX = 0.0;

            if (rotateX)
            {
                radianX = RotateXFunction.LastResult;
                if (UpdateFunctions)
                {
                    radianX = RotateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                if (RotateXDamping != null)
                {
                    RotateXDamping.Update(TimeElapsed, ref radianX, EnableDamping);
                }
            }

            double radianY = 0.0;

            if (rotateY)
            {
                radianY = RotateYFunction.LastResult;
                if (UpdateFunctions)
                {
                    radianY = RotateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                if (RotateYDamping != null)
                {
                    RotateYDamping.Update(TimeElapsed, ref radianY, EnableDamping);
                }
            }

            double radianZ = 0.0;

            if (rotateZ)
            {
                radianZ = RotateZFunction.LastResult;
                if (UpdateFunctions)
                {
                    radianZ = RotateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }

                if (RotateZDamping != null)
                {
                    RotateZDamping.Update(TimeElapsed, ref radianZ, EnableDamping);
                }
            }

            // texture shift
            bool shiftx = TextureShiftXFunction != null;
            bool shifty = TextureShiftYFunction != null;

            internalObject.TextureTranslation = Matrix4D.Identity;

            if (shiftx | shifty)
            {
                if (shiftx)
                {
                    double x = TextureShiftXFunction.LastResult;
                    if (UpdateFunctions)
                    {
                        x = TextureShiftXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }

                    x -= System.Math.Floor(x);
                    internalObject.TextureTranslation *= Matrix4D.CreateTranslation(x * TextureShiftXDirection.X, x * TextureShiftXDirection.Y, 1.0);
                }

                if (shifty)
                {
                    double y = TextureShiftYFunction.LastResult;
                    if (UpdateFunctions)
                    {
                        y = TextureShiftYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }

                    y -= System.Math.Floor(y);
                    internalObject.TextureTranslation *= Matrix4D.CreateTranslation(y * TextureShiftYDirection.X, y * TextureShiftYDirection.Y, 1.0);
                }
            }

            // led
            bool   led      = LEDFunction != null;
            double ledangle = 0.0;

            if (led)
            {
                ledangle = LEDFunction.LastResult;
                if (UpdateFunctions)
                {
                    ledangle = LEDFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                }
            }

            // null object
            if (States[CurrentState].Prototype == null)
            {
                return;
            }

            // led
            if (led)
            {
                /*
                 * Edges:         Vertices:
                 * 0 - bottom     0 - bottom-left
                 * 1 - left       1 - top-left
                 * 2 - top        2 - top-right
                 * 3 - right      3 - bottom-right
                 *                4 - center
                 * */
                int v = 1;
                if (LEDClockwiseWinding)
                {
                    /* winding is clockwise*/
                    if (ledangle < LEDInitialAngle)
                    {
                        ledangle = LEDInitialAngle;
                    }

                    if (ledangle < LEDLastAngle)
                    {
                        double currentEdgeFloat = System.Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
                        int    currentEdge      = ((int)currentEdgeFloat % 4 + 4) % 4;
                        double lastEdgeFloat    = System.Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449));
                        int    lastEdge         = ((int)lastEdgeFloat % 4 + 4) % 4;
                        if (lastEdge < currentEdge | lastEdge == currentEdge & System.Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0)
                        {
                            lastEdge += 4;
                        }

                        if (currentEdge == lastEdge)
                        {
                            /* current angle to last angle */
                            {
                                double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz);
                                v++;
                            }
                            {
                                double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz);
                                v++;
                            }
                        }
                        else
                        {
                            {
                                /* current angle to square vertex */
                                double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(cx, cy, cz);
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[currentEdge];
                                v += 2;
                            }
                            for (int j = currentEdge + 1; j < lastEdge; j++)
                            {
                                /* square-vertex to square-vertex */
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4];
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4];
                                v += 2;
                            }

                            {
                                /* square vertex to last angle */
                                double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge % 4].X;
                                double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge % 4].Y;
                                double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge % 4].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(lastEdge + 3) % 4];
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = new Vector3(lx, ly, lz);
                                v += 2;
                            }
                        }
                    }
                }
                else
                {
                    /* winding is counter-clockwise*/
                    if (ledangle > LEDInitialAngle)
                    {
                        ledangle = LEDInitialAngle;
                    }

                    if (ledangle > LEDLastAngle)
                    {
                        double currentEdgeFloat = System.Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
                        int    currentEdge      = ((int)currentEdgeFloat % 4 + 4) % 4;
                        double lastEdgeFloat    = System.Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449));
                        int    lastEdge         = ((int)lastEdgeFloat % 4 + 4) % 4;
                        if (currentEdge < lastEdge | lastEdge == currentEdge & System.Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0)
                        {
                            currentEdge += 4;
                        }

                        if (currentEdge == lastEdge)
                        {
                            /* current angle to last angle */
                            {
                                double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz);
                                v++;
                            }
                            {
                                double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = t - System.Math.Floor(t);
                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz);
                                v++;
                            }
                        }
                        else
                        {
                            {
                                /* current angle to square vertex */
                                double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge % 4].X;
                                double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge % 4].Y;
                                double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge % 4].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(currentEdge + 3) % 4];
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = new Vector3(cx, cy, cz);
                                v += 2;
                            }
                            for (int j = currentEdge - 1; j > lastEdge; j--)
                            {
                                /* square-vertex to square-vertex */
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4];
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4];
                                v += 2;
                            }

                            {
                                /* square vertex to last angle */
                                double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat;
                                if (t < 0.0)
                                {
                                    t = 0.0;
                                }
                                else if (t > 1.0)
                                {
                                    t = 1.0;
                                }

                                t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t)));
                                double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                States[CurrentState].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(lx, ly, lz);
                                States[CurrentState].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[lastEdge % 4];
                                v += 2;
                            }
                        }
                    }
                }

                for (int j = v; v < 11; v++)
                {
                    States[CurrentState].Prototype.Mesh.Vertices[j].Coordinates = LEDVectors[4];
                }
            }

            // update prototype
            internalObject.Prototype = States[CurrentState].Prototype;

            // update VAO for led if required
            UpdateVAO = led;

            // update state
            // rotate
            internalObject.Rotate = Matrix4D.Identity;

            if (rotateX)
            {
                internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateXDirection.X, RotateXDirection.Y, -RotateXDirection.Z), 2.0 * System.Math.PI - radianX);
            }

            if (rotateY)
            {
                internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateYDirection.X, RotateYDirection.Y, -RotateYDirection.Z), 2.0 * System.Math.PI - radianY);
            }

            if (rotateZ)
            {
                internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateZDirection.X, RotateZDirection.Y, -RotateZDirection.Z), 2.0 * System.Math.PI - radianZ);
            }

            if (Camera != null && Camera.CurrentRestriction != CameraRestrictionMode.NotAvailable && Camera.CurrentRestriction != CameraRestrictionMode.Restricted3D)
            {
                internalObject.Rotate *= States[CurrentState].Translation * Matrix4D.CreateTranslation(-Position.X, -Position.Y, Position.Z);
                internalObject.Rotate *= (Matrix4D) new Transformation((Vector3)Camera.AbsoluteDirection, (Vector3)Camera.AbsoluteUp, (Vector3)Camera.AbsoluteSide);

                // translate
                double  dx  = -System.Math.Tan(Camera.Alignment.Yaw) - Camera.Alignment.Position.X;
                double  dy  = -System.Math.Tan(Camera.Alignment.Pitch) - Camera.Alignment.Position.Y;
                double  dz  = -Camera.Alignment.Position.Z;
                Vector3 add = Camera.AbsolutePosition + dx * Camera.AbsoluteSide + dy * Camera.AbsoluteUp + dz * Camera.AbsoluteDirection;
                internalObject.Translation = Matrix4D.CreateTranslation(add.X, add.Y, -add.Z);
            }
            else
            {
                internalObject.Rotate *= States[CurrentState].Translation;
                internalObject.Rotate *= (Matrix4D) new Transformation(Direction, Up, Side);

                // translate
                internalObject.Translation = Matrix4D.CreateTranslation(Position.X, Position.Y, -Position.Z);
            }

            // visibility changed
            // TouchElement is handled by another function.
            if (!IsTouch)
            {
                if (Show)
                {
                    if (Camera != null)
                    {
                        currentHost.ShowObject(internalObject, ObjectType.Overlay);
                    }
                    else
                    {
                        currentHost.ShowObject(internalObject, ObjectType.Dynamic);
                    }
                }
                else
                {
                    currentHost.HideObject(internalObject);
                }
            }
        }
Ejemplo n.º 3
0
        internal static void RefreshObjects()
        {
            LightingRelative = -1.0;
            Game.Reset();
            for (int i = 0; i < Files.Length; i++)
            {
                try
                {
                    if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        string currentTrainFolder = System.IO.Path.GetDirectoryName(Files[i]);

                        for (int j = 0; j < Program.CurrentHost.Plugins.Length; j++)
                        {
                            if (Program.CurrentHost.Plugins[j].Train != null && Program.CurrentHost.Plugins[j].Train.CanLoadTrain(currentTrainFolder))
                            {
                                TrainManager.Trains = new TrainBase[1];
                                Control[] dummyControls = new Control[0];
                                TrainManager.Trains[0] = new TrainManager.Train();
                                AbstractTrain playerTrain = TrainManager.Trains[0] as AbstractTrain;
                                Program.CurrentHost.Plugins[j].Train.LoadTrain(Encoding.UTF8, currentTrainFolder, ref playerTrain, ref dummyControls);
                                TrainManager.PlayerTrain = TrainManager.Trains[0];
                                break;
                            }
                        }
                        TrainManager.PlayerTrain.Initialize();
                        foreach (var Car in TrainManager.PlayerTrain.Cars)
                        {
                            double length = TrainManager.PlayerTrain.Cars[0].Length;
                            Car.Move(-length);
                            Car.Move(length);
                        }
                        TrainManager.PlayerTrain.PlaceCars(0);
                        for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                        {
                            TrainManager.PlayerTrain.Cars[j].UpdateTrackFollowers(0, true, false);
                            TrainManager.PlayerTrain.Cars[j].ChangeCarSection(CarSectionType.Exterior);
                            TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                            TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                        }
                    }
                    else
                    {
                        UnifiedObject o;
                        Program.CurrentHost.LoadObject(Files[i], System.Text.Encoding.UTF8, out o);
                        o.CreateObject(Vector3.Zero, 0.0, 0.0, 0.0);
                    }
                }
                catch (Exception ex)
                {
                    Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + ".");
                }
            }

            Renderer.InitializeVisibility();
            Renderer.UpdateViewingDistances(600);
            Renderer.UpdateVisibility(0.0, true);
            ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
            Program.TrainManager.UpdateTrainObjects(0.0, true);
            Renderer.ApplyBackgroundColor();
        }
Ejemplo n.º 4
0
        /// <summary>Updates the specified signal section</summary>
        /// <param name="secondsSinceMidnight">The in-game time in seconds since midnight</param>
        public void Update(double secondsSinceMidnight)
        {
            // preparations
            int  zeroaspect;
            bool settored = false;

            if (Type == SectionType.ValueBased)
            {
                // value-based
                zeroaspect = 0;
                for (int i = 1; i < Aspects.Length; i++)
                {
                    if (Aspects[i].Number < Aspects[zeroaspect].Number)
                    {
                        zeroaspect = i;
                    }
                }
            }
            else
            {
                // index-based
                zeroaspect = 0;
            }
            // hold station departure signal at red
            int d = StationIndex;

            if (d >= 0)
            {
                // look for train in previous blocks
                int           l     = PreviousSection;
                AbstractTrain train = null;
                while (true)
                {
                    if (l >= 0)
                    {
                        train = CurrentRoute.Sections[l].GetFirstTrain(false);
                        if (train != null)
                        {
                            break;
                        }
                        l = CurrentRoute.Sections[l].PreviousSection;
                    }
                    else
                    {
                        break;
                    }
                }
                if (train == null)
                {
                    double b = -double.MaxValue;
                    for (int i = 0; i < CurrentRoute.Trains.Length; i++)
                    {
                        if (CurrentRoute.Trains[i].State == TrainState.Available)
                        {
                            if (CurrentRoute.Trains[i].TimetableDelta > b)
                            {
                                b     = CurrentRoute.Trains[i].TimetableDelta;
                                train = CurrentRoute.Trains[i];
                            }
                        }
                    }
                }
                // set to red where applicable
                if (train != null)
                {
                    if (!TrainReachedStopPoint)
                    {
                        if (train.Station == d)
                        {
                            int c = CurrentRoute.Stations[d].GetStopIndex(train.NumberOfCars);
                            if (c >= 0)
                            {
                                double p0 = train.FrontCarTrackPosition();
                                double p1 = CurrentRoute.Stations[d].Stops[c].TrackPosition - CurrentRoute.Stations[d].Stops[c].BackwardTolerance;
                                if (p0 >= p1)
                                {
                                    TrainReachedStopPoint = true;
                                }
                            }
                            else
                            {
                                TrainReachedStopPoint = true;
                            }
                        }
                    }
                    double t = -15.0;
                    if (CurrentRoute.Stations[d].DepartureTime >= 0.0)
                    {
                        t = CurrentRoute.Stations[d].DepartureTime - 15.0;
                    }
                    else if (CurrentRoute.Stations[d].ArrivalTime >= 0.0)
                    {
                        t = CurrentRoute.Stations[d].ArrivalTime;
                    }
                    if (train.IsPlayerTrain & CurrentRoute.Stations[d].Type != StationType.Normal & CurrentRoute.Stations[d].DepartureTime < 0.0)
                    {
                        settored = true;
                    }
                    else if (t >= 0.0 & secondsSinceMidnight < t - train.TimetableDelta)
                    {
                        settored = true;
                    }
                    else if (!TrainReachedStopPoint)
                    {
                        settored = true;
                    }
                }
                else if (CurrentRoute.Stations[d].Type != StationType.Normal)
                {
                    settored = true;
                }
            }
            // train in block
            if (!IsFree())
            {
                settored = true;
            }
            // free sections
            int newaspect = -1;

            if (settored)
            {
                FreeSections = 0;
                newaspect    = zeroaspect;
            }
            else
            {
                int n = NextSection;
                if (n >= 0)
                {
                    if (CurrentRoute.Sections[n].FreeSections == -1)
                    {
                        FreeSections = -1;
                    }
                    else
                    {
                        FreeSections = CurrentRoute.Sections[n].FreeSections + 1;
                    }
                }
                else
                {
                    FreeSections = -1;
                }
            }
            // change aspect
            if (newaspect == -1)
            {
                if (Type == SectionType.ValueBased)
                {
                    // value-based
                    int n = NextSection;
                    int a = Aspects[Aspects.Length - 1].Number;
                    if (n >= 0 && CurrentRoute.Sections[n].CurrentAspect >= 0)
                    {
                        a = CurrentRoute.Sections[n].Aspects[CurrentRoute.Sections[n].CurrentAspect].Number;
                    }
                    for (int i = Aspects.Length - 1; i >= 0; i--)
                    {
                        if (Aspects[i].Number > a)
                        {
                            newaspect = i;
                        }
                    }
                    if (newaspect == -1)
                    {
                        newaspect = Aspects.Length - 1;
                    }
                }
                else
                {
                    // index-based
                    if (FreeSections >= 0 & FreeSections < Aspects.Length)
                    {
                        newaspect = FreeSections;
                    }
                    else
                    {
                        newaspect = Aspects.Length - 1;
                    }
                }
            }
            // apply new aspect
            CurrentAspect = newaspect;
            // update previous section
            if (PreviousSection >= 0 && PreviousSection < CurrentRoute.Sections.Length)
            {
                CurrentRoute.Sections[PreviousSection].Update(secondsSinceMidnight);
            }
        }
Ejemplo n.º 5
0
 /// <summary>Checks whether the section is free, disregarding the specified train.</summary>
 /// <param name="train">The train to disregard.</param>
 /// <returns>Whether the section is free, disregarding the specified train.</returns>
 public bool IsFree(AbstractTrain train)
 {
     return(Trains.All(t => !(t != train & (t.State == TrainState.Available | t.State == TrainState.Bogus))));
 }
Ejemplo n.º 6
0
 /// <summary>Checks whether a train is currently within the section</summary>
 /// <param name="Train">The train</param>
 /// <returns>True if the train is within the section, false otherwise</returns>
 public bool Exists(AbstractTrain Train)
 {
     return(Trains.Any(t => t == Train));
 }
Ejemplo n.º 7
0
        public override void Trigger(int Direction, EventTriggerType TriggerType, AbstractTrain Train, AbstractCar Car)
        {
            if (Train == null)
            {
                return;
            }

            if (Train.RouteLimits == null)
            {
                Train.RouteLimits = new double[] { };
            }

            if (Direction < 0)
            {
                if (TriggerType == EventTriggerType.FrontCarFrontAxle)
                {
                    int n = Train.RouteLimits.Length;
                    if (n > 0)
                    {
                        Array.Resize(ref Train.RouteLimits, n - 1);
                        Train.CurrentRouteLimit = double.PositiveInfinity;
                        for (int i = 0; i < n - 1; i++)
                        {
                            if (Train.RouteLimits[i] < Train.CurrentRouteLimit)
                            {
                                Train.CurrentRouteLimit = Train.RouteLimits[i];
                            }
                        }
                    }
                }
                else if (TriggerType == EventTriggerType.RearCarRearAxle)
                {
                    int n = Train.RouteLimits.Length;
                    Array.Resize(ref Train.RouteLimits, n + 1);
                    for (int i = n; i > 0; i--)
                    {
                        Train.RouteLimits[i] = Train.RouteLimits[i - 1];
                    }

                    Train.RouteLimits[0] = PreviousSpeedLimit;
                }
            }
            else if (Direction > 0)
            {
                if (TriggerType == EventTriggerType.FrontCarFrontAxle)
                {
                    int n = Train.RouteLimits.Length;
                    Array.Resize(ref Train.RouteLimits, n + 1);
                    Train.RouteLimits[n] = NextSpeedLimit;
                    if (NextSpeedLimit < Train.CurrentRouteLimit)
                    {
                        Train.CurrentRouteLimit = NextSpeedLimit;
                    }
                }
                else if (TriggerType == EventTriggerType.RearCarRearAxle)
                {
                    int n = Train.RouteLimits.Length;
                    if (n > 0)
                    {
                        Train.CurrentRouteLimit = double.PositiveInfinity;
                        for (int i = 0; i < n - 1; i++)
                        {
                            Train.RouteLimits[i] = Train.RouteLimits[i + 1];
                            if (Train.RouteLimits[i] < Train.CurrentRouteLimit)
                            {
                                Train.CurrentRouteLimit = Train.RouteLimits[i];
                            }
                        }
                        Array.Resize(ref Train.RouteLimits, n - 1);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        internal static void RefreshObjects()
        {
            LightingRelative = -1.0;
            Game.Reset();
            formTrain.Instance?.DisableUI();
            for (int i = 0; i < Files.Count; i++)
            {
                try
                {
                    if (Files[i].EndsWith(".dat", StringComparison.InvariantCultureIgnoreCase) || Files[i].EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase) || Files[i].EndsWith(".cfg", StringComparison.InvariantCultureIgnoreCase))
                    {
                        string currentTrainFolder = System.IO.Path.GetDirectoryName(Files[i]);
                        bool   canLoad            = false;
                        for (int j = 0; j < Program.CurrentHost.Plugins.Length; j++)
                        {
                            if (Program.CurrentHost.Plugins[j].Train != null && Program.CurrentHost.Plugins[j].Train.CanLoadTrain(currentTrainFolder))
                            {
                                Control[] dummyControls = new Control[0];
                                TrainManager.Trains = new[] { new TrainBase(TrainState.Available) };
                                AbstractTrain playerTrain = TrainManager.Trains[0];
                                Program.CurrentHost.Plugins[j].Train.LoadTrain(Encoding.UTF8, currentTrainFolder, ref playerTrain, ref dummyControls);
                                TrainManager.PlayerTrain = TrainManager.Trains[0];
                                canLoad = true;
                                break;
                            }
                        }

                        if (canLoad)
                        {
                            TrainManager.PlayerTrain.Initialize();
                            foreach (var Car in TrainManager.PlayerTrain.Cars)
                            {
                                double length = TrainManager.PlayerTrain.Cars[0].Length;
                                Car.Move(-length);
                                Car.Move(length);
                            }
                            TrainManager.PlayerTrain.PlaceCars(0);
                            for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                            {
                                TrainManager.PlayerTrain.Cars[j].UpdateTrackFollowers(0, true, false);
                                TrainManager.PlayerTrain.Cars[j].UpdateTopplingCantAndSpring(0.0);
                                TrainManager.PlayerTrain.Cars[j].ChangeCarSection(CarSectionType.Exterior);
                                TrainManager.PlayerTrain.Cars[j].FrontBogie.UpdateTopplingCantAndSpring();
                                TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                                TrainManager.PlayerTrain.Cars[j].RearBogie.UpdateTopplingCantAndSpring();
                                TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                                TrainManager.PlayerTrain.Cars[j].Coupler.ChangeSection(0);
                            }
                        }
                        else
                        {
                            //As we now attempt to load the train as a whole, the most likely outcome is that the train.dat file is MIA
                            Interface.AddMessage(MessageType.Critical, false, "No plugin found capable of loading file " + Files[i] + ".");
                        }
                    }
                    else
                    {
                        UnifiedObject o;
                        if (CurrentHost.LoadObject(Files[i], System.Text.Encoding.UTF8, out o))
                        {
                            o.CreateObject(Vector3.Zero, 0.0, 0.0, 0.0);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + ".");
                }
            }

            NearestTrain.UpdateSpecs();
            NearestTrain.Apply();
            formTrain.Instance?.EnableUI();

            Renderer.InitializeVisibility();
            Renderer.UpdateViewingDistances(600);
            Renderer.UpdateVisibility(0.0, true);
            ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
            Program.TrainManager.UpdateTrainObjects(0.0, true);
            Renderer.ApplyBackgroundColor();
        }
Ejemplo n.º 9
0
        /// <summary>Updates the specified signal section</summary>
        /// <param name="Section"></param>
        /// <param name="PreviousSection"></param>
        public void UpdateSection(Section Section, out Section PreviousSection)
        {
            if (Section == null)
            {
                PreviousSection = null;
                return;
            }

            // preparations
            int  zeroAspect;
            bool setToRed = false;

            if (Section.Type == SectionType.ValueBased)
            {
                // value-based
                zeroAspect = 0;

                for (int i = 1; i < Section.Aspects.Length; i++)
                {
                    if (Section.Aspects[i].Number < Section.Aspects[zeroAspect].Number)
                    {
                        zeroAspect = i;
                    }
                }
            }
            else
            {
                // index-based
                zeroAspect = 0;
            }

            // hold station departure signal at red
            int d = Section.StationIndex;

            if (d >= 0)
            {
                // look for train in previous blocks
                Section       l     = Section.PreviousSection;
                AbstractTrain train = null;

                while (true)
                {
                    if (l != null)
                    {
                        train = l.GetFirstTrain(false);

                        if (train != null)
                        {
                            break;
                        }

                        l = l.PreviousSection;
                    }
                    else
                    {
                        break;
                    }
                }

                if (train == null)
                {
                    double b = -Double.MaxValue;

                    foreach (AbstractTrain t in currentHost.Trains)
                    {
                        if (t.State == TrainState.Available)
                        {
                            if (t.TimetableDelta > b)
                            {
                                b     = t.TimetableDelta;
                                train = t;
                            }
                        }
                    }
                }

                // set to red where applicable
                if (train != null)
                {
                    if (!Section.TrainReachedStopPoint)
                    {
                        if (train.Station == d)
                        {
                            int c = Stations[d].GetStopIndex(train.NumberOfCars);

                            if (c >= 0)
                            {
                                double p0 = train.FrontCarTrackPosition();
                                double p1 = Stations[d].Stops[c].TrackPosition - Stations[d].Stops[c].BackwardTolerance;

                                if (p0 >= p1)
                                {
                                    Section.TrainReachedStopPoint = true;
                                }
                            }
                            else
                            {
                                Section.TrainReachedStopPoint = true;
                            }
                        }
                    }

                    double t = -15.0;

                    if (Stations[d].DepartureTime >= 0.0)
                    {
                        t = Stations[d].DepartureTime - 15.0;
                    }
                    else if (Stations[d].ArrivalTime >= 0.0)
                    {
                        t = Stations[d].ArrivalTime;
                    }

                    if (train.IsPlayerTrain & Stations[d].Type != StationType.Normal & Stations[d].DepartureTime < 0.0)
                    {
                        setToRed = true;
                    }
                    else if (t >= 0.0 & SecondsSinceMidnight < t - train.TimetableDelta)
                    {
                        setToRed = true;
                    }
                    else if (!Section.TrainReachedStopPoint)
                    {
                        setToRed = true;
                    }
                }
                else if (Stations[d].Type != StationType.Normal)
                {
                    setToRed = true;
                }
            }

            // train in block
            if (!Section.IsFree())
            {
                setToRed = true;
            }

            // free sections
            int newAspect = -1;

            if (setToRed)
            {
                Section.FreeSections = 0;
                newAspect            = zeroAspect;
            }
            else
            {
                Section n = Section.NextSection;

                if (n != null)
                {
                    if (n.FreeSections == -1)
                    {
                        Section.FreeSections = -1;
                    }
                    else
                    {
                        Section.FreeSections = n.FreeSections + 1;
                    }
                }
                else
                {
                    Section.FreeSections = -1;
                }
            }

            // change aspect
            if (newAspect == -1)
            {
                if (Section.Type == SectionType.ValueBased)
                {
                    // value-based
                    Section n = Section.NextSection;
                    int     a = Section.Aspects.Last().Number;

                    if (n != null && n.CurrentAspect >= 0)
                    {
                        a = n.Aspects[n.CurrentAspect].Number;
                    }

                    for (int i = Section.Aspects.Length - 1; i >= 0; i--)
                    {
                        if (Section.Aspects[i].Number > a)
                        {
                            newAspect = i;
                        }
                    }

                    if (newAspect == -1)
                    {
                        newAspect = Section.Aspects.Length - 1;
                    }
                }
                else
                {
                    // index-based
                    if (Section.FreeSections >= 0 & Section.FreeSections < Section.Aspects.Length)
                    {
                        newAspect = Section.FreeSections;
                    }
                    else
                    {
                        newAspect = Section.Aspects.Length - 1;
                    }
                }
            }

            // apply new aspect
            Section.CurrentAspect = newAspect;

            // update previous section
            PreviousSection = Section.PreviousSection;
        }
Ejemplo n.º 10
0
 /// <summary>Updates the object</summary>
 /// <param name="NearestTrain">The nearest train to this object</param>
 /// <param name="TimeElapsed">The time elapsed in milliseconds</param>
 /// <param name="ForceUpdate">Whether this is a forced update (e.g. Change of viewpoint) or periodic</param>
 /// <param name="CurrentlyVisible">Whether the object is currently visble to the player</param>
 public abstract void Update(AbstractTrain NearestTrain, double TimeElapsed, bool ForceUpdate, bool CurrentlyVisible);
Ejemplo n.º 11
0
 /// <summary>Plays a car sound.</summary>
 /// <param name="sound">The car sound.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="train">The train the sound is attached to.</param>
 /// <param name="car">The car in the train the sound is attached to.</param>
 /// <param name="looped">Whether to play the sound in a loop.</param>
 /// <returns>The sound source.</returns>
 internal static void PlayCarSound(TrainManager.CarSound sound, double pitch, double volume, AbstractTrain train, int car, bool looped)
 {
     if (sound.Buffer == null)
     {
         return;
     }
     if (train == null)
     {
         throw new InvalidDataException("A train and car must be specified");
     }
     sound.Source = PlaySound(sound.Buffer, pitch, volume, sound.Position, train, car, looped);
 }
Ejemplo n.º 12
0
 /// <summary>The unconditional event trigger function</summary>
 /// <param name="Direction">The direction:
 ///  1 - Forwards
 /// -1 - Reverse</param>
 /// <param name="TriggerType">The trigger type (Car axle, camera follower etc.)</param>
 /// <param name="Train">The train, or a null reference</param>
 /// <param name="Car">The car, or a null reference</param>
 public abstract void Trigger(int Direction, EventTriggerType TriggerType, AbstractTrain Train, AbstractCar Car);
Ejemplo n.º 13
0
        /// <summary>Called every frame to update the plugin.</summary>
        public void UpdatePlugin()
        {
            if (Train.Cars == null || Train.Cars.Length == 0)
            {
                return;
            }

            /*
             * Prepare the vehicle state.
             * */
            double location = this.Train.Cars[0].FrontAxle.Follower.TrackPosition - this.Train.Cars[0].FrontAxle.Position + 0.5 * this.Train.Cars[0].Length;

            //If the list of stations has not been loaded, do so
            if (!StationsLoaded)
            {
                currentRouteStations = new List <Station>();
                int s = 0;
                foreach (RouteStation selectedStation in TrainManagerBase.CurrentRoute.Stations)
                {
                    double stopPosition = -1;
                    int    stopIdx      = TrainManagerBase.CurrentRoute.Stations[s].GetStopIndex(Train.NumberOfCars);
                    if (selectedStation.Stops.Length != 0)
                    {
                        stopPosition = selectedStation.Stops[stopIdx].TrackPosition;
                    }

                    Station i = new Station(selectedStation, stopPosition);
                    currentRouteStations.Add(i);
                    s++;
                }

                StationsLoaded = true;
            }

            //End of additions
            double       speed       = this.Train.Cars[this.Train.DriverCar].Specs.PerceivedSpeed;
            double       bcPressure  = this.Train.Cars[this.Train.DriverCar].CarBrake.brakeCylinder.CurrentPressure;
            double       mrPressure  = this.Train.Cars[this.Train.DriverCar].CarBrake.mainReservoir.CurrentPressure;
            double       erPressure  = this.Train.Cars[this.Train.DriverCar].CarBrake.equalizingReservoir.CurrentPressure;
            double       bpPressure  = this.Train.Cars[this.Train.DriverCar].CarBrake.brakePipe.CurrentPressure;
            double       sapPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.straightAirPipe.CurrentPressure;
            VehicleState vehicle     = new VehicleState(location, new Speed(speed), bcPressure, mrPressure, erPressure, bpPressure, sapPressure, this.Train.Cars[0].FrontAxle.Follower);

            /*
             * Prepare the preceding vehicle state.
             * */


            PrecedingVehicleState precedingVehicle;

            try
            {
                AbstractTrain closestTrain = TrainManagerBase.currentHost.ClosestTrain(this.Train);
                precedingVehicle = closestTrain != null ? new PrecedingVehicleState(closestTrain.RearCarTrackPosition(), closestTrain.RearCarTrackPosition() - location, new Speed(closestTrain.CurrentSpeed)) : new PrecedingVehicleState(Double.MaxValue, Double.MaxValue - location, new Speed(0.0));
            }
            catch
            {
                precedingVehicle = null;
            }

            /*
             * Get the driver handles.
             * */
            OpenBveApi.Runtime.Handles handles = GetHandles();

            /*
             * Update the plugin.
             * */
            double totalTime   = TrainManagerBase.currentHost.InGameTime;
            double elapsedTime = TrainManagerBase.currentHost.InGameTime - LastTime;

            ElapseData data = new ElapseData(vehicle, precedingVehicle, handles, this.Train.SafetySystems.DoorInterlockState, new Time(totalTime), new Time(elapsedTime), currentRouteStations, TrainManagerBase.Renderer.Camera.CurrentMode, Translations.CurrentLanguageCode, this.Train.Destination);
            ElapseData inputDevicePluginData = data;

            LastTime = TrainManagerBase.currentHost.InGameTime;
            Elapse(ref data);
            this.PluginMessage = data.DebugMessage;
            this.Train.SafetySystems.DoorInterlockState = data.DoorInterlockState;
            DisableTimeAcceleration = data.DisableTimeAcceleration;
            for (int i = 0; i < InputDevicePlugin.AvailablePluginInfos.Count; i++)
            {
                if (InputDevicePlugin.AvailablePluginInfos[i].Status == InputDevicePlugin.PluginInfo.PluginStatus.Enable)
                {
                    InputDevicePlugin.AvailablePlugins[i].SetElapseData(inputDevicePluginData);
                }
            }

            /*
             * Set the virtual handles.
             * */
            this.PluginValid = true;
            SetHandles(data.Handles, true);
            this.Train.Destination = data.Destination;
        }
Ejemplo n.º 14
0
        public override bool LoadTrain(Encoding Encoding, string trainPath, ref AbstractTrain train, ref Control[] currentControls)
        {
            CurrentProgress = 0.0;
            LastProgress    = 0.0;
            IsLoading       = true;
            CurrentControls = currentControls;
            TrainBase currentTrain = train as TrainBase;

            if (currentTrain == null)
            {
                currentHost.ReportProblem(ProblemType.InvalidData, "Train was not valid");
                IsLoading = false;
                return(false);
            }

            if (currentTrain.State == TrainState.Bogus)
            {
                // bogus train
                string TrainData = Path.CombineFile(FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat");
                TrainDatParser.Parse(TrainData, Encoding.UTF8, currentTrain);
                Thread.Sleep(1);

                if (Cancel)
                {
                    IsLoading = false;
                    return(false);
                }
            }
            else
            {
                currentTrain.TrainFolder = trainPath;
                // real train
                if (currentTrain.IsPlayerTrain)
                {
                    FileSystem.AppendToLogFile("Loading player train: " + currentTrain.TrainFolder);
                }
                else
                {
                    FileSystem.AppendToLogFile("Loading AI train: " + currentTrain.TrainFolder);
                }

                string TrainData = null;
                if (!currentTrain.IsPlayerTrain)
                {
                    TrainData = Path.CombineFile(currentTrain.TrainFolder, "train.ai");
                }
                if (currentTrain.IsPlayerTrain || !File.Exists(TrainData))
                {
                    TrainData = Path.CombineFile(currentTrain.TrainFolder, "train.dat");
                }
                TrainDatParser.Parse(TrainData, Encoding, currentTrain);
                LastProgress = 0.1;
                Thread.Sleep(1);
                if (Cancel)
                {
                    return(false);
                }
                SoundCfgParser.ParseSoundConfig(currentTrain);
                LastProgress = 0.2;
                Thread.Sleep(1);
                if (Cancel)
                {
                    IsLoading = false;
                    return(false);
                }
                // door open/close speed
                for (int i = 0; i < currentTrain.Cars.Length; i++)
                {
                    currentTrain.Cars[i].DetermineDoorClosingSpeed();
                }
            }
            // add panel section
            if (currentTrain.IsPlayerTrain)
            {
                ParsePanelConfig(currentTrain, Encoding);
                LastProgress = 0.6;
                Thread.Sleep(1);
                if (Cancel)
                {
                    IsLoading = false;
                    return(false);
                }
                FileSystem.AppendToLogFile("Train panel loaded sucessfully.");
            }
            // add exterior section
            if (currentTrain.State != TrainState.Bogus)
            {
                bool[]          VisibleFromInterior;
                UnifiedObject[] CarObjects     = new UnifiedObject[currentTrain.Cars.Length];
                UnifiedObject[] BogieObjects   = new UnifiedObject[currentTrain.Cars.Length * 2];
                UnifiedObject[] CouplerObjects = new UnifiedObject[currentTrain.Cars.Length];

                string tXml = Path.CombineFile(currentTrain.TrainFolder, "train.xml");
                if (File.Exists(tXml))
                {
                    TrainXmlParser.Parse(tXml, currentTrain, ref CarObjects, ref BogieObjects, ref CouplerObjects, out VisibleFromInterior);
                }
                else
                {
                    ExtensionsCfgParser.ParseExtensionsConfig(currentTrain.TrainFolder, Encoding, ref CarObjects, ref BogieObjects, ref CouplerObjects, out VisibleFromInterior, currentTrain);
                }

                currentTrain.CameraCar = currentTrain.DriverCar;
                Thread.Sleep(1);
                if (Cancel)
                {
                    IsLoading = false;
                    return(false);
                }
                //Stores the current array index of the bogie object to add
                //Required as there are two bogies per car, and we're using a simple linear array....
                int currentBogieObject = 0;
                for (int i = 0; i < currentTrain.Cars.Length; i++)
                {
                    if (CarObjects[i] == null)
                    {
                        // load default exterior object
                        string file = Path.CombineFile(FileSystem.GetDataFolder("Compatibility"), "exterior.csv");
                        currentHost.LoadStaticObject(file, Encoding.UTF8, false, out var so);
                        if (so == null)
                        {
                            CarObjects[i] = null;
                        }
                        else
                        {
                            StaticObject c = (StaticObject)so.Clone();                              //Clone as otherwise the cached object doesn't scale right
                            c.ApplyScale(currentTrain.Cars[i].Width, currentTrain.Cars[i].Height, currentTrain.Cars[i].Length);
                            CarObjects[i] = c;
                        }
                    }

                    if (CarObjects[i] != null)
                    {
                        // add object
                        currentTrain.Cars[i].LoadCarSections(CarObjects[i], VisibleFromInterior[i]);
                    }

                    if (CouplerObjects[i] != null)
                    {
                        currentTrain.Cars[i].Coupler.LoadCarSections(CouplerObjects[i], VisibleFromInterior[i]);
                    }

                    //Load bogie objects
                    if (BogieObjects[currentBogieObject] != null)
                    {
                        currentTrain.Cars[i].FrontBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]);
                    }

                    currentBogieObject++;
                    if (BogieObjects[currentBogieObject] != null)
                    {
                        currentTrain.Cars[i].RearBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]);
                    }

                    currentBogieObject++;
                }
            }
            // place cars
            currentTrain.PlaceCars(0.0);
            currentControls = CurrentControls;
            IsLoading       = false;
            return(true);
        }
Ejemplo n.º 15
0
 /// <summary>Executes a function script in the host application</summary>
 /// <param name="functionScript">The function script to execute</param>
 /// <param name="train">The train or a null reference</param>
 /// <param name="CarIndex">The car index</param>
 /// <param name="Position">The world position</param>
 /// <param name="TrackPosition">The linear track position</param>
 /// <param name="SectionIndex">The index to the signalling section</param>
 /// <param name="IsPartOfTrain">Whether this is part of a train</param>
 /// <param name="TimeElapsed">The frame time elapsed</param>
 /// <param name="CurrentState">The current state of the attached object</param>
 public virtual void ExecuteFunctionScript(FunctionScripting.FunctionScript functionScript, AbstractTrain train, int CarIndex, Vector3 Position, double TrackPosition, int SectionIndex, bool IsPartOfTrain, double TimeElapsed, int CurrentState)
 {
 }
Ejemplo n.º 16
0
            /// <summary> Updates the position and state of the animated object</summary>
            /// <param name="IsPartOfTrain">Whether this object forms part of a train</param>
            /// <param name="Train">The train, or a null reference otherwise</param>
            /// <param name="CarIndex">If this object forms part of a train, the car index it refers to</param>
            /// <param name="SectionIndex">If this object has been placed via Track.Sig, the index of the section it is attached to</param>
            /// <param name="TrackPosition"></param>
            /// <param name="Position"></param>
            /// <param name="Direction"></param>
            /// <param name="Up"></param>
            /// <param name="Side"></param>
            /// <param name="Overlay">Whether this object should be overlaid over the other objects on-screen (Forms part of the cab etc.)</param>
            /// <param name="UpdateFunctions">Whether the functions associated with this object should be re-evaluated</param>
            /// <param name="Show"></param>
            /// <param name="TimeElapsed">The time elapsed since this object was last updated</param>
            /// <param name="EnableDamping">Whether damping is to be applied for this call</param>
            /// <param name="IsTouch">Whether Animated Object belonging to TouchElement class.</param>
            internal void Update(bool IsPartOfTrain, AbstractTrain Train, int CarIndex, int SectionIndex, double TrackPosition, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, bool Overlay, bool UpdateFunctions, bool Show, double TimeElapsed, bool EnableDamping, bool IsTouch = false)
            {
                int s = CurrentState;
                int i = ObjectIndex;

                // state change
                if (StateFunction != null & UpdateFunctions)
                {
                    double sd = StateFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    int    si = (int)Math.Round(sd);
                    int    sn = States.Length;
                    if (si < 0 | si >= sn)
                    {
                        si = -1;
                    }
                    if (s != si)
                    {
                        Initialize(si, Overlay, Show);
                        s = si;
                    }
                }
                if (s == -1)
                {
                    return;
                }
                // translation
                if (TranslateXFunction != null)
                {
                    double x;
                    if (UpdateFunctions)
                    {
                        x = TranslateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        x = TranslateXFunction.LastResult;
                    }
                    Vector3 translationVector = new Vector3(TranslateXDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= x;
                    Position          += translationVector;
                }
                else if (TranslateXScriptFile != null)
                {
                    //Translate X Script
                    if (TranslateXAnimationScript == null)
                    {
                        //Load the script if required
                        try
                        {
                            CSScript.GlobalSettings.TargetFramework = "v4.0";
                            TranslateXAnimationScript = CSScript.LoadCodeFrom(TranslateXScriptFile)
                                                        .CreateObject("OpenBVEScript")
                                                        .AlignToInterface <AnimationScript>(true);
                        }
                        catch
                        {
                            Interface.AddMessage(MessageType.Error, false,
                                                 "An error occcured whilst parsing script " + TranslateXScriptFile);
                            TranslateXScriptFile = null;
                            return;
                        }
                    }
                    double x = TranslateXAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                       IsPartOfTrain, TimeElapsed);
                    Vector3 translationVector = new Vector3(TranslateXDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= x;
                    Position          += translationVector;
                }


                if (TranslateYFunction != null)
                {
                    double y;
                    if (UpdateFunctions)
                    {
                        y = TranslateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        y = TranslateYFunction.LastResult;
                    }
                    Vector3 translationVector = new Vector3(TranslateYDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= y;
                    Position          += translationVector;
                }
                else if (TranslateYScriptFile != null)
                {
                    //Translate X Script
                    if (TranslateYAnimationScript == null)
                    {
                        //Load the script if required
                        try
                        {
                            CSScript.GlobalSettings.TargetFramework = "v4.0";
                            TranslateYAnimationScript = CSScript.LoadCodeFrom(TranslateYScriptFile)
                                                        .CreateObject("OpenBVEScript")
                                                        .AlignToInterface <AnimationScript>(true);
                        }
                        catch
                        {
                            Interface.AddMessage(MessageType.Error, false,
                                                 "An error occcured whilst parsing script " + TranslateYScriptFile);
                            TranslateYScriptFile = null;
                            return;
                        }
                    }
                    double y = TranslateYAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                       IsPartOfTrain, TimeElapsed);
                    Vector3 translationVector = new Vector3(TranslateYDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= y;
                    Position          += translationVector;
                }

                if (TranslateZFunction != null)
                {
                    double z;
                    if (UpdateFunctions)
                    {
                        z = TranslateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        z = TranslateZFunction.LastResult;
                    }
                    Vector3 translationVector = new Vector3(TranslateZDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= z;
                    Position          += translationVector;
                }
                else if (TranslateZScriptFile != null)
                {
                    //Translate X Script
                    if (TranslateZAnimationScript == null)
                    {
                        //Load the script if required
                        try
                        {
                            CSScript.GlobalSettings.TargetFramework = "v4.0";
                            TranslateZAnimationScript = CSScript.LoadCodeFrom(TranslateZScriptFile)
                                                        .CreateObject("OpenBVEScript")
                                                        .AlignToInterface <AnimationScript>(true);
                        }
                        catch
                        {
                            Interface.AddMessage(MessageType.Error, false,
                                                 "An error occcured whilst parsing script " + TranslateZScriptFile);
                            TranslateZScriptFile = null;
                            return;
                        }
                    }
                    double z = TranslateZAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex,
                                                                       IsPartOfTrain, TimeElapsed);
                    Vector3 translationVector = new Vector3(TranslateZDirection);                     //Must clone
                    translationVector.Rotate(Direction, Up, Side);
                    translationVector *= z;
                    Position          += translationVector;
                }
                // rotation
                bool   rotateX = RotateXFunction != null;
                bool   rotateY = RotateYFunction != null;
                bool   rotateZ = RotateZFunction != null;
                double cosX, sinX;

                if (rotateX)
                {
                    double a;
                    if (UpdateFunctions)
                    {
                        a = RotateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        a = RotateXFunction.LastResult;
                    }
                    if (RotateXDamping != null)
                    {
                        RotateXDamping.Update(TimeElapsed, ref a, EnableDamping);
                    }
                    cosX = Math.Cos(a);
                    sinX = Math.Sin(a);
                }
                else
                {
                    cosX = 0.0; sinX = 0.0;
                }
                double cosY, sinY;

                if (rotateY)
                {
                    double a;
                    if (UpdateFunctions)
                    {
                        a = RotateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        a = RotateYFunction.LastResult;
                    }
                    if (RotateYDamping != null)
                    {
                        RotateYDamping.Update(TimeElapsed, ref a, EnableDamping);
                    }
                    cosY = Math.Cos(a);
                    sinY = Math.Sin(a);
                }
                else
                {
                    cosY = 0.0; sinY = 0.0;
                }
                double cosZ, sinZ;

                if (rotateZ)
                {
                    double a;
                    if (UpdateFunctions)
                    {
                        a = RotateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        a = RotateZFunction.LastResult;
                    }
                    if (RotateZDamping != null)
                    {
                        RotateZDamping.Update(TimeElapsed, ref a, EnableDamping);
                    }
                    cosZ = Math.Cos(a);
                    sinZ = Math.Sin(a);
                }
                else
                {
                    cosZ = 0.0; sinZ = 0.0;
                }
                // texture shift
                bool shiftx = TextureShiftXFunction != null;
                bool shifty = TextureShiftYFunction != null;

                if ((shiftx | shifty) & UpdateFunctions)
                {
                    for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++)
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates = States[s].Object.Mesh.Vertices[k].TextureCoordinates;
                    }
                    if (shiftx)
                    {
                        double x = TextureShiftXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                        x -= Math.Floor(x);
                        for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++)
                        {
                            ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(x * TextureShiftXDirection.X);
                            ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(x * TextureShiftXDirection.Y);
                        }
                    }
                    if (shifty)
                    {
                        double y = TextureShiftYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                        y -= Math.Floor(y);
                        for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++)
                        {
                            ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(y * TextureShiftYDirection.X);
                            ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(y * TextureShiftYDirection.Y);
                        }
                    }
                }
                // led
                bool   led = LEDFunction != null;
                double ledangle;

                if (led)
                {
                    if (UpdateFunctions)
                    {
                        ledangle = LEDFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
                    }
                    else
                    {
                        ledangle = LEDFunction.LastResult;
                    }
                }
                else
                {
                    ledangle = 0.0;
                }
                // null object
                if (States[s].Object == null)
                {
                    return;
                }
                // initialize vertices
                for (int k = 0; k < States[s].Object.Mesh.Vertices.Length; k++)
                {
                    ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates = States[s].Object.Mesh.Vertices[k].Coordinates;
                }
                // led
                if (led)
                {
                    /*
                     * Edges:         Vertices:
                     * 0 - bottom     0 - bottom-left
                     * 1 - left       1 - top-left
                     * 2 - top        2 - top-right
                     * 3 - right      3 - bottom-right
                     *                4 - center
                     * */
                    int v = 1;
                    if (LEDClockwiseWinding)
                    {
                        /* winding is clockwise*/
                        if (ledangle < LEDInitialAngle)
                        {
                            ledangle = LEDInitialAngle;
                        }
                        if (ledangle < LEDLastAngle)
                        {
                            double currentEdgeFloat = Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
                            int    currentEdge      = ((int)currentEdgeFloat % 4 + 4) % 4;
                            double lastEdgeFloat    = Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449));
                            int    lastEdge         = ((int)lastEdgeFloat % 4 + 4) % 4;
                            if (lastEdge < currentEdge | lastEdge == currentEdge & Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0)
                            {
                                lastEdge += 4;
                            }
                            if (currentEdge == lastEdge)
                            {
                                /* current angle to last angle */
                                {
                                    double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                    double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                    double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                    States[s].Object.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz);
                                    v++;
                                }
                                {
                                    double t = 0.5 + (0.636619772367582 * LEDLastAngle) - lastEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                    double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                    double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                    States[s].Object.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz);
                                    v++;
                                }
                            }
                            else
                            {
                                {
                                    /* current angle to square vertex */
                                    double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                    double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                    double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = new Vector3(cx, cy, cz);
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = LEDVectors[currentEdge];
                                    v += 2;
                                }
                                for (int j = currentEdge + 1; j < lastEdge; j++)
                                {
                                    /* square-vertex to square-vertex */
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4];
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4];
                                    v += 2;
                                }
                                {
                                    /* square vertex to last angle */
                                    double t = 0.5 + (0.636619772367582 * LEDLastAngle) - lastEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge % 4].X;
                                    double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge % 4].Y;
                                    double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge % 4].Z;
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(lastEdge + 3) % 4];
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = new Vector3(lx, ly, lz);
                                    v += 2;
                                }
                            }
                        }
                    }
                    else
                    {
                        /* winding is counter-clockwise*/
                        if (ledangle > LEDInitialAngle)
                        {
                            ledangle = LEDInitialAngle;
                        }
                        if (ledangle > LEDLastAngle)
                        {
                            double currentEdgeFloat = Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
                            int    currentEdge      = ((int)currentEdgeFloat % 4 + 4) % 4;
                            double lastEdgeFloat    = Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449));
                            int    lastEdge         = ((int)lastEdgeFloat % 4 + 4) % 4;
                            if (currentEdge < lastEdge | lastEdge == currentEdge & Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0)
                            {
                                currentEdge += 4;
                            }
                            if (currentEdge == lastEdge)
                            {
                                /* current angle to last angle */
                                {
                                    double t = 0.5 + (0.636619772367582 * LEDLastAngle) - lastEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                    double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                    double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                    States[s].Object.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz);
                                    v++;
                                }
                                {
                                    double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = t - Math.Floor(t);
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X;
                                    double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y;
                                    double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z;
                                    States[s].Object.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz);
                                    v++;
                                }
                            }
                            else
                            {
                                {
                                    /* current angle to square vertex */
                                    double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge % 4].X;
                                    double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge % 4].Y;
                                    double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge % 4].Z;
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(currentEdge + 3) % 4];
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = new Vector3(cx, cy, cz);
                                    v += 2;
                                }
                                for (int j = currentEdge - 1; j > lastEdge; j--)
                                {
                                    /* square-vertex to square-vertex */
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4];
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4];
                                    v += 2;
                                }
                                {
                                    /* square vertex to last angle */
                                    double t = 0.5 + (0.636619772367582 * LEDLastAngle) - lastEdgeFloat;
                                    if (t < 0.0)
                                    {
                                        t = 0.0;
                                    }
                                    else if (t > 1.0)
                                    {
                                        t = 1.0;
                                    }
                                    t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
                                    double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X;
                                    double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y;
                                    double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z;
                                    States[s].Object.Mesh.Vertices[v + 0].Coordinates = new Vector3(lx, ly, lz);
                                    States[s].Object.Mesh.Vertices[v + 1].Coordinates = LEDVectors[lastEdge % 4];
                                    v += 2;
                                }
                            }
                        }
                    }
                    for (int j = v; v < 11; v++)
                    {
                        States[s].Object.Mesh.Vertices[j].Coordinates = LEDVectors[4];
                    }
                }
                // update vertices
                for (int k = 0; k < States[s].Object.Mesh.Vertices.Length; k++)
                {
                    // rotate
                    if (rotateX)
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateXDirection, cosX, sinX);
                    }
                    if (rotateY)
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateYDirection, cosY, sinY);
                    }
                    if (rotateZ)
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateZDirection, cosZ, sinZ);
                    }
                    // translate
                    if (Overlay & Camera.CurrentRestriction != CameraRestrictionMode.NotAvailable)
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates += States[s].Position - Position;
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(Camera.AbsoluteDirection, Camera.AbsoluteUp, Camera.AbsoluteSide);
                        double dx = -Math.Tan(Camera.CurrentAlignment.Yaw) - Camera.CurrentAlignment.Position.X;
                        double dy = -Math.Tan(Camera.CurrentAlignment.Pitch) - Camera.CurrentAlignment.Position.Y;
                        double dz = -Camera.CurrentAlignment.Position.Z;
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Camera.AbsolutePosition.X + dx * Camera.AbsoluteSide.X + dy * Camera.AbsoluteUp.X + dz * Camera.AbsoluteDirection.X;
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Camera.AbsolutePosition.Y + dx * Camera.AbsoluteSide.Y + dy * Camera.AbsoluteUp.Y + dz * Camera.AbsoluteDirection.Y;
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Camera.AbsolutePosition.Z + dx * Camera.AbsoluteSide.Z + dy * Camera.AbsoluteUp.Z + dz * Camera.AbsoluteDirection.Z;
                    }
                    else
                    {
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates += States[s].Position;
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(Direction, Up, Side);
                        ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates += Position;
                    }
                }
                // update normals
                for (int k = 0; k < States[s].Object.Mesh.Faces.Length; k++)
                {
                    for (int h = 0; h < States[s].Object.Mesh.Faces[k].Vertices.Length; h++)
                    {
                        ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal = States[s].Object.Mesh.Faces[k].Vertices[h].Normal;
                        if (!Vector3.IsZero(States[s].Object.Mesh.Faces[k].Vertices[h].Normal))
                        {
                            if (rotateX)
                            {
                                ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateXDirection, cosX, sinX);
                            }
                            if (rotateY)
                            {
                                ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateYDirection, cosY, sinY);
                            }
                            if (rotateZ)
                            {
                                ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateZDirection, cosZ, sinZ);
                            }
                            ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(Direction, Up, Side);
                        }
                    }
                    // visibility changed
                    // TouchElement is handled by another function.
                    if (!IsTouch)
                    {
                        if (Show)
                        {
                            if (Overlay)
                            {
                                Renderer.ShowObject(i, ObjectType.Overlay);
                            }
                            else
                            {
                                Renderer.ShowObject(i, ObjectType.Dynamic);
                            }
                        }
                        else
                        {
                            Renderer.HideObject(i);
                        }
                    }
                }
            }
Ejemplo n.º 17
0
 /// <summary>Processes a jump</summary>
 /// <param name="Train">The train to be jumped</param>
 /// <param name="StationIndex">The station to jump to</param>
 public virtual void ProcessJump(AbstractTrain Train, int StationIndex)
 {
 }
Ejemplo n.º 18
0
        public Coupler(double minimumDistance, double maximumDistance, CarBase frontCar, CarBase rearCar, AbstractTrain train)
        {
            MinimumDistanceBetweenCars = minimumDistance;
            MaximumDistanceBetweenCars = maximumDistance;
            baseCar = frontCar;
            if (rearCar != null)
            {
                connectedCar = rearCar;
            }
            else
            {
                connectedCar = frontCar;
            }

            CarSections = new CarSection[] { };
            baseTrain   = train;
        }
Ejemplo n.º 19
0
 /// <summary>Gets the closest train to the specified train</summary>
 /// <param name="Train">The specified train</param>
 /// <returns>The closest train, or null if no other trains</returns>
 public virtual AbstractTrain ClosestTrain(AbstractTrain Train)
 {
     return(null);
 }
Ejemplo n.º 20
0
        /// <summary>Gets the signal data for a plugin.</summary>
        /// <param name="train">The train.</param>
        /// <returns>The signal data.</returns>
        public SignalData GetPluginSignal(AbstractTrain train)
        {
            if (Exists(train))
            {
                int aspect;

                if (IsFree(train))
                {
                    if (Type == SectionType.IndexBased)
                    {
                        if (NextSection != null)
                        {
                            int value = NextSection.FreeSections;

                            if (value == -1)
                            {
                                value = Aspects.Length - 1;
                            }
                            else
                            {
                                value++;

                                if (value >= Aspects.Length)
                                {
                                    value = Aspects.Length - 1;
                                }

                                if (value < 0)
                                {
                                    value = 0;
                                }
                            }

                            aspect = Aspects[value].Number;
                        }
                        else
                        {
                            aspect = Aspects[Aspects.Length - 1].Number;
                        }
                    }
                    else
                    {
                        aspect = Aspects[Aspects.Length - 1].Number;

                        if (NextSection != null)
                        {
                            int value = NextSection.Aspects[NextSection.CurrentAspect].Number;

                            for (int i = 0; i < Aspects.Length; i++)
                            {
                                if (Aspects[i].Number > value)
                                {
                                    aspect = Aspects[i].Number;
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    aspect = Aspects[CurrentAspect].Number;
                }

                double position = train.FrontCarTrackPosition();
                double distance = TrackPosition - position;
                return(new SignalData(aspect, distance));
            }
            else
            {
                int    aspect   = Aspects[CurrentAspect].Number;
                double position = train.FrontCarTrackPosition();
                double distance = TrackPosition - position;
                return(new SignalData(aspect, distance));
            }
        }
        /// <inheritdoc/>
        public override void Update(AbstractTrain NearestTrain, double TimeElapsed, bool ForceUpdate, bool CurrentlyVisible)
        {
            if (CurrentlyVisible | ForceUpdate)
            {
                if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                {
                    double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                    Object.SecondsSinceLastUpdate = 0.0;
                    Object.Update(false, NearestTrain, NearestTrain == null ? 0 : NearestTrain.DriverCar, SectionIndex, TrackPosition, Position, Direction, Up, Side, true, true, timeDelta, true);
                    if (this.Object.CurrentState != this.lastState && currentHost.SimulationSetup)
                    {
                        if (this.SingleBuffer && this.Buffers[0] != null)
                        {
                            switch (this.Object.CurrentState)
                            {
                            case -1:
                                if (this.PlayOnHide)
                                {
                                    Source = currentHost.PlaySound(Buffers[0], currentPitch, currentVolume, Position, null, false);
                                }

                                break;

                            case 0:
                                if (this.PlayOnShow || this.lastState != -1)
                                {
                                    Source = currentHost.PlaySound(Buffers[0], currentPitch, currentVolume, Position, null, false);
                                }

                                break;

                            default:
                                Source = currentHost.PlaySound(Buffers[0], currentPitch, currentVolume, Position, null, false);
                                break;
                            }
                        }
                        else
                        {
                            int bufferIndex = this.Object.CurrentState + 1;
                            if (bufferIndex < this.Buffers.Length && this.Buffers[bufferIndex] != null)
                            {
                                switch (bufferIndex)
                                {
                                case 0:
                                    if (this.PlayOnHide)
                                    {
                                        Source = currentHost.PlaySound(Buffers[bufferIndex], currentPitch, currentVolume, Position, null, false);
                                    }

                                    break;

                                case 1:
                                    if (this.PlayOnShow || this.lastState != -1)
                                    {
                                        Source = currentHost.PlaySound(Buffers[bufferIndex], currentPitch, currentVolume, Position, null, false);
                                    }

                                    break;

                                default:
                                    Source = currentHost.PlaySound(Buffers[bufferIndex], currentPitch, currentVolume, Position, null, false);
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                }

                if (!base.Visible)
                {
                    currentHost.ShowObject(Object.internalObject, ObjectType.Dynamic);
                    base.Visible = true;
                }
            }
            else
            {
                Object.SecondsSinceLastUpdate += TimeElapsed;
                if (base.Visible)
                {
                    currentHost.HideObject(Object.internalObject);
                    base.Visible = false;
                }
            }

            this.lastState = this.Object.CurrentState;
        }
Ejemplo n.º 22
0
 public override void ExecuteFunctionScript(OpenBveApi.FunctionScripting.FunctionScript functionScript, AbstractTrain train, int CarIndex, Vector3 Position, double TrackPosition, int SectionIndex, bool IsPartOfTrain, double TimeElapsed, int CurrentState)
 {
     FunctionScripts.ExecuteFunctionScript(functionScript, (TrainManager.Train)train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState);
 }
Ejemplo n.º 23
0
 /// <summary>Creates a new sound source.</summary>
 /// <param name="buffer">The sound buffer.</param>
 /// <param name="radius">The effective sound radius.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="position">The position. If a train and car are specified, the position is relative to the car, otherwise absolute.</param>
 /// <param name="train">The train this sound source is attached to, or a null reference.</param>
 /// <param name="type">The type of sound</param>
 /// <param name="looped">Whether this sound source plays in a loop.</param>
 internal SoundSource(SoundBuffer buffer, double radius, double pitch, double volume, Vector3 position, AbstractTrain train, SoundType type, bool looped)
 {
     Buffer           = buffer;
     Radius           = radius;
     Pitch            = pitch;
     Volume           = volume;
     Position         = position;
     Parent           = train;
     Looped           = looped;
     State            = SoundSourceState.PlayPending;
     OpenAlSourceName = 0;
     //Set sound type manually
     Type = type;
 }