コード例 #1
0
        /// <summary>
        /// Check wether this vector node is closest to the mouse location
        /// </summary>
        /// <param name="location">Location to check</param>
        /// <param name="mouseLocation">Current mouse location</param>
        /// <param name="trackNode">The trackNode that will be stored when indeed it is the closest to the mouse location</param>
        /// <param name="vectorSection">the vectorSection that will be stored when indeed it is closest to the mouse location</param>
        /// <param name="tvsi">Current index of the trackvectorsection</param>
        /// <param name="pixelsPerMeter"></param>
        public void CheckMouseDistance(WorldLocation location, WorldLocation mouseLocation,
                                       TrackNode trackNode, TrVectorSection vectorSection, int tvsi, double pixelsPerMeter)
        {
            storedMouseLocation = mouseLocation;
            float distanceSquared = WorldLocation.GetDistanceSquared2D(location, mouseLocation);
            // to make unique distances becasue they also act as Key
            double distanceSquaredIndexed = ((double)distanceSquared) * (1 + 1e-16 * trackNode.Index);

            if (distanceSquaredIndexed < sortedTrackCandidates.First().Key)
            {
                if (!sortedTrackCandidates.ContainsKey(distanceSquaredIndexed))
                {
                    sortedTrackCandidates.Add(distanceSquaredIndexed, new TrackCandidate(trackNode, vectorSection, tvsi, 0));

                    // The next one is a bit tricky. The problem is that the first culling is done based on the trackvector section location
                    // Which is only at one side of the section. So the other end might be quiet far away.
                    // Unfortunately, this means that we need to keep track of many candidates to make sure we can calculate the closest one
                    // Which is costing performance.
                    // The biggest issue is for a long track close to a region with lots junctions and hence small track segments
                    // By making this number zoom dependent, we get good results for big zooms, and not a large
                    // performance penalty for wide views
                    int maxNumberOfCandidates = 50 + (int)(100 * pixelsPerMeter);
                    while (sortedTrackCandidates.Count > maxNumberOfCandidates)
                    {
                        sortedTrackCandidates.RemoveAt(0); // First one has largest distance
                    }
                }
            }
        }
コード例 #2
0
 public TrackCandidate(TrackNode node, TrVectorSection section, int tvsi, float lon)
 {
     trackNode               = node;
     vectorSection           = section;
     trackVectorSectionIndex = tvsi;
     distanceAlongSection    = lon;
 }
コード例 #3
0
ファイル: TrackNodeAE.cs プロジェクト: xiaomailong/OpenRails
        public static uint getShapeIdx(this TrackNode node, int direction)
        {
            uint shapeIdx = 0;

            if (node.TrEndNode || node.TrJunctionNode != null)
            {
                shapeIdx = 0;
            }
            else if (node.TrVectorNode.TrVectorSections.Length > 1)
            {
                if (direction == 0)
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.Last();
                    shapeIdx = section.ShapeIndex;
                }
                else
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.First();
                    shapeIdx = section.ShapeIndex;
                }
            }
            else
            {
                shapeIdx = 0;
            }
            return(shapeIdx);
        }
コード例 #4
0
ファイル: TrackNodeAE.cs プロジェクト: xiaomailong/OpenRails
        public static uint getSectionIndex(this TrackNode node, int direction)
        {
            uint index = 0;

            if (node.TrEndNode)
            {
                index = (uint)node.UiD.WorldId;
            }
            else if (node.TrJunctionNode != null)
            {
                index = (uint)node.TrJunctionNode.Idx;
            }
            else if (node.TrVectorNode.TrVectorSections != null && node.TrVectorNode.TrVectorSections.Length > 1)
            {
                if (direction == 0)
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.Last();
                    index = section.SectionIndex;
                }
                else
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.First();
                    index = section.SectionIndex;
                }
            }
            else if (node.TrVectorNode.TrVectorSections != null)
            {
                index = node.TrVectorNode.TrVectorSections[0].SectionIndex;
            }
            else
            {
                index = (uint)node.UiD.WorldId;
            }
            return(index);
        }
コード例 #5
0
ファイル: MSTSCoord.cs プロジェクト: pzgulyas/openrails-1
 public MSTSCoord(TrVectorSection section)
 {
     TileX   = section.TileX;
     TileY   = section.TileZ;
     X       = section.X;
     Y       = section.Z;
     Reduced = section.Reduced;
 }
コード例 #6
0
ファイル: AESegment.cs プロジェクト: pzgulyas/openrails-1
        public AESegment(TrVectorSection item1, TrVectorSection item2)
        {
            MSTSCoord A = new MSTSCoord(item1);
            MSTSCoord B = new MSTSCoord(item2);

            startPoint = A.ConvertToPointF();
            endPoint   = B.ConvertToPointF();
        }
コード例 #7
0
ファイル: SuperElevation.cs プロジェクト: robwor/openrails
        //remove a section from the tile-section map
        public static void RemoveSectionsFromMap(Simulator simulator, TrVectorSection section)
        {
            var key = (int)(Math.Abs(section.WFNameX) + Math.Abs(section.WFNameZ));

            if (simulator.SuperElevation.Sections.ContainsKey(key))
            {
                simulator.SuperElevation.Sections[key].Remove(section);
            }
        }
コード例 #8
0
ファイル: CloseToMouse.cs プロジェクト: yinwuu/openrails
        /// <summary>
        /// Calculate the closest distance to a track, as well as the 'longitude' along it.
        /// </summary>
        /// <param name="trackVectorSection">The vectorsection for which we want to know the distance</param>
        /// <param name="trackSection">The corresponding tracksection</param>
        /// <returns>Distance Squared to the track as well as length along track.</returns>
        /// <remarks>Partly the same code as in Traveller.cs, but here no culling, and we just want the distance.
        /// The math here is not perfect (it is quite difficult to calculate the distances to a curved line
        /// for all possibilities) but good enough. The math was designed (in Traveller.cs) to work well for close distances.
        /// Math is modified to prevent NaN and to combine straight and curved tracks.</remarks>
        DistanceLon CalcRealDistanceSquared(TrVectorSection trackVectorSection, TrackSection trackSection)
        {
            //Calculate the vector from start of track to the mouse
            Vector3 vectorToMouse = new Vector3
            {
                X = storedMouseLocation.Location.X - trackVectorSection.X,
                Z = storedMouseLocation.Location.Z - trackVectorSection.Z
            };

            vectorToMouse.X += (storedMouseLocation.TileX - trackVectorSection.TileX) * 2048;
            vectorToMouse.Z += (storedMouseLocation.TileZ - trackVectorSection.TileZ) * 2048;

            //Now rotate the vector such that a direction along the track is in a direction (x=0, z=1)
            vectorToMouse = Vector3.Transform(vectorToMouse, Matrix.CreateRotationY(-trackVectorSection.AY));

            float lon, lat;

            if (trackSection.SectionCurve == null)
            {
                //Track is straight. In this coordinate system, the distance along track (lon) and orthogonal to track (lat) are easy.
                lon = vectorToMouse.Z;
                lat = vectorToMouse.X;
            }
            else
            {
                // make sure the vector is as if the vector section turns to the left.
                // The center of the curved track is now a (x=-radius, z=0), track starting at (0,0), pointing in positive Z
                if (trackSection.SectionCurve.Angle > 0)
                {
                    vectorToMouse.X *= -1;
                }

                //make vector relative to center of curve. Track now starts at (radius,0)
                vectorToMouse.X += trackSection.SectionCurve.Radius;

                float radiansAlongCurve = (float)Math.Atan2(vectorToMouse.Z, vectorToMouse.X);

                //The following calculations make sense when close to the track. Otherwise they are not necessarily sensible, but at least well-defined.
                // Distance from mouse to circle through track section.
                lat = (float)Math.Sqrt(vectorToMouse.X * vectorToMouse.X + vectorToMouse.Z * vectorToMouse.Z) - trackSection.SectionCurve.Radius;
                lon = radiansAlongCurve * trackSection.SectionCurve.Radius;
            }


            float trackSectionLength = DrawTrackDB.GetLength(trackSection);

            if (lon < 0)
            {   // distance from start of track
                return(new DistanceLon(lat * lat + lon * lon, 0));
            }
            if (lon > trackSectionLength)
            {                                                                                                                     // distance from end of track
                return(new DistanceLon(lat * lat + (lon - trackSectionLength) * (lon - trackSectionLength), trackSectionLength)); //idem
            }
            // somewhere along track. Distance is only in lateral direction
            return(new DistanceLon(lat * lat, lon));
        }
コード例 #9
0
        bool InitTrackSectionCurved(int tileX, int tileZ, float x, float z, TrVectorSection trackVectorSection, float treeWidth)
        {
            // We're working relative to the track section, so offset as needed.
            x += (tileX - trackVectorSection.TileX) * 2048;
            z += (tileZ - trackVectorSection.TileZ) * 2048;
            var sx = trackVectorSection.X;
            var sz = trackVectorSection.Z;

            // Do a preliminary cull based on a bounding square around the track section.
            // Bounding distance is (radius * angle + error) by (radius * angle + error) around starting coordinates but no more than 2 for angle.
            var boundingDistance = trackSection.SectionCurve.Radius * Math.Min(Math.Abs(MathHelper.ToRadians(trackSection.SectionCurve.Angle)), 2) + MaximumCenterlineOffset + treeWidth;
            var dx = Math.Abs(x - sx);
            var dz = Math.Abs(z - sz);

            if (dx > boundingDistance || dz > boundingDistance)
            {
                return(false);
            }

            // To simplify the math, center around the start of the track section, rotate such that the track section starts out pointing north (+z) and flip so the track curves to the right.
            x -= sx;
            z -= sz;
            MstsUtility.Rotate2D(trackVectorSection.AY, ref x, ref z);
            if (trackSection.SectionCurve.Angle < 0)
            {
                x *= -1;
            }

            // Compute distance to curve's center at (radius,0) then adjust to get distance from centerline.
            dx = x - trackSection.SectionCurve.Radius;
            var lat = Math.Sqrt(dx * dx + z * z) - trackSection.SectionCurve.Radius;

            if (Math.Abs(lat) > MaximumCenterlineOffset + treeWidth)
            {
                return(false);
            }

            // Compute distance along curve (ensure we are in the top right quadrant, otherwise our math goes wrong).
            if (z < -InitErrorMargin || x > trackSection.SectionCurve.Radius + InitErrorMargin || z > trackSection.SectionCurve.Radius + InitErrorMargin)
            {
                return(false);
            }
            var radiansAlongCurve = (float)Math.Asin(z / trackSection.SectionCurve.Radius);
            var lon = radiansAlongCurve * trackSection.SectionCurve.Radius;
            var trackSectionLength = GetLength(trackSection);

            if (lon < -InitErrorMargin || lon > trackSectionLength + InitErrorMargin)
            {
                return(false);
            }

            return(true);
        }
コード例 #10
0
 bool InitTrackSection(TrVectorSection section, Vector3 xnaTreePosition, int tileX, int tileZ, float treeWidth)
 {
     trackSection = Viewer.Simulator.TSectionDat.TrackSections.Get(section.SectionIndex);
     if (trackSection == null)
     {
         return(false);
     }
     if (trackSection.SectionCurve != null)
     {
         return(InitTrackSectionCurved(tileX, tileZ, xnaTreePosition.X, -xnaTreePosition.Z, section, treeWidth));
     }
     return(InitTrackSectionStraight(tileX, tileZ, xnaTreePosition.X, -xnaTreePosition.Z, section, treeWidth));
 }
コード例 #11
0
ファイル: TrainpathNode.cs プロジェクト: yinwuu/openrails
        /// <summary>
        /// Find the exact distance of the start of the current tracksection (from the beginning of the vector node)
        /// </summary>
        /// <returns></returns>
        private float GetSectionStartDistance()
        {
            float     distanceFromStart = 0;
            TrackNode tn = TrackDB.TrackNodes[TvnIndex];

            for (int tvsi = 0; tvsi < TrackVectorSectionIndex; tvsi++)
            {
                TrVectorSection tvs          = tn.TrVectorNode.TrVectorSections[tvsi];
                TrackSection    trackSection = TsectionDat.TrackSections.Get(tvs.SectionIndex);
                if (trackSection != null)  // if trackSection is missing somehow, well, do without.
                {
                    distanceFromStart += ORTS.TrackViewer.Drawing.DrawTrackDB.GetLength(trackSection);
                }
            }
            return(distanceFromStart);
        }
コード例 #12
0
 /// <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());
     }
 }
コード例 #13
0
ファイル: TrackNodeAE.cs プロジェクト: xiaomailong/OpenRails
        public static int searchIdx(this TrackNode node, TrVectorSection currentSection)
        {
            TrVectorNode nodes = node.TrVectorNode;

            if (nodes == null || nodes.TrVectorSections == null)
            {
                return(0);
            }
            for (int cnt = 0; cnt < nodes.TrVectorSections.Count(); cnt++)
            {
                if (nodes.TrVectorSections[cnt].SectionIndex == currentSection.SectionIndex &&
                    nodes.TrVectorSections[cnt].WorldFileUiD == currentSection.WorldFileUiD)
                {
                    return(cnt);
                }
            }
            return(0);
        }
コード例 #14
0
        /// <summary>
        /// Determine the length of the section along the track.
        /// </summary>
        /// <param name="tn">The current tracknode, which needs to be a vector node</param>
        /// <param name="tvsi">The track vector section index</param>
        private float SectionLengthAlongTrack(TrackNode tn, int tvsi)
        {
            float           fullSectionLength;
            TrVectorSection tvs          = tn.TrVectorNode.TrVectorSections[tvsi];
            TrackSection    trackSection = tsectionDat.TrackSections.Get(tvs.SectionIndex);

            if (trackSection == null)
            {
                return(100);  // need to return something. Not easy to recover
            }

            if (trackSection.SectionCurve != null)
            {
                fullSectionLength = trackSection.SectionCurve.Radius * Math.Abs(Microsoft.Xna.Framework.MathHelper.ToRadians(trackSection.SectionCurve.Angle));
            }
            else
            {
                fullSectionLength = trackSection.SectionSize.Length;
            }
            return(fullSectionLength);
        }
コード例 #15
0
ファイル: TrackNodeAE.cs プロジェクト: xiaomailong/OpenRails
        /// <summary>
        /// Permet de récupérer les coordonnées du node au format MSTSCoord propre à l'éditeur d'activité
        /// Return the MSTSCoord for the current node as needed by Activity Editor
        ///     For vectorNode with multiple section, the direction is used to give the first encountered section
        /// </summary>
        public static MSTSCoord getMSTSCoord(this TrackNode node, int direction)
        {
            MSTSCoord coord = new MSTSCoord();

            if (node.TrEndNode || node.TrJunctionNode != null || node.TrVectorNode.TrVectorSections == null)
            {
                coord.TileX = node.UiD.TileX;
                coord.TileY = node.UiD.TileZ;
                coord.X     = node.UiD.X;
                coord.Y     = node.UiD.Z;
            }
            else if (node.TrVectorNode != null && node.TrVectorNode.TrVectorSections.Length > 1)
            {
                if (direction == 0)
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.Last();
                    coord.TileX = section.TileX;
                    coord.TileY = section.TileZ;
                    coord.X     = section.X;
                    coord.Y     = section.Z;
                }
                else
                {
                    TrVectorSection section = node.TrVectorNode.TrVectorSections.First();
                    coord.TileX = section.TileX;
                    coord.TileY = section.TileZ;
                    coord.X     = section.X;
                    coord.Y     = section.Z;
                }
            }
            else if (node.TrVectorNode != null)
            {
                coord.TileX = node.TrVectorNode.TrVectorSections[0].TileX;
                coord.TileY = node.TrVectorNode.TrVectorSections[0].TileZ;
                coord.X     = node.TrVectorNode.TrVectorSections[0].X;
                coord.Y     = node.TrVectorNode.TrVectorSections[0].Z;
            }
            return(coord);
        }
コード例 #16
0
        /// <summary>
        /// Get the curvature for the current section index in a vector track node.
        /// </summary>
        /// <param name="vectorNode">The vector track node</param>
        /// <param name="tvsi">The tracknode vector section index in the given verctor track node</param>
        /// <param name="isForward">Is the path in the same direction as the vector track node?</param>
        private float GetCurvature(TrVectorNode vectorNode, int tvsi, bool isForward)
        {
            TrVectorSection tvs          = vectorNode.TrVectorSections[tvsi];
            TrackSection    trackSection = tsectionDat.TrackSections.Get(tvs.SectionIndex);

            float curvature = 0;

            if (trackSection != null) // if it is null, something is wrong but we do not want to crash
            {
                SectionCurve thisCurve = trackSection.SectionCurve;

                if (thisCurve != null)
                {
                    curvature = Math.Sign(thisCurve.Angle) / thisCurve.Radius;
                    if (!isForward)
                    {
                        curvature *= -1;
                    }
                }
            }

            return(curvature);
        }
コード例 #17
0
ファイル: TrackNodeAE.cs プロジェクト: xiaomailong/OpenRails
        public static TrVectorSection getVectorSection(this TrackNode node)
        {
            TrVectorSection section = null;

            if (node.TrEndNode)
            {
                //section = TrVectorNode.TrVectorSections[0];
            }
            else if (node.TrJunctionNode != null)
            {
            }
            else if (node.TrVectorNode.TrVectorSections == null)
            {
            }
            else if (node.TrVectorNode.TrVectorSections.Length > 1)
            {
            }
            else
            {
                section = node.TrVectorNode.TrVectorSections[0];
            }
            return(section);
        }
コード例 #18
0
        bool InitTrackSectionStraight(int tileX, int tileZ, float x, float z, TrVectorSection trackVectorSection, float treeWidth)
        {
            // We're working relative to the track section, so offset as needed.
            x += (tileX - trackVectorSection.TileX) * 2048;
            z += (tileZ - trackVectorSection.TileZ) * 2048;
            var sx = trackVectorSection.X;
            var sz = trackVectorSection.Z;

            // Do a preliminary cull based on a bounding square around the track section.
            // Bounding distance is (length + error) by (length + error) around starting coordinates.
            var boundingDistance = trackSection.SectionSize.Length + MaximumCenterlineOffset + treeWidth;
            var dx = Math.Abs(x - sx);
            var dz = Math.Abs(z - sz);

            if (dx > boundingDistance || dz > boundingDistance)
            {
                return(false);
            }

            // Calculate distance along and away from the track centerline.
            float lat, lon;

            MstsUtility.Survey(sx, sz, trackVectorSection.AY, x, z, out lon, out lat);
            var trackSectionLength = GetLength(trackSection);

            if (Math.Abs(lat) > MaximumCenterlineOffset + treeWidth)
            {
                return(false);
            }
            if (lon < -InitErrorMargin || lon > trackSectionLength + InitErrorMargin)
            {
                return(false);
            }

            return(true);
        }
コード例 #19
0
ファイル: AEStationPath.cs プロジェクト: pzgulyas/openrails-1
        public List <StationPath> explore(AETraveller myTravel, List <TrackSegment> listConnector, MSTSItems aeItems, StationItem parent)
        {
            List <AEJunctionItem> insideJunction = new List <AEJunctionItem>();
            Stopwatch             stopWatch      = new Stopwatch();
            TimeSpan ts;
            string   elapsedTime;

            stopWatch.Start();
            TrackNode       currentNode             = myTravel.GetCurrentNode();
            int             pathChecked             = 0;
            int             trackNodeIndex          = myTravel.TrackNodeIndex;
            int             lastCommonTrack         = trackNodeIndex;
            int             trackVectorSectionIndex = myTravel.TrackVectorSectionIndex;
            TrVectorSection currentSection          = myTravel.GetCurrentSection();
            GlobalItem      startNode = aeItems.GetTrackSegment(currentNode, trackVectorSectionIndex);

            //paths.Add(new StationPath(startNode, myTravel));
            paths.Add(new StationPath(myTravel));
            paths[0].LastCommonTrack = trackNodeIndex;
            while ((pathChecked < paths.Count && !paths[pathChecked].complete) && paths.Count < 100)
            {
                TrackNode node2 = paths[pathChecked].explore(aeItems, listConnector, trackNodeIndex, parent);
                ts = stopWatch.Elapsed;

                // Format and display the TimeSpan value.
                elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                            ts.Hours, ts.Minutes, ts.Seconds,
                                            ts.Milliseconds / 10);
                Console.WriteLine("RunTime " + elapsedTime);

                if (node2.TrJunctionNode != null)
                {
                    AEJunctionItem junction = (AEJunctionItem)paths[pathChecked].ComponentItem[paths[pathChecked].ComponentItem.Count - 1];
                    if (!insideJunction.Contains(junction))
                    {
                        insideJunction.Add(junction);
                    }
                    if (node2.TrPins[0].Link == lastCommonTrack)
                    {
                        paths[pathChecked].jctnIdx         = paths[pathChecked].ComponentItem.Count - 1;
                        paths[pathChecked].LastCommonTrack = lastCommonTrack;
                        paths.Add(new StationPath(paths[pathChecked]));
                        paths[pathChecked].directionJunction = 0;
                        paths[pathChecked].switchJnct(0);
                    }
                    else
                    {
                        paths[pathChecked].NextNode();
                    }
                }
                else if (node2.TrEndNode)
                {
                    AEBufferItem buffer = (AEBufferItem)paths[pathChecked].ComponentItem[paths[pathChecked].ComponentItem.Count - 1];
                    if (!buffer.Configured || buffer.DirBuffer == AllowedDir.OUT)
                    {
                        //AEJunctionItem junction = (AEJunctionItem)paths[pathChecked].ComponentItem[paths[pathChecked].jctnIdx];
                        paths.RemoveAt(pathChecked);
                    }
                    else
                    {
                        paths[pathChecked].setComplete(buffer);
                        pathChecked++;
                    }
                    if (pathChecked < paths.Count)
                    {
                        paths[pathChecked].switchJnct(paths[pathChecked].directionJunction);
                        if (paths[pathChecked].ComponentItem.Count > 1)
                        {
                            lastCommonTrack = (int)paths[pathChecked].LastCommonTrack;
                        }
                        else
                        {
                            lastCommonTrack = trackNodeIndex;
                        }
                    }
                }
                else
                {
                    int lastIndex = (int)node2.Index;
                    //lastCommonTrack = (int)node2.Index;
                    if (paths[pathChecked].complete)
                    {
                        TrackSegment segment = (TrackSegment)paths[pathChecked].ComponentItem[paths[pathChecked].ComponentItem.Count - 1];

                        if (segment.HasConnector == null ||
                            (segment.HasConnector != null &&
                             (segment.HasConnector.dirConnector == AllowedDir.IN || !segment.HasConnector.isConfigured())))
                        {
                            paths.RemoveAt(pathChecked);
                        }
                        else
                        {
                            pathChecked++;
                        }
                        //pathChecked++;
                        if (pathChecked < paths.Count)
                        {
                            lastIndex = (int)paths[pathChecked].ComponentItem[paths[pathChecked].ComponentItem.Count - 2].associateNode.Index;
                            paths[pathChecked].switchJnct(paths[pathChecked].directionJunction);
                        }
                    }
                    if (pathChecked < paths.Count)
                    {
                        if (paths[pathChecked].ComponentItem.Count > 1)
                        {
                            lastCommonTrack = lastIndex;
                            //lastCommonTrack = (int)paths[pathChecked].ComponentItem[paths[pathChecked].ComponentItem.Count - 2].associateNode.Index;
                        }
                        else
                        {
                            lastCommonTrack = trackNodeIndex;
                        }
                    }
                }
            }
            stopWatch.Stop();
            ts = stopWatch.Elapsed;

            // Format and display the TimeSpan value.
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            Console.WriteLine("RunTime " + elapsedTime);

            pathChecked = 1;
            foreach (StationPath path in paths)
            {
                if (path.PassingYard > MaxPassingYard)
                {
                    MaxPassingYard = path.PassingYard;
                }
                if (path.PassingYard < ShortPassingYard)
                {
                    ShortPassingYard = path.PassingYard;
                }
            }
            return(paths);
        }
コード例 #20
0
ファイル: SuperElevation.cs プロジェクト: robwor/openrails
        /// <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);
        }
コード例 #21
0
ファイル: SuperElevation.cs プロジェクト: robwor/openrails
        //no use anymore
        public static int DecomposeStaticSuperElevationOneSection(Viewer viewer, List <DynamicTrackViewer> dTrackList, int TileX, int TileZ, TrVectorSection ts)
        {
            if (ts == null)
            {
                return(0);
            }

            WorldLocation location        = new WorldLocation();
            Vector3       directionVector = new Vector3();

            var tss = viewer.Simulator.TSectionDat.TrackSections.Get(ts.SectionIndex);

            if (tss == null || tss.SectionCurve == null)
            {
                return(0);
            }
            location.TileX      = ts.TileX;
            location.TileZ      = ts.TileZ;
            location.Location.X = ts.X;
            location.Location.Y = ts.Y;
            location.Location.Z = ts.Z;
            directionVector.X   = ts.AX;
            directionVector.Y   = ts.AY;
            directionVector.Z   = ts.AZ;
            Vector3       trackLoc = new Vector3(ts.X, ts.Y, -ts.Z);
            WorldPosition root     = new WorldPosition(); root.TileX = ts.TileX; root.TileZ = ts.TileZ;

            root.XNAMatrix = Matrix.CreateFromYawPitchRoll(-ts.AY, -ts.AX, ts.AZ);// CreateRotationX(-ts.AY) * Matrix.CreateRotationY(-ts.AX) * Matrix.CreateRotationZ(ts.AZ);

            root.XNAMatrix.Translation  = Vector3.Zero;
            root.XNAMatrix.Translation += Vector3.Transform(trackLoc, Matrix.Identity);

            var     sign = -Math.Sign(tss.SectionCurve.Angle); var to = Math.Abs(tss.SectionCurve.Angle * 0.0174f);
            var     vectorCurveStartToCenter = Vector3.Left * tss.SectionCurve.Radius * sign;
            var     curveRotation            = Matrix.CreateRotationY(to * sign);
            Vector3 dummy;
            var     displacement = Traveller.MSTSInterpolateAlongCurve(Vector3.Zero, vectorCurveStartToCenter, curveRotation, root.XNAMatrix, out dummy);

            WorldPosition nextRoot = new WorldPosition(root);

            nextRoot.XNAMatrix.Translation = displacement;

            sv = ev = mv = 0f; dir = 1f;
            sv = ts.StartElev; ev = ts.EndElev; mv = ts.MaxElev;

            //nextRoot.XNAMatrix.Translation += Vector3.Transform(trackLoc, worldMatrix.XNAMatrix);
            dTrackList.Add(new SuperElevationViewer(viewer, root, nextRoot, tss.SectionCurve.Radius, tss.SectionCurve.Angle * 3.14f / 180, sv, ev, mv, dir));
            return(1);
        }
コード例 #22
0
        public void LoadItemsFromMSTS()
        {
#if SHOW_STOPWATCH
            Stopwatch stopWatch = new Stopwatch();
            TimeSpan  ts;
            string    elapsedTime;
            if (File.Exists(@"C:\temp\stopwatch.txt"))
            {
                File.Delete(@"C:\temp\stopwatch.txt");
            }
#endif


            if (TDB == null ||
                TDB.TrackDB == null ||
                TDB.TrackDB.TrItemTable == null)
            {
                return;
            }
            foreach (GlobalItem item in orRouteConfig.AllItems)
            {
                if (item.GetType() == typeof(AEBufferItem))
                {
                    mstsItems.buffers.Add((AEBufferItem)item);
                }
            }
            Program.actEditor.DisplayStatusMessage("Start loading Track Nodes ...");
#if SHOW_STOPWATCH
            stopWatch.Start();
#endif
            nodes = TDB.TrackDB.TrackNodes;
            for (int nodeIdx = 0; nodeIdx < nodes.Length; nodeIdx++)
            {
                if (nodes[nodeIdx] != null)
                {
                    TrackNode currNode = nodes[nodeIdx];

                    AEBufferItem foundBuffer;
                    if (currNode.TrEndNode)
                    {
                        //Program.actEditor.DisplayStatusMessage("Init data for display...  Load End Nodes: " + currNode.Index);
                        try
                        {
                            foundBuffer = (AEBufferItem)orRouteConfig.AllItems.First(x => x.associateNodeIdx == currNode.Index);
                            foundBuffer.updateNode(currNode);
                        }
                        catch (InvalidOperationException)
                        {
                            foundBuffer = new AEBufferItem((TrackNode)currNode);
                            mstsItems.buffers.Add(foundBuffer);
                        }
#if SHOW_STOPWATCH
                        ts = stopWatch.Elapsed;
                        stopWatch.Reset();

                        // Format and display the TimeSpan value.
                        elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                                                    ts.Hours, ts.Minutes, ts.Seconds,
                                                    ts.Milliseconds);
                        File.AppendAllText(@"C:\temp\stopwatch.txt", "One END node: " + elapsedTime + "\n");
                        stopWatch.Start();
#endif
                    }
                    else if (currNode.TrVectorNode != null && currNode.TrVectorNode.TrVectorSections != null)
                    {
                        //Program.actEditor.DisplayStatusMessage("Init data for display...  Load Vector Nodes: " + currNode.Index);
                        if (currNode.TrVectorNode.TrVectorSections.Length > 1)
                        {
                            AddSegments(currNode);
                            TrVectorSection section = currNode.TrVectorNode.TrVectorSections[currNode.TrVectorNode.TrVectorSections.Length - 1];
                            MSTSCoord       A       = new MSTSCoord(section);

                            TrPin pin = currNode.TrPins[1];
                            {
                                TrackNode connectedNode = nodes[pin.Link];
                                int       direction     = DrawUtility.getDirection(currNode, connectedNode);
                                if (A == connectedNode.getMSTSCoord(direction))
                                {
                                    continue;
                                }
                                AESegment    aeSegment = new AESegment(A, connectedNode.getMSTSCoord(direction));
                                TrackSegment lineSeg   = new TrackSegment(aeSegment, currNode, currNode.TrVectorNode.TrVectorSections.Length - 1, direction, TSectionDat);
                                addTrItems(lineSeg, currNode);
                                mstsItems.AddSegment(lineSeg);
                            }
#if SHOW_STOPWATCH
                            ts = stopWatch.Elapsed;
                            stopWatch.Reset();

                            // Format and display the TimeSpan value.
                            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                                                        ts.Hours, ts.Minutes, ts.Seconds,
                                                        ts.Milliseconds);
                            File.AppendAllText(@"C:\temp\stopwatch.txt", "One mult TRACK node: " + elapsedTime + "\n");
                            stopWatch.Start();
#endif
                        }
                        else
                        {
                            TrVectorSection s;
                            s = currNode.TrVectorNode.TrVectorSections[0];
                            areaRoute.manageTiles(s.TileX, s.TileZ);
                            foreach (TrPin pin in currNode.TrPins)
                            {
                                TrackNode connectedNode = nodes[pin.Link];
                                int       direction     = DrawUtility.getDirection(currNode, connectedNode);
                                if (MSTSCoord.near(currNode.getMSTSCoord(direction), connectedNode.getMSTSCoord(direction)))
                                {
                                    continue;
                                }
                                AESegment    aeSegment = new AESegment(currNode.getMSTSCoord(direction), connectedNode.getMSTSCoord(direction));
                                TrackSegment lineSeg   = new TrackSegment(aeSegment, currNode, 0, direction, TSectionDat);
                                addTrItems(lineSeg, currNode);
                                mstsItems.AddSegment(lineSeg);
                            }
#if SHOW_STOPWATCH
                            ts = stopWatch.Elapsed;
                            stopWatch.Reset();

                            // Format and display the TimeSpan value.
                            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                                                        ts.Hours, ts.Minutes, ts.Seconds,
                                                        ts.Milliseconds);
                            File.AppendAllText(@"C:\temp\stopwatch.txt", "One simple TRACK node: " + elapsedTime + "\n");
                            stopWatch.Start();
#endif
                        }
                    }

                    else if (currNode.TrJunctionNode != null)
                    {
                        //Program.actEditor.DisplayStatusMessage("Init data for display...  Load Junction Nodes: " + currNode.Index);
                        mstsItems.switches.Add(new AEJunctionItem(currNode));
                        areaRoute.manageTiles(currNode.UiD.TileX, currNode.UiD.TileZ);
#if SHOW_STOPWATCH
                        ts = stopWatch.Elapsed;
                        stopWatch.Reset();

                        // Format and display the TimeSpan value.
                        elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                                                    ts.Hours, ts.Minutes, ts.Seconds,
                                                    ts.Milliseconds);
                        File.AppendAllText(@"C:\temp\stopwatch.txt", "One JN node: " + elapsedTime + "\n");
                        stopWatch.Start();
#endif
                    }
                }
            }
#if SPA_ADD
            var maxsize = maxX - minX > maxX - minX ? maxX - minX : maxX - minX;
            maxsize = (int)maxsize / 100 * 100;
            if (maxsize < 2000)
            {
                maxsize = 2000;
            }
            ZoomFactor = (decimal)maxsize;
#endif
            #region AddItem


            Program.actEditor.DisplayStatusMessage("Init data for display...  Load MSTS Items...");
            foreach (var item in TDB.TrackDB.TrItemTable)
            {
                if (item.ItemType == TrItem.trItemType.trSIGNAL && Signals != null)
                {
                    if (item is SignalItem)
                    {
#if SHOW_STOPWATCH
                        Program.actEditor.DisplayStatusMessage("Init data for display...  Load Items... Signal");
#endif
                        SignalItem si = item as SignalItem;

                        if (si.SigObj >= 0 && si.SigObj < Signals.SignalObjects.Length)
                        {
                            AESignalObject s = Signals.SignalObjects[si.SigObj];
                            if (s.isSignal) // && s.isSignalNormal())
                            {
                                mstsItems.AddSignal(new AESignalItem(si, s, TDB));
                            }
                        }
                    }
                }
            }

#if SHOW_STOPWATCH
            ts = stopWatch.Elapsed;

            // Format and display the TimeSpan value.
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds);
            File.AppendAllText(@"C:\temp\stopwatch.txt", "Signals: " + elapsedTime + "\n");
            stopWatch.Stop();
#endif
            #endregion
        }