Exemplo n.º 1
0
        internal RoadCollection(RoadTopology topology, AssetLoadContext loadContext, HeightMap heightMap)
            : this()
        {
            // The map stores road segments with no connectivity:
            // - a segment is from point A to point B
            // - with a road type name
            // - and start and end curve types (angled, tight curve, broad curve).

            // The goal is to create road networks of connected road segments,
            // where a network has only a single road type.

            // A road network is composed of 2 or more nodes.
            // A network is a (potentially) cyclic graph.

            // A road node has > 1 and <= 4 edges connected to it.
            // A node can be part of multiple networks.

            // An edge can only exist in one network.

            var roadTemplateList = new RoadTemplateList(loadContext.AssetStore.RoadTemplates);

            var networks = RoadNetwork.BuildNetworks(topology, roadTemplateList);

            foreach (var network in networks)
            {
                _roads.Add(AddDisposable(new Road(
                                             loadContext,
                                             heightMap,
                                             network)));
            }
        }
Exemplo n.º 2
0
        private static IList <RoadNetwork> BuildNetworks(RoadTopology topology, IReadOnlyDictionary <RoadTopologyEdge, StraightRoadSegment> edgeSegments)
        {
            var networks = new List <RoadNetwork>();

            // Create one network for each connected set of segments of a specific type.
            foreach (var templateEdges in topology.Edges.GroupBy(e => e.Template))
            {
                var edgesToProcess = new HashSet <IRoadSegment>(templateEdges.Select(e => edgeSegments[e]));

                while (edgesToProcess.Any())
                {
                    var edgeSegment = edgesToProcess.First();
                    edgesToProcess.Remove(edgeSegment);

                    var seenSegments = new HashSet <IRoadSegment>();
                    seenSegments.Add(edgeSegment);

                    var network = new RoadNetwork(templateEdges.Key);
                    networks.Add(network);

                    network._segments.Add(edgeSegment);

                    foreach (var endPoint in edgeSegment.EndPoints)
                    {
                        FollowPath(endPoint);
                    }

                    void FollowPath(RoadSegmentEndPoint endPoint)
                    {
                        if (endPoint.To == null || seenSegments.Contains(endPoint.To))
                        {
                            return;
                        }

                        edgesToProcess.Remove(endPoint.To);
                        network._segments.Add(endPoint.To);
                        seenSegments.Add(endPoint.To);

                        foreach (var nextEndPoint in endPoint.To.EndPoints)
                        {
                            FollowPath(nextEndPoint);
                        }
                    }
                }
            }

            return(networks);
        }
Exemplo n.º 3
0
        internal RoadCollection(RoadTopology topology, AssetLoadContext loadContext, HeightMap heightMap)
            : this()
        {
            // The map stores road segments with no connectivity:
            // - a segment is from point A to point B
            // - with a road type name
            // - and start and end curve types (angled, tight curve, broad curve).

            // The goal is to create road networks of connected road segments,
            // where a network has only a single road type.

            // A road network is composed of 2 or more nodes.
            // A network is a (potentially) cyclic graph.

            // A road node has > 1 and <= 4 edges connected to it.
            // A node can be part of multiple networks.

            // An edge can only exist in one network.

            // TODO: If a node stored in the map has > 4 edges, the extra edges
            // are put into a separate network.

            var networks = RoadNetwork.BuildNetworks(topology);

            // Roads of different types are rendered in reverse template order:
            // the first template has the lowest z-index, the last one the highest.
            // Since we don't know the index here we start with the templates,
            // join them with the networks and reverse the result.
            var sortedNetworks = loadContext.AssetStore.RoadTemplates
                                 .Join(
                networks,
                t => t.InstanceId,
                n => n.Template.InstanceId,
                (t, n) => n)
                                 .Reverse();

            foreach (var network in sortedNetworks)
            {
                _roads.Add(AddDisposable(new Road(
                                             loadContext,
                                             heightMap,
                                             network)));
            }
        }