コード例 #1
0
ファイル: DrawPath.cs プロジェクト: perpetualKid/ORTS-MG
        /// <summary>
        /// Draw (part of) a tracksection (either curved or straight)
        /// </summary>
        /// <param name="drawArea">Area to draw upon</param>
        /// <param name="tvs">The vectorSection itself that needs to be drawn</param>
        /// <param name="colors">Colorscheme to use</param>
        /// <param name="startOffset">Do not draw the first startOffset meters in the section</param>
        /// <param name="stopOffset">Do not draw past stopOffset meters (draw all if stopOffset less than 0)</param>
        /// <remarks>Note that his is very similar to DrawTrackSection in class DrawTrackDB, but this one allows to draw partial sections</remarks>
        private void DrawTrackSection(DrawArea drawArea, TrackVectorSection tvs, ColorScheme colors,
                                      float startOffset, float stopOffset)
        {
            TrackSection trackSection = tsectionDat.TrackSections.Get(tvs.SectionIndex);

            if (trackSection == null)
            {
                return;
            }

            ref readonly WorldLocation thisLocation = ref tvs.Location;
コード例 #2
0
ファイル: Exceptions.cs プロジェクト: perpetualKid/ORTS-MG
 protected TravellerInitializationException(Exception innerException, int tileX, int tileZ, float x, float y, float z, TrackVectorSection tvs, float errorLimit, string format, params object[] args)
     : base(string.Format(CultureInfo.CurrentCulture, format, args), innerException)
 {
     TileX = tileX;
     TileZ = tileZ;
     X     = x;
     Y     = y;
     Z     = z;
     TrackVectorSection = tvs;
     ErrorLimit         = errorLimit;
 }
コード例 #3
0
        /// <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;
            TrackVectorNode tn = TrackDB.TrackNodes[TvnIndex] as TrackVectorNode;

            for (int tvsi = 0; tvsi < TrackVectorSectionIndex; tvsi++)
            {
                TrackVectorSection tvs          = tn.TrackVectorSections[tvsi];
                TrackSection       trackSection = TsectionDat.TrackSections.Get(tvs.SectionIndex);
                if (trackSection != null)  // if trackSection is missing somehow, well, do without.
                {
                    distanceFromStart += DrawTrackDB.GetLength(trackSection);
                }
            }
            return(distanceFromStart);
        }
コード例 #4
0
ファイル: PathChartData.cs プロジェクト: perpetualKid/ORTS-MG
        /// <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(TrackVectorNode vectorNode, int tvsi, bool isForward)
        {
            TrackVectorSection tvs          = vectorNode.TrackVectorSections[tvsi];
            TrackSection       trackSection = tsectionDat.TrackSections.Get(tvs.SectionIndex);

            float curvature = 0;

            if (trackSection?.Curved ?? false) // if it is null, something is wrong but we do not want to crash
            {
                curvature = Math.Sign(trackSection.Angle) / trackSection.Radius;
                if (!isForward)
                {
                    curvature *= -1;
                }
            }

            return(curvature);
        }
コード例 #5
0
ファイル: PathChartData.cs プロジェクト: perpetualKid/ORTS-MG
        /// <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(TrackVectorNode tn, int tvsi)
        {
            float fullSectionLength;
            TrackVectorSection tvs          = tn.TrackVectorSections[tvsi];
            TrackSection       trackSection = tsectionDat.TrackSections.Get(tvs.SectionIndex);

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

            if (trackSection.Curved)
            {
                fullSectionLength = trackSection.Radius * Math.Abs(Microsoft.Xna.Framework.MathHelper.ToRadians(trackSection.Angle));
            }
            else
            {
                fullSectionLength = trackSection.Length;
            }
            return(fullSectionLength);
        }
コード例 #6
0
ファイル: Exceptions.cs プロジェクト: perpetualKid/ORTS-MG
 public TravellerOutsideBoundingAreaException(int tileX, int tileZ, float x, float y, float z, TrackVectorSection tvs, float errorLimit, float dx, float dz)
     : base(null, tileX, tileZ, x, y, z, tvs, errorLimit, "{0} is ({3} > {2} or {4} > {2}) outside the bounding area of track vector section {1}", new WorldLocation(tileX, tileZ, x, y, z), tvs, errorLimit, dx, dz)
 {
     DistanceX = dx;
     DistanceZ = dz;
 }
コード例 #7
0
ファイル: Exceptions.cs プロジェクト: perpetualKid/ORTS-MG
 public TravellerBeyondTrackLengthException(int tileX, int tileZ, float x, float y, float z, TrackVectorSection tvs, float errorLimit, float length, float distance)
     : base(null, tileX, tileZ, x, y, z, tvs, errorLimit, "{0} is ({2} < {3} or {2} > {4}) beyond the extents of track vector section {1}", new WorldLocation(tileX, tileZ, x, y, z), tvs, distance, -errorLimit, length + errorLimit)
 {
     Length   = length;
     Distance = distance;
 }
コード例 #8
0
ファイル: Exceptions.cs プロジェクト: perpetualKid/ORTS-MG
 public TravellerOutsideCenterlineException(int tileX, int tileZ, float x, float y, float z, TrackVectorSection tvs, float errorLimit, float distance)
     : base(null, tileX, tileZ, x, y, z, tvs, errorLimit, "{0} is ({2} > {3}) from the centerline of track vector section {1}", new WorldLocation(tileX, tileZ, x, y, z), tvs, distance, errorLimit)
 {
     Distance = distance;
 }
コード例 #9
0
ファイル: TrackSegment.cs プロジェクト: perpetualKid/ORTS-MG
 public TrackSegment(TrackVectorSection trackVectorSection, TrackSection trackSection, uint trackNodeIndex)
 {
     ref readonly WorldLocation location = ref trackVectorSection.Location;
コード例 #10
0
        private void AddTrackSegments()
        {
            double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue;

            List <TrackSegment>    trackSegments = new List <TrackSegment>();
            List <TrackEndSegment> endSegments = new List <TrackEndSegment>();
            List <JunctionSegment> junctionSegments = new List <JunctionSegment>();
            List <TrackSegment>    roadSegments = new List <TrackSegment>();
            List <TrackEndSegment> roadEndSegments = new List <TrackEndSegment>();

            foreach (TrackNode trackNode in trackDB?.TrackNodes ?? Enumerable.Empty <TrackNode>())
            {
                switch (trackNode)
                {
                case TrackEndNode trackEndNode:
                    TrackVectorNode connectedVectorNode = trackDB.TrackNodes[trackEndNode.TrackPins[0].Link] as TrackVectorNode;
                    endSegments.Add(new TrackEndSegment(trackEndNode, connectedVectorNode, trackSectionsFile.TrackSections));
                    break;

                case TrackVectorNode trackVectorNode:
                    foreach (TrackVectorSection trackVectorSection in trackVectorNode.TrackVectorSections)
                    {
                        TrackSection trackSection = trackSectionsFile.TrackSections.Get(trackVectorSection.SectionIndex);
                        if (trackSection != null)
                        {
                            trackSegments.Add(new TrackSegment(trackVectorSection, trackSection, trackVectorNode.Index));
                        }
                    }
                    break;

                case TrackJunctionNode trackJunctionNode:
                    foreach (TrackPin pin in trackJunctionNode.TrackPins)
                    {
                        if (trackDB.TrackNodes[pin.Link] is TrackVectorNode vectorNode && vectorNode.TrackVectorSections.Length > 0)
                        {
                            TrackVectorSection item = pin.Direction == Common.TrackDirection.Reverse ? vectorNode.TrackVectorSections.First() : vectorNode.TrackVectorSections.Last();
                        }
                    }
                    junctionSegments.Add(new JunctionSegment(trackJunctionNode));
                    break;
                }
            }

            TrackSegments     = new TileIndexedList <TrackSegment, Tile>(trackSegments);
            JunctionSegments  = new TileIndexedList <JunctionSegment, Tile>(junctionSegments);
            TrackEndSegments  = new TileIndexedList <TrackEndSegment, Tile>(endSegments);
            TrackNodeSegments = trackSegments.GroupBy(t => t.TrackNodeIndex).ToDictionary(i => i.Key, i => i.ToList());

            foreach (TrackNode trackNode in roadTrackDB?.TrackNodes ?? Enumerable.Empty <TrackNode>())
            {
                switch (trackNode)
                {
                case TrackEndNode trackEndNode:
                    TrackVectorNode connectedVectorNode = roadTrackDB.TrackNodes[trackEndNode.TrackPins[0].Link] as TrackVectorNode;
                    roadEndSegments.Add(new RoadEndSegment(trackEndNode, connectedVectorNode, trackSectionsFile.TrackSections));
                    break;

                case TrackVectorNode trackVectorNode:
                    foreach (TrackVectorSection trackVectorSection in trackVectorNode.TrackVectorSections)
                    {
                        TrackSection trackSection = trackSectionsFile.TrackSections.Get(trackVectorSection.SectionIndex);
                        if (trackSection != null)
                        {
                            roadSegments.Add(new RoadSegment(trackVectorSection, trackSection, trackVectorNode.Index));
                        }
                    }
                    break;
                }
            }

            RoadSegments          = new TileIndexedList <RoadSegment, Tile>(roadSegments);
            RoadEndSegments       = new TileIndexedList <RoadEndSegment, Tile>(roadEndSegments);
            RoadTrackNodeSegments = roadSegments.GroupBy(t => t.TrackNodeIndex).ToDictionary(i => i.Key, i => i.ToList());

            Tiles = new TileIndexedList <GridTile, Tile>(
                TrackSegments.Select(d => d.Tile as ITile).Distinct()
                .Union(TrackEndSegments.Select(d => d.Tile as ITile).Distinct())
                .Union(RoadSegments.Select(d => d.Tile as ITile).Distinct())
                .Union(RoadEndSegments.Select(d => d.Tile as ITile).Distinct())
                .Select(t => new GridTile(t)));

            if (Tiles.Count == 1)
            {
                foreach (TrackEndSegment trackEndSegment in TrackEndSegments)
                {
                    minX = Math.Min(minX, trackEndSegment.Location.X);
                    minY = Math.Min(minY, trackEndSegment.Location.Y);
                    maxX = Math.Max(maxX, trackEndSegment.Location.X);
                    maxY = Math.Max(maxY, trackEndSegment.Location.Y);
                }
            }
            else
            {
                minX = Math.Min(minX, Tiles[0][0].Tile.X);
                maxX = Math.Max(maxX, Tiles[Tiles.Count - 1][0].Tile.X);
                foreach (GridTile tile in Tiles)
                {
                    minY = Math.Min(minY, tile.Tile.Z);
                    maxY = Math.Max(maxY, tile.Tile.Z);
                }
                minX = minX * WorldLocation.TileSize - WorldLocation.TileSize / 2;
                maxX = maxX * WorldLocation.TileSize + WorldLocation.TileSize / 2;
                minY = minY * WorldLocation.TileSize - WorldLocation.TileSize / 2;
                maxY = maxY * WorldLocation.TileSize + WorldLocation.TileSize / 2;
            }
            Bounds = new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
        }