ShowObject() static private méthode

static private ShowObject ( int ObjectIndex, ObjectType Type ) : void
ObjectIndex int
Type ObjectType
Résultat void
Exemple #1
0
 internal void ChangeSection(int SectionIndex)
 {
     if (CarSections.Length == 0)
     {
         CurrentCarSection = -1;
         //Hack: If no bogie objects are defined, just return
         return;
     }
     for (int i = 0; i < CarSections.Length; i++)
     {
         for (int j = 0; j < CarSections[i].Elements.Length; j++)
         {
             int o = CarSections[i].Elements[j].ObjectIndex;
             Renderer.HideObject(o);
         }
     }
     if (SectionIndex >= 0)
     {
         CarSections[SectionIndex].Initialize(CurrentlyVisible);
         for (int j = 0; j < CarSections[SectionIndex].Elements.Length; j++)
         {
             int o = CarSections[SectionIndex].Elements[j].ObjectIndex;
             Renderer.ShowObject(o, ObjectType.Dynamic);
         }
     }
     CurrentCarSection = SectionIndex;
     UpdateObjects(0.0, true);
 }
Exemple #2
0
            internal void Initialize(int StateIndex, bool Overlay, bool Show)
            {
                int i = ObjectIndex;

                Renderer.HideObject(i);
                int t = StateIndex;

                if (t >= 0 && States[t].Object != null)
                {
                    int m = States[t].Object.Mesh.Vertices.Length;
                    ObjectManager.Objects[i].Mesh.Vertices = new VertexTemplate[m];
                    for (int k = 0; k < m; k++)
                    {
                        if (States[t].Object.Mesh.Vertices[k] is ColoredVertex)
                        {
                            ObjectManager.Objects[i].Mesh.Vertices[k] = new ColoredVertex((ColoredVertex)States[t].Object.Mesh.Vertices[k]);
                        }
                        else
                        {
                            ObjectManager.Objects[i].Mesh.Vertices[k] = new Vertex((Vertex)States[t].Object.Mesh.Vertices[k]);
                        }
                    }
                    m = States[t].Object.Mesh.Faces.Length;
                    ObjectManager.Objects[i].Mesh.Faces = new MeshFace[m];
                    for (int k = 0; k < m; k++)
                    {
                        ObjectManager.Objects[i].Mesh.Faces[k].Flags    = States[t].Object.Mesh.Faces[k].Flags;
                        ObjectManager.Objects[i].Mesh.Faces[k].Material = States[t].Object.Mesh.Faces[k].Material;
                        int o = States[t].Object.Mesh.Faces[k].Vertices.Length;
                        ObjectManager.Objects[i].Mesh.Faces[k].Vertices = new MeshFaceVertex[o];
                        for (int h = 0; h < o; h++)
                        {
                            ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h] = States[t].Object.Mesh.Faces[k].Vertices[h];
                        }
                    }
                    ObjectManager.Objects[i].Mesh.Materials = States[t].Object.Mesh.Materials;
                }
                else
                {
                    ObjectManager.Objects[i] = new StaticObject(Program.CurrentHost);
                }
                CurrentState = StateIndex;
                if (Show)
                {
                    if (Overlay)
                    {
                        Renderer.ShowObject(i, ObjectType.Overlay);
                    }
                    else
                    {
                        Renderer.ShowObject(i, ObjectType.Dynamic);
                    }
                }
            }
        /// <summary>Called once at the start of the simulation to setup the visibility for all objects</summary>
        internal static void InitializeVisibility()
        {
            // sort objects
            ObjectsSortedByStart = new int[ObjectsUsed];
            ObjectsSortedByEnd   = new int[ObjectsUsed];
            double[] a = new double[ObjectsUsed];
            double[] b = new double[ObjectsUsed];
            int      n = 0;

            for (int i = 0; i < ObjectsUsed; i++)
            {
                if (!Objects[i].Dynamic)
                {
                    ObjectsSortedByStart[n] = i;
                    ObjectsSortedByEnd[n]   = i;
                    a[n] = Objects[i].StartingDistance;
                    b[n] = Objects[i].EndingDistance;
                    n++;
                }
            }
            Array.Resize <int>(ref ObjectsSortedByStart, n);
            Array.Resize <int>(ref ObjectsSortedByEnd, n);
            Array.Resize <double>(ref a, n);
            Array.Resize <double>(ref b, n);
            Array.Sort <double, int>(a, ObjectsSortedByStart);
            Array.Sort <double, int>(b, ObjectsSortedByEnd);
            ObjectsSortedByStartPointer = 0;
            ObjectsSortedByEndPointer   = 0;
            // initial visiblity
            double p = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z;

            for (int i = 0; i < ObjectsUsed; i++)
            {
                if (!Objects[i].Dynamic)
                {
                    if (Objects[i].StartingDistance <= p + World.ForwardViewingDistance & Objects[i].EndingDistance >= p - World.BackwardViewingDistance)
                    {
                        Renderer.ShowObject(i, ObjectType.Static);
                    }
                }
            }
        }
Exemple #4
0
            internal void Show()
            {
                if (Groups.Length > 0)
                {
                    for (int i = 0; i < Groups[0].Elements.Length; i++)
                    {
                        int o = Groups[0].Elements[i].ObjectIndex;
                        if (Groups[0].Overlay)
                        {
                            Renderer.ShowObject(o, ObjectType.Overlay);
                        }
                        else
                        {
                            Renderer.ShowObject(o, ObjectType.Dynamic);
                        }
                    }
                }

                int add = CurrentAdditionalGroup + 1;

                if (add < Groups.Length)
                {
                    for (int i = 0; i < Groups[add].Elements.Length; i++)
                    {
                        int o = Groups[add].Elements[i].ObjectIndex;
                        if (Groups[add].Overlay)
                        {
                            Renderer.ShowObject(o, ObjectType.Overlay);
                        }
                        else
                        {
                            Renderer.ShowObject(o, ObjectType.Dynamic);
                        }
                    }
                }
            }
            internal override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                double       z           = Object.TranslateZFunction == null ? 0.0 : Object.TranslateZFunction.LastResult;
                double       pa          = TrackPosition + z - Radius - extraRadius;
                double       pb          = TrackPosition + z + Radius + extraRadius;
                double       ta          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z - World.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z + World.BackgroundImageDistance + World.ExtraViewingDistance;
                bool         visible     = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                    {
                        double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                        Object.SecondsSinceLastUpdate = 0.0;
                        TrainManager.Train train         = null;
                        double             trainDistance = double.MaxValue;
                        for (int j = 0; j < TrainManager.Trains.Length; j++)
                        {
                            if (TrainManager.Trains[j].State == TrainManager.TrainState.Available)
                            {
                                double distance;
                                if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < TrackPosition)
                                {
                                    distance = TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                                }
                                else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > TrackPosition)
                                {
                                    distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - TrackPosition;
                                }
                                else
                                {
                                    distance = 0;
                                }
                                if (distance < trainDistance)
                                {
                                    train         = TrainManager.Trains[j];
                                    trainDistance = distance;
                                }
                            }
                        }
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, Direction, Up, Side, false, true, true, timeDelta, true);
                        if (this.Object.CurrentState != this.lastState && Loading.SimulationSetup)
                        {
                            if (this.SingleBuffer && this.Buffers[0] != null)
                            {
                                switch (this.Object.CurrentState)
                                {
                                case -1:
                                    if (this.PlayOnHide)
                                    {
                                        this.Source = Sounds.PlaySound(this.Buffers[0], this.currentPitch, this.currentVolume, this.Position, false);
                                    }
                                    break;

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

                                default:
                                    this.Source = Sounds.PlaySound(this.Buffers[0], this.currentPitch, this.currentVolume, this.Position, 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)
                                        {
                                            this.Source = Sounds.PlaySound(this.Buffers[bufferIndex], this.currentPitch, this.currentVolume, this.Position, false);
                                        }
                                        break;

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

                                    default:
                                        this.Source = Sounds.PlaySound(this.Buffers[bufferIndex], this.currentPitch, this.currentVolume, this.Position, false);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
                this.lastState = this.Object.CurrentState;
            }
#pragma warning restore 0649

            public override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                double       z           = Object.TranslateZFunction == null ? 0.0 : Object.TranslateZFunction.LastResult;
                double       pa          = TrackPosition + z - Radius - extraRadius;
                double       pb          = TrackPosition + z + Radius + extraRadius;
                double       ta          = World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z - Backgrounds.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z + Backgrounds.BackgroundImageDistance + World.ExtraViewingDistance;
                bool         visible     = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                    {
                        double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                        Object.SecondsSinceLastUpdate = 0.0;
                        TrainManager.Train train         = null;
                        double             trainDistance = double.MaxValue;
                        for (int j = 0; j < TrainManager.Trains.Length; j++)
                        {
                            if (TrainManager.Trains[j].State == TrainState.Available)
                            {
                                double distance;
                                if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < TrackPosition)
                                {
                                    distance = TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                                }
                                else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > TrackPosition)
                                {
                                    distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - TrackPosition;
                                }
                                else
                                {
                                    distance = 0;
                                }
                                if (distance < trainDistance)
                                {
                                    train         = TrainManager.Trains[j];
                                    trainDistance = distance;
                                }
                            }
                        }
                        if (Visible)
                        {
                            //Calculate the distance travelled
                            double delta = UpdateTrackFollowerScript(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, true, timeDelta);
                            //Update the front and rear axle track followers
                            FrontAxleFollower.Update((TrackPosition + FrontAxlePosition) + delta, true, true);
                            RearAxleFollower.Update((TrackPosition + RearAxlePosition) + delta, true, true);
                            //Update the base object position
                            FrontAxleFollower.UpdateWorldCoordinates(false);
                            RearAxleFollower.UpdateWorldCoordinates(false);
                            UpdateObjectPosition();
                        }
                        //Update the actual animated object- This must be done last in case the user has used Translation or Rotation
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, FrontAxleFollower.TrackPosition, FrontAxleFollower.WorldPosition, Direction, Up, Side, false, true, true, timeDelta, true);
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
            }
        /// <summary>Is called to update the visibility of the camera</summary>
        /// <param name="TrackPosition">The camera's track position</param>
        internal static void UpdateVisibility(double TrackPosition)
        {
            double d = TrackPosition - LastUpdatedTrackPosition;
            int    n = ObjectsSortedByStart.Length;
            double p = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z;

            if (d < 0.0)
            {
                if (ObjectsSortedByStartPointer >= n)
                {
                    ObjectsSortedByStartPointer = n - 1;
                }

                if (ObjectsSortedByEndPointer >= n)
                {
                    ObjectsSortedByEndPointer = n - 1;
                }
                // dispose
                while (ObjectsSortedByStartPointer >= 0)
                {
                    int o = ObjectsSortedByStart[ObjectsSortedByStartPointer];
                    if (Objects[o].StartingDistance > p + World.ForwardViewingDistance)
                    {
                        Renderer.HideObject(o);
                        ObjectsSortedByStartPointer--;
                    }
                    else
                    {
                        break;
                    }
                }
                // introduce
                while (ObjectsSortedByEndPointer >= 0)
                {
                    int o = ObjectsSortedByEnd[ObjectsSortedByEndPointer];
                    if (Objects[o].EndingDistance >= p - World.BackwardViewingDistance)
                    {
                        if (Objects[o].StartingDistance <= p + World.ForwardViewingDistance)
                        {
                            Renderer.ShowObject(o, ObjectType.Static);
                        }
                        ObjectsSortedByEndPointer--;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else if (d > 0.0)
            {
                if (ObjectsSortedByStartPointer < 0)
                {
                    ObjectsSortedByStartPointer = 0;
                }

                if (ObjectsSortedByEndPointer < 0)
                {
                    ObjectsSortedByEndPointer = 0;
                }
                // dispose
                while (ObjectsSortedByEndPointer < n)
                {
                    int o = ObjectsSortedByEnd[ObjectsSortedByEndPointer];
                    if (Objects[o].EndingDistance < p - World.BackwardViewingDistance)
                    {
                        Renderer.HideObject(o);
                        ObjectsSortedByEndPointer++;
                    }
                    else
                    {
                        break;
                    }
                }
                // introduce
                while (ObjectsSortedByStartPointer < n)
                {
                    int o = ObjectsSortedByStart[ObjectsSortedByStartPointer];
                    if (Objects[o].StartingDistance <= p + World.ForwardViewingDistance)
                    {
                        if (Objects[o].EndingDistance >= p - World.BackwardViewingDistance)
                        {
                            Renderer.ShowObject(o, ObjectType.Static);
                        }
                        ObjectsSortedByStartPointer++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            LastUpdatedTrackPosition = TrackPosition;
        }
            internal override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                double       z           = Object.TranslateZFunction == null ? 0.0 : Object.TranslateZFunction.LastResult;
                double       pa          = TrackPosition + z - Radius - extraRadius;
                double       pb          = TrackPosition + z + Radius + extraRadius;
                double       ta          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z - World.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z + World.BackgroundImageDistance + World.ExtraViewingDistance;
                bool         visible     = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                    {
                        double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                        Object.SecondsSinceLastUpdate = 0.0;
                        TrainManager.Train train         = null;
                        double             trainDistance = double.MaxValue;
                        for (int j = 0; j < TrainManager.Trains.Length; j++)
                        {
                            if (TrainManager.Trains[j].State == TrainState.Available)
                            {
                                double distance;
                                if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < TrackPosition)
                                {
                                    distance = TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                                }
                                else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > TrackPosition)
                                {
                                    distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - TrackPosition;
                                }
                                else
                                {
                                    distance = 0;
                                }
                                if (distance < trainDistance)
                                {
                                    train         = TrainManager.Trains[j];
                                    trainDistance = distance;
                                }
                            }
                        }
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, Direction, Up, Side, false, true, true, timeDelta, true);
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
            }
Exemple #9
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);
                        }
                    }
                }
            }