Exemple #1
0
        /// <summary>
        /// Gets a vertex from the path tree.
        /// </summary>
        public override void GetPathTree(PathTree tree, uint pointer, out uint vertex, out float weight, out uint previous)
        {
            uint data1;

            tree.Get(pointer, out vertex, out data1, out previous);
            weight = data1 / 10.0f;
        }
Exemple #2
0
        /// <summary>
        /// Gets the visit at the given location.
        /// </summary>
        /// <param name="tree">The tree.</param>
        /// <param name="pointer">The pointer.</param>
        /// <returns>The visit.</returns>
        public static (VertexId vertex, uint edge, uint previousPointer) GetVisit(this PathTree tree, uint pointer)
        {
            tree.Get(pointer, out var data0, out var data1, out var data2, out var data3);

            return(new VertexId()
            {
                TileId = data0,
                LocalId = data1
            }, data2, data3);
        }
Exemple #3
0
        /// <summary>
        /// Gets a settled vertex weight.
        /// </summary>
        public static WeightAndDir <float> GetSettledVertexWeight(this PathTree tree, uint pointer)
        {
            uint data0, data1, data2;

            tree.Get(pointer, out data0, out data1, out data2);
            return(new WeightAndDir <float>()
            {
                Weight = data1 / WeightFactor,
                Direction = new Dir()
                {
                    _val = (byte)(data2 & 3)
                }
            });
        }
Exemple #4
0
        /// <summary>
        /// Gets a settled vertex.
        /// </summary>
        public static void GetSettledVertex(this PathTree tree, uint pointer, out uint vertex,
                                            out WeightAndDir <float> weightAndDir, out uint hops)
        {
            uint data0, data1, data2;

            tree.Get(pointer, out data0, out data1, out data2);
            vertex       = data0;
            weightAndDir = new WeightAndDir <float>()
            {
                Weight    = data1 / WeightFactor,
                Direction = new Dir()
                {
                    _val = (byte)(data2 & 3)
                }
            };
            hops = data2 / 4;
        }
Exemple #5
0
        /// <summary>
        /// Finds loops and merges them together.
        /// </summary>
        /// <param name="maxSettles">The maximum labels to settle.</param>
        /// <param name="updateLabel">A callback to update label.</param>
        internal void FindLoops(uint maxSettles, IslandLabels islandLabels, Action <uint, uint> updateLabel)
        {
            // TODO: it's probably better to call reduce here when too much has changed.

            var  pathTree   = new PathTree();
            var  enumerator = _graph.GetEdgeEnumerator();
            var  settled    = new HashSet <uint>();
            var  queue      = new Queue <uint>();
            var  loop       = new HashSet <uint>(); // keeps all with a path back to label, initially only label.
            uint label      = 0;

            while (label < _graph.VertexCount)
            {
                if (!enumerator.MoveTo(label))
                {
                    label++;
                    continue;
                }

                if (islandLabels[label] != label)
                {
                    label++;
                    continue;
                }

                queue.Clear();
                pathTree.Clear();
                settled.Clear();

                loop.Add(label);
                queue.Enqueue(pathTree.Add(label, uint.MaxValue));

                while (queue.Count > 0 &&
                       settled.Count < maxSettles)
                {
                    var pointer = queue.Dequeue();
                    pathTree.Get(pointer, out var current, out var previous);

                    if (settled.Contains(current))
                    {
                        continue;
                    }

                    settled.Add(current);

                    if (!enumerator.MoveTo(current))
                    {
                        continue;
                    }

                    while (enumerator.MoveNext())
                    {
                        var n = enumerator.Neighbour;

                        n = islandLabels[n];

                        if (loop.Contains(n))
                        {
                            // yay, a loop!
                            loop.Add(current);
                            while (previous != uint.MaxValue)
                            {
                                pathTree.Get(previous, out current, out previous);
                                loop.Add(current);
                            }
                        }
                        if (settled.Contains(n))
                        {
                            continue;
                        }

                        queue.Enqueue(pathTree.Add(n, pointer));
                    }
                }

                if (loop.Count > 0)
                {
                    this.Merge(loop, updateLabel);
                }
                loop.Clear();

                // move to the next label.
                label++;
            }
        }