/// <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) { int s = CurrentState; // 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); int sn = States.Length; if (si < 0 | si >= sn) { si = -1; } if (s != si) { Initialize(si, Camera != null, 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.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; 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.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; 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.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; 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); } radianX = a; } else { radianX = 0.0; } double radianY; 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); } radianY = a; } else { radianY = 0.0; } double radianZ; 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); } radianZ = a; } else { radianZ = 0.0; } // texture shift bool shiftx = TextureShiftXFunction != null; bool shifty = TextureShiftYFunction != null; internalObject.TextureTranslation = Matrix4D.Identity; if (shiftx | shifty) { if (shiftx) { double x; if (UpdateFunctions) { x = TextureShiftXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { x = TextureShiftXFunction.LastResult; } x -= System.Math.Floor(x); internalObject.TextureTranslation *= Matrix4D.CreateTranslation(x * TextureShiftXDirection.X, x * TextureShiftXDirection.Y, 1.0); } if (shifty) { double y; if (UpdateFunctions) { y = TextureShiftYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { y = TextureShiftYFunction.LastResult; } y -= System.Math.Floor(y); internalObject.TextureTranslation *= Matrix4D.CreateTranslation(y * TextureShiftYDirection.X, y * TextureShiftYDirection.Y, 1.0); } } // 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].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[s].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[s].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[s].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(cx, cy, cz); States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[currentEdge]; v += 2; } for (int j = currentEdge + 1; j < lastEdge; j++) { /* square-vertex to square-vertex */ States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4]; States[s].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[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(lastEdge + 3) % 4]; States[s].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[s].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[s].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[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(currentEdge + 3) % 4]; States[s].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[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4]; States[s].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[s].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(lx, ly, lz); States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[lastEdge % 4]; v += 2; } } } } for (int j = v; v < 11; v++) { States[s].Prototype.Mesh.Vertices[j].Coordinates = LEDVectors[4]; } } // update prototype internalObject.Prototype = States[s].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[s].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[s].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); } } }
/// <summary>Loads a list of compatibility signal objects</summary> /// <param name="currentHost">The host application interface</param> /// <param name="fileName">The file name of the object list</param> /// <param name="objects">The returned array of speed limits</param> /// <param name="signalPost">Sets the default signal post</param> /// <param name="speedLimits">The array of signal speed limits</param> /// <returns>An array of compatability signal objects</returns> public static void ReadCompatibilitySignalXML(HostInterface currentHost, string fileName, out CompatibilitySignalObject[] objects, out UnifiedObject signalPost, out double[] speedLimits) { signalPost = new StaticObject(currentHost); objects = new CompatibilitySignalObject[9]; //Default Japanese speed limits converted to m/s speedLimits = new[] { 0.0, 6.94444444444444, 15.2777777777778, 20.8333333333333, double.PositiveInfinity, double.PositiveInfinity }; XmlDocument currentXML = new XmlDocument(); currentXML.Load(fileName); string currentPath = System.IO.Path.GetDirectoryName(fileName); if (currentXML.DocumentElement != null) { XmlNode node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalSetName"); if (node != null) { currentHost.AddMessage(MessageType.Information, false, "INFO: Using the " + node.InnerText + " compatibility signal set."); } XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/Signal"); if (DocumentNodes != null) { int index = 0; foreach (XmlNode nn in DocumentNodes) { List <StaticObject> objectList = new List <StaticObject>(); List <int> aspectList = new List <int>(); try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect; if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the signal object list in the compatability signal file " + fileName); continue; } aspectList.Add(aspect); StaticObject staticObject = new StaticObject(currentHost); if (n.InnerText.ToLowerInvariant() != "null") { string objectFile = Path.CombineFile(currentPath, n.InnerText); if (File.Exists(objectFile)) { currentHost.LoadStaticObject(objectFile, Encoding.UTF8, false, out staticObject); } else { currentHost.AddMessage(MessageType.Error, true, "Compatibility signal file " + objectFile + " not found in " + fileName); } } objectList.Add(staticObject); } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } objects[index] = new CompatibilitySignalObject(aspectList.ToArray(), objectList.ToArray(), currentHost); index++; } } string signalPostFile = Path.CombineFile(currentPath, "Japanese\\signal_post.csv"); //default plain post try { node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalPost"); if (node != null) { string newFile = Path.CombineFile(currentPath, node.InnerText); if (File.Exists(newFile)) { signalPostFile = newFile; } } currentHost.LoadObject(signalPostFile, Encoding.UTF8, out signalPost); } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/SpeedLimits"); if (DocumentNodes != null) { foreach (XmlNode nn in DocumentNodes) { try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect = 0; if (n.Attributes != null) { if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the speed limit list in the compatability signal file " + fileName); continue; } } if (aspect <= speedLimits.Length) { int l = speedLimits.Length; Array.Resize(ref speedLimits, aspect + 1); for (int i = l; i < speedLimits.Length; i++) { speedLimits[i] = double.PositiveInfinity; } if (!NumberFormats.TryParseDoubleVb6(n.InnerText, out speedLimits[aspect])) { speedLimits[aspect] = double.MaxValue; if (n.InnerText.ToLowerInvariant() != "unlimited") { currentHost.AddMessage(MessageType.Error, true, "Invalid speed limit provided for aspect " + aspect + " in the compatability signal file " + fileName); } } else { //convert to m/s as that's what we use internally speedLimits[aspect] *= 0.277777777777778; } } } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } } } } }