public CarSection(HostInterface Host, ObjectType Type, bool visibleFromInterior, UnifiedObject Object = null) { currentHost = Host; Groups = new ElementsGroup[1]; Groups[0] = new ElementsGroup(Type); VisibleFromInterior = visibleFromInterior; if (Object is StaticObject) { StaticObject s = (StaticObject)Object; Groups[0].Elements = new AnimatedObject[1]; Groups[0].Elements[0] = new AnimatedObject(Host) { States = new[] { new ObjectState(s) }, CurrentState = 0 }; currentHost.CreateDynamicObject(ref Groups[0].Elements[0].internalObject); } else if (Object is AnimatedObjectCollection) { AnimatedObjectCollection a = (AnimatedObjectCollection)Object; Groups[0].Elements = new AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { Groups[0].Elements[h] = a.Objects[h].Clone(); currentHost.CreateDynamicObject(ref Groups[0].Elements[h].internalObject); } } }
/// <summary>Attempts to load and parse the current train's panel configuration file.</summary> /// <param name="Train">The train</param> /// <param name="Encoding">The selected train encoding</param> internal void ParsePanelConfig(TrainBase Train, Encoding Encoding) { Train.Cars[Train.DriverCar].CarSections = new CarSection[1]; Train.Cars[Train.DriverCar].CarSections[0] = new CarSection(currentHost, ObjectType.Overlay, true); string File = Path.CombineFile(Train.TrainFolder, "panel.xml"); if (!System.IO.File.Exists(File)) { //Try animated variant too File = Path.CombineFile(Train.TrainFolder, "panel.animated.xml"); } if (System.IO.File.Exists(File)) { FileSystem.AppendToLogFile("Loading train panel: " + File); try { /* * First load the XML. We use this to determine * whether this is a 2D or a 3D animated panel */ XDocument CurrentXML = XDocument.Load(File, LoadOptions.SetLineInfo); // Check for null if (CurrentXML.Root != null) { IEnumerable <XElement> DocumentElements = CurrentXML.Root.Elements("PanelAnimated"); if (DocumentElements.Any()) { PanelAnimatedXmlParser.ParsePanelAnimatedXml(System.IO.Path.GetFileName(File), Train, Train.DriverCar); if (Train.Cars[Train.DriverCar].CameraRestrictionMode != CameraRestrictionMode.Restricted3D) { Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.NotAvailable; } return; } DocumentElements = CurrentXML.Root.Elements("Panel"); if (DocumentElements.Any()) { PanelXmlParser.ParsePanelXml(System.IO.Path.GetFileName(File), Train, Train.DriverCar); Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On; Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On; return; } } } catch { var currentError = Translations.GetInterfaceString("errors_critical_file"); currentError = currentError.Replace("[file]", "panel.xml"); currentHost.ReportProblem(ProblemType.InvalidData, currentError); Cancel = true; return; } currentHost.AddMessage(MessageType.Error, false, "The panel.xml file " + File + " failed to load. Falling back to legacy panel."); } else { File = Path.CombineFile(Train.TrainFolder, "panel.animated"); if (System.IO.File.Exists(File)) { FileSystem.AppendToLogFile("Loading train panel: " + File); if (System.IO.File.Exists(Path.CombineFile(Train.TrainFolder, "panel2.cfg")) || System.IO.File.Exists(Path.CombineFile(Train.TrainFolder, "panel.cfg"))) { FileSystem.AppendToLogFile("INFO: This train contains both a 2D and a 3D panel. The 3D panel will always take precedence"); } UnifiedObject currentObject; currentHost.LoadObject(File, Encoding, out currentObject); var a = currentObject as AnimatedObjectCollection; if (a != null) { //HACK: If a == null , loading our animated object completely failed (Missing objects?). Fallback to trying the panel2.cfg try { for (int i = 0; i < a.Objects.Length; i++) { currentHost.CreateDynamicObject(ref a.Objects[i].internalObject); } Train.Cars[Train.DriverCar].CarSections[0].Groups[0].Elements = a.Objects; if (Train.Cars[Train.DriverCar].CameraRestrictionMode != CameraRestrictionMode.Restricted3D) { Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.NotAvailable; Renderer.Camera.CurrentRestriction = CameraRestrictionMode.NotAvailable; } return; } catch { var currentError = Translations.GetInterfaceString("errors_critical_file"); currentError = currentError.Replace("[file]", "panel.animated"); currentHost.ReportProblem(ProblemType.InvalidData, currentError); Cancel = true; return; } } currentHost.AddMessage(MessageType.Error, false, "The panel.animated file " + File + " failed to load. Falling back to 2D panel."); } } var Panel2 = false; try { File = Path.CombineFile(Train.TrainFolder, "panel2.cfg"); if (System.IO.File.Exists(File)) { FileSystem.AppendToLogFile("Loading train panel: " + File); Panel2 = true; Panel2CfgParser.ParsePanel2Config("panel2.cfg", Train.TrainFolder, Train.Cars[Train.DriverCar]); Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On; Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On; } else { File = Path.CombineFile(Train.TrainFolder, "panel.cfg"); if (System.IO.File.Exists(File)) { FileSystem.AppendToLogFile("Loading train panel: " + File); PanelCfgParser.ParsePanelConfig(Train.TrainFolder, Encoding, Train.Cars[Train.DriverCar]); Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On; Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On; } else { Renderer.Camera.CurrentRestriction = CameraRestrictionMode.NotAvailable; } } } catch { var currentError = Translations.GetInterfaceString("errors_critical_file"); currentError = currentError.Replace("[file]", Panel2 ? "panel2.cfg" : "panel.cfg"); currentHost.ReportProblem(ProblemType.InvalidData, currentError); Cancel = true; } }
/// <summary>Creates the animated object within the game world</summary> /// <param name="Position">The absolute position</param> /// <param name="BaseTransformation">The base transformation (Rail 0)</param> /// <param name="AuxTransformation">The auxilary transformation (Placed rail)</param> /// <param name="SectionIndex">The index of the section if placed using a SigF command</param> /// <param name="TrackPosition">The absolute track position</param> /// <param name="Brightness">The brightness value at the track position</param> public void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = currentHost.AnimatedWorldObjectsUsed; Transformation FinalTransformation = new Transformation(AuxTransformation, BaseTransformation); //Place track followers if required if (TrackFollowerFunction != null) { var o = this.Clone(); currentHost.CreateDynamicObject(ref o.internalObject); TrackFollowingObject currentObject = new TrackFollowingObject(currentHost) { Position = Position, Direction = FinalTransformation.Z, Up = FinalTransformation.Y, Side = FinalTransformation.X, Object = o, SectionIndex = SectionIndex, TrackPosition = TrackPosition, }; currentObject.FrontAxleFollower.TrackPosition = TrackPosition + FrontAxlePosition; currentObject.RearAxleFollower.TrackPosition = TrackPosition + RearAxlePosition; currentObject.FrontAxlePosition = FrontAxlePosition; currentObject.RearAxlePosition = RearAxlePosition; currentObject.FrontAxleFollower.UpdateWorldCoordinates(false); currentObject.RearAxleFollower.UpdateWorldCoordinates(false); for (int i = 0; i < currentObject.Object.States.Length; i++) { if (currentObject.Object.States[i].Prototype == null) { currentObject.Object.States[i].Prototype = new StaticObject(currentHost); } } currentObject.Object.internalObject.Brightness = Brightness; double r = 0.0; for (int i = 0; i < currentObject.Object.States.Length; i++) { for (int j = 0; j < currentObject.Object.States[i].Prototype.Mesh.Vertices.Length; j++) { double t = States[i].Prototype.Mesh.Vertices[j].Coordinates.Norm(); if (t > r) { r = t; } } } currentObject.Radius = System.Math.Sqrt(r); currentObject.Visible = false; currentObject.Object.Initialize(0, ObjectType.Dynamic, false); currentHost.AnimatedWorldObjects[a] = currentObject; } else { var o = this.Clone(); currentHost.CreateDynamicObject(ref o.internalObject); AnimatedWorldObject currentObject = new AnimatedWorldObject(currentHost) { Position = Position, Direction = FinalTransformation.Z, Up = FinalTransformation.Y, Side = FinalTransformation.X, Object = o, SectionIndex = SectionIndex, TrackPosition = TrackPosition, }; for (int i = 0; i < currentObject.Object.States.Length; i++) { if (currentObject.Object.States[i].Prototype == null) { currentObject.Object.States[i].Prototype = new StaticObject(currentHost); } } currentObject.Object.internalObject.Brightness = Brightness; double r = 0.0; for (int i = 0; i < currentObject.Object.States.Length; i++) { for (int j = 0; j < currentObject.Object.States[i].Prototype.Mesh.Vertices.Length; j++) { double t = States[i].Prototype.Mesh.Vertices[j].Coordinates.Norm(); if (t > r) { r = t; } } } currentObject.Radius = System.Math.Sqrt(r); currentObject.Visible = false; currentObject.Object.Initialize(0, ObjectType.Dynamic, false); currentHost.AnimatedWorldObjects[a] = currentObject; } currentHost.AnimatedWorldObjectsUsed++; }