Ejemplo n.º 1
0
        private AABBTree getInitData1()
        {
            var tree = new AABBTree(true);

            tree.add(new AABBExternalNode()
            {
                Data = 1
            }, new AABBBox(new Point3(0, 0, 0), new Point3(10, 10, 10)));
            tree.add(new AABBExternalNode()
            {
                Data = 2
            }, new AABBBox(new Point3(5, 5, 5), new Point3(15, 15, 15)));
            tree.add(new AABBExternalNode()
            {
                Data = 3
            }, new AABBBox(new Point3(20, 20, 20), new Point3(30, 30, 30)));
            tree.add(new AABBExternalNode()
            {
                Data = 4
            }, new AABBBox(new Point3(40, 40, 40), new Point3(50, 50, 50)));
            tree.add(new AABBExternalNode()
            {
                Data = 5
            }, new AABBBox(new Point3(51, 51, 51), new Point3(60, 60, 60)));

            tree.finalize();

            return(tree);
        }
Ejemplo n.º 2
0
        public void UpdateTest()
        {
            var tree = new AABBTree(true);
            var node = new AABBExternalNode()
            {
                Data = 1
            };

            tree.add(node, new AABBBox(new Point3(1, 1, 1), new Point3(10, 10, 10)));
            tree.add(new AABBExternalNode()
            {
                Data = 2
            }, new AABBBox(new Point3(5, 5, 5), new Point3(15, 15, 15)));
            tree.finalize();
            Assert.Equal(3, tree.getNodes().Count);

            tree.update(node, new AABBBox(new Point3(20, 20, 20), new Point3(33, 33, 33)));
            tree.finalize();
            Assert.Equal(3, tree.getNodes().Count);

            var treeNode = tree.getNodes().FirstOrDefault(n => n.externalNode?.spatialIndex == node.spatialIndex);

            Assert.NotNull(treeNode);
            Assert.Equal(20, treeNode.extents[0]);
            Assert.Equal(20, treeNode.extents[1]);
            Assert.Equal(20, treeNode.extents[2]);
            Assert.Equal(33, treeNode.extents[3]);
            Assert.Equal(33, treeNode.extents[4]);
            Assert.Equal(33, treeNode.extents[5]);

            tree.clear();
            Assert.Equal(0, tree.getNodes().Count);
        }
Ejemplo n.º 3
0
 private AABBTreeRayTestResult DefaultCallback(AABBTree tree, AABBExternalNode node, AABBTreeRay ray, double distance, double upperBound)
 {
     return(new AABBTreeRayTestResult()
     {
         factor = Math.Min(distance, upperBound)
     });
 }
Ejemplo n.º 4
0
        public AABBTreeRayTestResult rayTest(AABBTree[] trees,
                                             AABBTreeRay ray,
                                             Func <AABBTree, AABBExternalNode, AABBTreeRay, double, double, AABBTreeRayTestResult> callback)
        {
            //
            //
            // we traverse both trees at once
            // keeping a priority list of nodes to check next.

            // TODO: possibly implement priority list more effeciently?
            //       binary heap probably too much overhead in typical case.
            List <PriorityNode> priorityList = new List <PriorityNode>();
            //current upperBound on distance to first intersection
            //and current closest object properties
            AABBTreeRayTestResult minimumResult = null;

            var upperBound = ray.maxFactor;

            for (int i = 0; i < trees.Length; i += 1)
            {
                AABBTree tree = trees[i];
                if (tree.getNodeCount() != 0)
                {
                    upperBound = processNode(tree, ray, 0, upperBound, callback, ref priorityList, ref minimumResult);
                }
            }

            while (priorityList.Count != 0)
            {
                var nodeObj = priorityList.Last();
                priorityList.RemoveAt(priorityList.Count - 1);
                // A node inserted into priority list after this one may have
                // moved the upper bound.
                if (nodeObj.distance >= upperBound)
                {
                    continue;
                }

                var      nodeIndex = nodeObj.nodeIndex;
                AABBTree tree      = nodeObj.tree;
                var      nodes     = tree.getNodes();

                var node     = nodes[nodeIndex];
                var maxIndex = nodeIndex + node.escapeNodeOffset;

                var childIndex = nodeIndex + 1;
                do
                {
                    upperBound  = processNode(tree, ray, childIndex, upperBound, callback, ref priorityList, ref minimumResult);
                    childIndex += nodes[childIndex].escapeNodeOffset;
                }while (childIndex < maxIndex);
            }

            return(minimumResult);
        }
Ejemplo n.º 5
0
        public void rayTest_Test()
        {
            AABBTree tree = getInitData();

            Assert.NotNull(tree);

            var ray = new AABBTreeRay()
            {
                direction = new Vector3(1, 1, 1), origin = new Point3(), maxFactor = 30
            };
            var testRes = new AABBTreeRayTest().rayTest(new AABBTree[] { tree }, ray);
        }
Ejemplo n.º 6
0
        public void getOverlappingPairs_Test()
        {
            AABBTree tree = getInitData1();

            Assert.NotNull(tree);

            List <AABBExternalNode> overlappingNodes = new List <AABBExternalNode>();
            var count = tree.getOverlappingPairs(overlappingNodes);

            Assert.Equal(2, count);
            Assert.Equal(1, overlappingNodes[0].Data);
            Assert.Equal(2, overlappingNodes[1].Data);
        }
Ejemplo n.º 7
0
        public void getSphereOverlappingNodes_Test(double center, double radius, int[] result)
        {
            AABBTree tree = getInitData1();

            Assert.NotNull(tree);

            List <AABBExternalNode> overlappingNodes = new List <AABBExternalNode>();
            var actualCount = tree.getSphereOverlappingNodes(new Point3(center, center, center), radius, overlappingNodes);

            Assert.Equal(result.Length, actualCount);
            var actualRes = overlappingNodes.Select(n => (int)n.Data).ToList();

            actualRes.Sort();
            Assert.Equal(result, actualRes);
        }
Ejemplo n.º 8
0
        public void getOverlappingNodes_Test(double min, double max, int[] result)
        {
            AABBTree tree = getInitData1();

            Assert.NotNull(tree);

            List <AABBExternalNode> overlappingNodes = new List <AABBExternalNode>();
            var queryExtents = new AABBBox(new Point3(min, min, min), new Point3(max, max, max));
            var actualCount  = tree.getOverlappingNodes(queryExtents, overlappingNodes);

            Assert.Equal(result.Length, actualCount);
            var actualRes = overlappingNodes.Select(n => (int)n.Data).ToList();

            actualRes.Sort();
            Assert.Equal(result, actualRes);
        }
Ejemplo n.º 9
0
        //[InlineData(0, 0, 1, 100, new int[] { 4, 5 })] ÓÐÎÊÌâ
        public void getOverlappingNodes_Test(double a, double b, double c, double d, int[] result)
        {
            AABBTree tree = getInitData();

            Assert.NotNull(tree);

            List <AABBExternalNode> resultNodes = new List <AABBExternalNode>();
            var plane       = new Plane3(a, b, c, d);
            var actualCount = tree.getVisibleNodes(new Plane3[] { plane }, resultNodes);

            Assert.Equal(result.Length, actualCount);
            var actualRes = resultNodes.Select(n => (int)n.Data).ToList();

            actualRes.Sort();
            Assert.Equal(result, actualRes);
        }
Ejemplo n.º 10
0
        public void AddTest()
        {
            var tree = new AABBTree(true);

            tree.add(new AABBExternalNode()
            {
                Data = 1
            }, new AABBBox(new Point3(1, 1, 1), new Point3(10, 10, 10)));
            tree.finalize();
            Assert.Equal(1, tree.getNodes().Count);

            tree.add(new AABBExternalNode()
            {
                Data = 2
            }, new AABBBox(new Point3(5, 5, 5), new Point3(15, 15, 15)));
            tree.finalize();
            Assert.Equal(3, tree.getNodes().Count);

            tree.clear();
            Assert.Equal(0, tree.getNodes().Count);
        }
Ejemplo n.º 11
0
        //if node is a leaf, intersect ray with shape
        // otherwise insert node into priority list.
        double processNode(AABBTree tree,
                           AABBTreeRay ray,
                           int nodeIndex,
                           double upperBound,
                           Func <AABBTree, AABBExternalNode, AABBTreeRay, double, double, AABBTreeRayTestResult> callback,
                           ref List <PriorityNode> priorityList,
                           ref AABBTreeRayTestResult minimumResult)
        {
            var nodes    = tree.getNodes();
            var node     = nodes[nodeIndex];
            var distance = distanceExtents(ray, node.extents, upperBound);

            if (distance == null)
            {
                return(upperBound);
            }

            if (node.externalNode != null)
            {
                var result = callback(tree, node.externalNode, ray, distance.Value, upperBound);
                if (result != null)
                {
                    minimumResult = result;
                    upperBound    = result.factor;
                }
            }
            else
            {
                // TODO: change to binary search?
                var length = priorityList.Count;
                int i;
                for (i = 0; i < length; i += 1)
                {
                    var curObj = priorityList[i];
                    if (distance > curObj.distance)
                    {
                        break;
                    }
                }

                if (i >= length - 1)
                {
                    //insert node at index i
                    priorityList.Add(new PriorityNode()
                    {
                        tree      = tree,
                        nodeIndex = nodeIndex,
                        distance  = distance.Value
                    });
                }
                else
                {
                    //insert node at index i
                    priorityList.Insert(i + 1, new PriorityNode()
                    {
                        tree      = tree,
                        nodeIndex = nodeIndex,
                        distance  = distance.Value
                    });
                }
            }

            return(upperBound);
        }
Ejemplo n.º 12
0
        static void Main(string[] args)
        {
            // build tree
            var tree = new AABBTree(true);

            tree.add(new AABBExternalNode()
            {
                Data = 1
            }, new AABBBox(new Point3(0, 0, 0), new Point3(10, 10, 10)));
            tree.add(new AABBExternalNode()
            {
                Data = 2
            }, new AABBBox(new Point3(5, 5, 5), new Point3(15, 15, 15)));
            tree.add(new AABBExternalNode()
            {
                Data = 3
            }, new AABBBox(new Point3(20, 20, 20), new Point3(30, 30, 30)));
            tree.add(new AABBExternalNode()
            {
                Data = 4
            }, new AABBBox(new Point3(40, 40, 40), new Point3(50, 50, 50)));
            var node = new AABBExternalNode()
            {
                Data = 6
            };

            tree.add(node, new AABBBox(new Point3(50, 50, 50), new Point3(60, 60, 60)));
            var lastNode = new AABBExternalNode()
            {
                Data = 5
            };

            tree.add(lastNode, new AABBBox(new Point3(51, 51, 51), new Point3(60, 60, 60)));

            tree.finalize();

            // remove
            tree.remove(node);
            tree.update(lastNode, new AABBBox(new Point3(51, 51, 51), new Point3(61, 61, 61)));
            tree.finalize();

            // get parent
            var parent   = tree.findParent(lastNode.spatialIndex);
            var children = tree.findChildren(1);

            // get all the overlapping pairs
            List <AABBExternalNode> overlappingNodes = new List <AABBExternalNode>();
            var count = tree.getOverlappingPairs(overlappingNodes);

            Console.WriteLine($"Node Count:{count}");
            overlappingNodes.ForEach(node => node.Print());
            overlappingNodes.Clear();

            // find overlapping nodes by bounding box
            var queryExtents = new AABBBox(new Point3(-40, -40, -40), new Point3(40, 40, 40));

            count = tree.getOverlappingNodes(queryExtents, overlappingNodes);
            Console.WriteLine($"Node Count:{count}");
            overlappingNodes.ForEach(node => node.Print());
            overlappingNodes.Clear();

            // find overlapping nodes by sphere
            count = tree.getSphereOverlappingNodes(new Point3(20, 20, 20), 21, overlappingNodes);
            Console.WriteLine($"Node Count:{count}");
            overlappingNodes.ForEach(node => node.Print());
            overlappingNodes.Clear();

            // find nodes by planes
            var normal = new Vector3(0, 0, 1);
            var plane  = new Plane3(normal.X, normal.Y, normal.Z, -20);

            count = tree.getVisibleNodes(new Plane3[] { plane }, overlappingNodes);
            Console.WriteLine($"Node Count:{count}");
            overlappingNodes.ForEach(node => node.Print());
            overlappingNodes.Clear();

            // TODO: ray test
            var ray = new AABBTreeRay()
            {
                direction = new Vector3(1, 1, 1), origin = new Point3(), maxFactor = 30
            };
            var testRes = new AABBTreeRayTest().rayTest(new AABBTree[] { tree }, ray);

            tree.clear();
        }