//a function to find the elevation of a section ,by searching the TDB database public static TrVectorSection FindSectionValue(TrackShape shape, Simulator simulator, TrackSection section, int TileX, int TileZ, uint UID) { if (section.SectionCurve == null) { return(null); } sv = ev = mv = 0f; dir = 1f; var key = (int)(Math.Abs(TileX) + Math.Abs(TileZ)); if (!simulator.SuperElevation.Sections.ContainsKey(key)) { return(null); //we do not have the maps of sections on the given tile, will not bother to search } var tileSections = simulator.SuperElevation.Sections[key]; foreach (var s in tileSections) { if (s.WFNameX == TileX && s.WFNameZ == TileZ && s.WorldFileUiD == UID && section.SectionIndex == s.SectionIndex) { return(s); } } //not found, will do again to find reversed foreach (var s in tileSections) { var sec = simulator.TSectionDat.TrackSections.Get(s.SectionIndex); if (s.WFNameX == TileX && s.WFNameZ == TileZ && s.WorldFileUiD == UID && section.SectionCurve.Radius == sec.SectionCurve.Radius && section.SectionCurve.Angle == -sec.SectionCurve.Angle) { return(s); } } return(null); }
private void WriteDrawingStyleTrackShape(XmlTextWriter w, string key) { TrackShape value = StyleElementTrackShape.Options[random.Next(StyleElementTrackShape.Options.Length)]; StyleElementTrackShape style = new StyleElementTrackShape(value); w.WriteStartElement("TrackShape"); w.WriteAttributeString("Key", key); style.WriteXml(w); w.WriteEndElement(); }
/// <summary> /// Add information about the closest vector section /// </summary> /// <param name="trackViewer"></param> private void AddVectorSectionStatus(TrackViewer trackViewer) { if (Properties.Settings.Default.statusShowVectorSections) { TrVectorSection tvs = trackViewer.DrawTrackDB.ClosestTrack.VectorSection; if (tvs == null) { return; } uint shapeIndex = tvs.ShapeIndex; string shapeName = "Unknown:" + shapeIndex.ToString(System.Globalization.CultureInfo.CurrentCulture); try { // Try to find a fixed track TrackShape shape = trackViewer.RouteData.TsectionDat.TrackShapes.Get(shapeIndex); shapeName = shape.FileName; } catch { // try to find a dynamic track try { TrackPath trackPath = trackViewer.RouteData.TsectionDat.TSectionIdx.TrackPaths[tvs.ShapeIndex]; shapeName = "<dynamic ?>"; foreach (uint trackSection in trackPath.TrackSections) { if (trackSection == tvs.SectionIndex) { shapeName = "<dynamic>"; } // For some reason I do not undestand the (route) section.tdb. trackpaths are not consistent tracksections // so this foreach loop will not always find a combination } } catch { } } statusAdditional.Text += string.Format(System.Globalization.CultureInfo.CurrentCulture, " VectorSection ({3}/{4}) filename={2} Index={0} shapeIndex={1}", tvs.SectionIndex, shapeIndex, shapeName, trackViewer.DrawTrackDB.ClosestTrack.TrackVectorSectionIndex + 1, trackViewer.DrawTrackDB.ClosestTrack.TrackNode.TrVectorNode.TrVectorSections.Count()); } }
/// <summary> /// Find the indices we need to use for TrPins in the various junction nodes in case we want to use either main /// or siding path. That information is available in the trackshapes in the tsectionDat. /// </summary> /// <param name="trackNodesIn">The tracknodes</param> /// <param name="tsectionDatIn">Track section Data</param> public static void Initialize(TrackNode[] trackNodesIn, TrackSectionsFile tsectionDatIn) { trackNodes = trackNodesIn; tsectionDat = tsectionDatIn; mainRouteIndex = new uint[trackNodes.Length]; sidingRouteIndex = new uint[trackNodes.Length]; for (int tni = 0; tni < trackNodes.Length; tni++) { TrackNode tn = trackNodes[tni]; if (tn == null) { continue; } if (tn.TrJunctionNode == null) { continue; } uint mainRoute = 0; uint trackShapeIndex = tn.TrJunctionNode.ShapeIndex; try { TrackShape trackShape = tsectionDat.TrackShapes.Get(trackShapeIndex); mainRoute = trackShape.MainRoute; } catch (System.IO.InvalidDataException exception) { exception.ToString(); } mainRouteIndex[tni] = tn.Inpins + mainRoute; if (mainRoute == 0) { // sidingRouteIndex is simply the next sidingRouteIndex[tni] = tn.Inpins + 1; } else { // sidingRouteIndex is the first sidingRouteIndex[tni] = tn.Inpins; } } }
protected void InitializeOffsetsAndTrackNodes() { TrackShape trackShape = Simulator.Instance.TSectionDat.TrackShapes[(uint)TrackShapeIndex]; uint nSections = trackShape.SectionIndices[0].SectionsCount; trackNodesIndex = new int[trackShape.SectionIndices.Length]; trackNodesOrientation = new bool[trackNodesIndex.Length]; trackVectorSectionsIndex = new int[trackNodesIndex.Length]; int i = 0; foreach (SectionIndex sectionIdx in trackShape.SectionIndices) { offsets.Add(verticalTransfer ? sectionIdx.Offset.Y : sectionIdx.Offset.X); trackNodesIndex[i] = -1; trackVectorSectionsIndex[i] = -1; i++; } TrackNode[] trackNodes = Simulator.Instance.TrackDatabase.TrackDB.TrackNodes; for (int j = 1; j < trackNodes.Length; j++) { if (trackNodes[j] is TrackVectorNode tvn && tvn.TrackVectorSections != null) { int trackVectorSection = Array.FindIndex(tvn.TrackVectorSections, trVectorSection => (trVectorSection.Location.TileX == WorldPosition.TileX && trVectorSection.Location.TileZ == WorldPosition.TileZ && trVectorSection.WorldFileUiD == UID)); if (trackVectorSection >= 0) { if (tvn.TrackVectorSections.Length > (int)nSections) { i = tvn.TrackVectorSections[trackVectorSection].Flag1 / 2; trackNodesIndex[i] = j; trackVectorSectionsIndex[i] = trackVectorSection; trackNodesOrientation[i] = tvn.TrackVectorSections[trackVectorSection].Flag1 % 2 == 0; } } } } if (verticalTransfer) { OffsetPos = CenterOffset.Y; Span = trackShape.SectionIndices[^ 1].Offset.Y - trackShape.SectionIndices[0].Offset.Y;
private void InitializeAnglesAndTrackNodes() { TrackShape trackShape = Simulator.Instance.TSectionDat.TrackShapes[(uint)TrackShapeIndex]; uint nSections = Simulator.Instance.TSectionDat.TrackShapes[(uint)TrackShapeIndex].SectionIndices[0].SectionsCount; trackNodesIndex = new int[Simulator.Instance.TSectionDat.TrackShapes[(uint)TrackShapeIndex].SectionIndices.Length]; trackNodesOrientation = new bool[trackNodesIndex.Length]; trackVectorSectionsIndex = new int[trackNodesIndex.Length]; int i = 0; foreach (SectionIndex sectionIdx in trackShape.SectionIndices) { angles.Add(MathHelper.ToRadians((float)sectionIdx.AngularOffset)); trackNodesIndex[i] = -1; trackVectorSectionsIndex[i] = -1; i++; } TrackNode[] trackNodes = Simulator.Instance.TrackDatabase.TrackDB.TrackNodes; for (int j = 1; j < trackNodes.Length; j++) { if (trackNodes[j] is TrackVectorNode tvn && tvn.TrackVectorSections != null) { int trackVectorSection = Array.FindIndex(tvn.TrackVectorSections, trVectorSection => trVectorSection.Location.TileX == WorldPosition.TileX && trVectorSection.Location.TileZ == WorldPosition.TileZ && trVectorSection.WorldFileUiD == UID); if (trackVectorSection >= 0) { if (tvn.TrackVectorSections.Length > (int)nSections) { i = tvn.TrackVectorSections[trackVectorSection].Flag1 / 2; trackNodesIndex[i] = j; trackVectorSectionsIndex[i] = trackVectorSection; trackNodesOrientation[i] = tvn.TrackVectorSections[trackVectorSection].Flag1 % 2 == 0; } } } } }
/// <summary> /// Decompose and add a SuperElevation on top of MSTS track section /// </summary> /// <param name="viewer">Viewer reference.</param> /// <param name="trackList">DynamicTrackViewer list.</param> /// <param name="trackObj">Dynamic track section to decompose.</param> /// <param name="worldMatrixInput">Position matrix.</param> /// <param name="TileX">TileX coordinates.</param> /// <param name="TileZ">TileZ coordinates.</param> /// <param name="shapeFilePath">Path to the shape file.</param> public static bool DecomposeStaticSuperElevation(Viewer viewer, List <DynamicTrackViewer> trackList, TrackObj trackObj, WorldPosition worldMatrixInput, int TileX, int TileZ, string shapeFilePath) { TrackShape shape = null; try { shape = viewer.Simulator.TSectionDat.TrackShapes.Get(trackObj.SectionIdx); if (shape.RoadShape == true) { return(false); } } catch (Exception) { return(false); } SectionIdx[] SectionIdxs = shape.SectionIdxs; int count = -1; int drawn = 0; bool isTunnel = shape.TunnelShape; List <TrVectorSection> sectionsinShape = new List <TrVectorSection>(); //List<DynamicTrackViewer> tmpTrackList = new List<DynamicTrackViewer>(); foreach (SectionIdx id in SectionIdxs) { uint[] sections = id.TrackSections; for (int i = 0; i < sections.Length; i++) { count++; uint sid = id.TrackSections[i]; TrackSection section = viewer.Simulator.TSectionDat.TrackSections.Get(sid); if (Math.Abs(section.SectionSize.Width - viewer.Simulator.SuperElevationGauge) > 0.2) { continue; //the main route has a gauge different than mine } if (section.SectionCurve == null) { continue; //with strait track, will remove all related sections later } TrVectorSection tmp = null; if (section.SectionCurve != null) { tmp = FindSectionValue(shape, viewer.Simulator, section, TileX, TileZ, trackObj.UID); } if (tmp == null) //cannot find the track for super elevation, will return 0; { continue; } sectionsinShape.Add(tmp); drawn++; } } if (drawn <= count || isTunnel)//tunnel or not every section is in SE, will remove all sections in the shape out { if (sectionsinShape.Count > 0) { RemoveTracks(viewer.Simulator, sectionsinShape); } return(false); } return(true); }
public List <int> SignalsPassingRoutes; // list of signals reading passed junction // //================================================================================================// // // Constructor // public TrackCircuitSection(TrackNode thisNode, int orgINode, TSectionDatFile tsectiondat, Signals thisSignals) { // // Copy general info // signalRef = thisSignals; Index = orgINode; OriginalIndex = orgINode; if (thisNode.TrEndNode) { CircuitType = TrackCircuitType.EndOfTrack; } else if (thisNode.TrJunctionNode != null) { CircuitType = TrackCircuitType.Junction; } else { CircuitType = TrackCircuitType.Normal; } // // Preset pins, then copy pin info // for (int direction = 0; direction < 2; direction++) { for (int pin = 0; pin < 2; pin++) { Pins[direction, pin] = new TrPin(); Pins[direction, pin].Direction = -1; Pins[direction, pin].Link = -1; ActivePins[direction, pin] = new TrPin(); ActivePins[direction, pin].Direction = -1; ActivePins[direction, pin].Link = -1; } } int PinNo = 0; for (int pin = 0; pin < Math.Min(thisNode.Inpins, Pins.GetLength(1)); pin++) { Pins[0, pin] = thisNode.TrPins[PinNo].Copy(); PinNo++; } if (PinNo < thisNode.Inpins) { PinNo = (int)thisNode.Inpins; } for (int pin = 0; pin < Math.Min(thisNode.Outpins, Pins.GetLength(1)); pin++) { Pins[1, pin] = thisNode.TrPins[PinNo].Copy(); PinNo++; } // // preset no end signals // preset no trailing junction // for (int direction = 0; direction < 2; direction++) { EndSignals[direction] = null; EndIsTrailingJunction[direction] = false; } // // Preset length and offset // If section index not in tsectiondat, set length to 0. // float totalLength = 0.0f; if (thisNode.TrVectorNode != null && thisNode.TrVectorNode.TrVectorSections != null) { foreach (TrVectorSection thisSection in thisNode.TrVectorNode.TrVectorSections) { float thisLength = 0.0f; if (tsectiondat.TrackSections.ContainsKey(thisSection.SectionIndex)) { TrackSection TS = tsectiondat.TrackSections[thisSection.SectionIndex]; if (TS.SectionCurve != null) { thisLength = MathHelper.ToRadians(Math.Abs(TS.SectionCurve.Angle)) * TS.SectionCurve.Radius; } else { thisLength = TS.SectionSize.Length; } } totalLength += thisLength; } } Length = totalLength; for (int direction = 0; direction < 2; direction++) { OffsetLength[direction] = 0; } // // set signal list for junctions // if (CircuitType == TrackCircuitType.Junction) { SignalsPassingRoutes = new List <int>(); } else { SignalsPassingRoutes = null; } // for Junction nodes, obtain default route // set switch to default route // copy overlap (if set) if (CircuitType == TrackCircuitType.Junction) { uint trackShapeIndex = thisNode.TrJunctionNode.ShapeIndex; try { TrackShape trackShape = tsectiondat.TrackShapes[trackShapeIndex]; JunctionDefaultRoute = (int)trackShape.MainRoute; Overlap = trackShape.ClearanceDistance; } catch (Exception) { JunctionDefaultRoute = 0; Overlap = 0; } JunctionLastRoute = JunctionDefaultRoute; //signalRef.setSwitch(OriginalIndex, JunctionLastRoute, this); } // // Create circuit items // CircuitItems = new TrackCircuitItems(); CircuitState = new TrackCircuitState(); }
public MapCell(TrackShape shape, Cart cart) { Track = shape; Cart = cart; }