Example #1
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);
        }
Example #2
0
 private AABBTreeRayTestResult DefaultCallback(AABBTree tree, AABBExternalNode node, AABBTreeRay ray, double distance, double upperBound)
 {
     return(new AABBTreeRayTestResult()
     {
         factor = Math.Min(distance, upperBound)
     });
 }
Example #3
0
        public void clear()
        {
            this.escapeNodeOffset = 1;
            this.externalNode     = null;
            var oldExtents = this.extents;
            var maxNumber  = double.MaxValue;

            oldExtents[0] = maxNumber;
            oldExtents[1] = maxNumber;
            oldExtents[2] = maxNumber;
            oldExtents[3] = -maxNumber;
            oldExtents[4] = -maxNumber;
            oldExtents[5] = -maxNumber;
        }
Example #4
0
        public void reset(double minX, double minY, double minZ,
                          double maxX, double maxY, double maxZ,
                          int escapeNodeOffset, AABBExternalNode externalNode = null)
        {
            this.escapeNodeOffset = escapeNodeOffset;
            this.externalNode     = externalNode;
            var oldExtents = this.extents;

            oldExtents[0] = minX;
            oldExtents[1] = minY;
            oldExtents[2] = minZ;
            oldExtents[3] = maxX;
            oldExtents[4] = maxY;
            oldExtents[5] = maxZ;
        }
Example #5
0
        public void remove(AABBExternalNode externalNode)
        {
            var index = externalNode.spatialIndex;

            if (index >= 0)
            {
                if (this.numExternalNodes > 1)
                {
                    var nodes = this.nodes;
                    Debug.Assert(nodes[index].externalNode == externalNode);
                    nodes[index].clear();

                    var endNode = this.getNodeCount();
                    if ((index + 1) >= endNode)
                    {
                        while (nodes[endNode - 1].externalNode == null) // No leaf
                        {
                            endNode -= 1;
                        }

                        if (this.nodes.Count > endNode)
                        {
                            this.nodes.RemoveRange(endNode, this.nodes.Count - endNode);
                        }
                    }
                    else
                    {
                        this.needsRebuild = true;
                    }
                    this.numExternalNodes -= 1;
                }
                else
                {
                    this.clear();
                }

                externalNode.spatialIndex = -1;
            }
        }
Example #6
0
        public void RemoveTest()
        {
            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.remove(node);
            tree.finalize();
            Assert.Equal(1, tree.getNodes().Count);

            tree.clear();
            Assert.Equal(0, tree.getNodes().Count);
        }
Example #7
0
        public void add(AABBExternalNode externalNode, AABBBox extents)
        {
            var endNode = this.getNodeCount();

            externalNode.spatialIndex = endNode - 1;

            var node = new AABBTreeNode(new AABBBox(), 1, null);

            node.escapeNodeOffset = 1;
            node.externalNode     = externalNode;
            var copyExtents = node.extents;

            copyExtents[0] = extents[0];
            copyExtents[1] = extents[1];
            copyExtents[2] = extents[2];
            copyExtents[3] = extents[3];
            copyExtents[4] = extents[4];
            copyExtents[5] = extents[5];

            this.nodes.Add(node);
            this.needsRebuild      = true;
            this.numAdds          += 1;
            this.numExternalNodes += 1;
        }
Example #8
0
        public void update(AABBExternalNode externalNode, AABBBox extents)
        {
            var index = externalNode.spatialIndex;

            if (index >= 0)
            {
                var min0 = extents[0];
                var min1 = extents[1];
                var min2 = extents[2];
                var max0 = extents[3];
                var max1 = extents[4];
                var max2 = extents[5];

                var needsRebuild = this.needsRebuild;
                var needsRebound = this.needsRebound;
                var nodes        = this.nodes;
                var node         = nodes[index];
                Debug.Assert(node.externalNode == externalNode);
                var nodeExtents = node.extents;

                var doUpdate = (needsRebuild ||
                                needsRebound ||
                                nodeExtents[0] > min0 ||
                                nodeExtents[1] > min1 ||
                                nodeExtents[2] > min2 ||
                                nodeExtents[3] < max0 ||
                                nodeExtents[4] < max1 ||
                                nodeExtents[5] < max2);

                nodeExtents[0] = min0;
                nodeExtents[1] = min1;
                nodeExtents[2] = min2;
                nodeExtents[3] = max0;
                nodeExtents[4] = max1;
                nodeExtents[5] = max2;

                if (doUpdate)
                {
                    if (!needsRebuild && 1 < nodes.Count)
                    {
                        this.numUpdates += 1;
                        if (this.startUpdate > index)
                        {
                            this.startUpdate = index;
                            if (this.endUpdate < index)
                            {
                                this.endUpdate = index;
                                if (!needsRebound)
                                {
                                    // force a rebound when things change too much
                                    if ((2 * this.numUpdates) > this.numExternalNodes)
                                    {
                                        this.needsRebound = true;
                                    }
                                    else
                                    {
                                        var parent        = this.findParent(index);
                                        var parentExtents = parent.extents;
                                        if (parentExtents[0] > min0 ||
                                            parentExtents[1] > min1 ||
                                            parentExtents[2] > min2 ||
                                            parentExtents[3] < max0 ||
                                            parentExtents[4] < max1 ||
                                            parentExtents[5] < max2)
                                        {
                                            this.needsRebound = true;
                                        }
                                    }
                                }
                                else
                                {
                                    // force a rebuild when things change too much
                                    if (this.numUpdates > (3 * this.numExternalNodes))
                                    {
                                        this.needsRebuild = true;
                                        this.numAdds      = this.numUpdates;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        this.add(externalNode, extents);
                    }
                }
            }
        }
Example #9
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();
        }
Example #10
0
        public AABBBox extents;               // bounding box

        public AABBTreeNode(AABBBox extents, int escapeNodeOffset, AABBExternalNode externalNode)
        {
            this.escapeNodeOffset = escapeNodeOffset;
            this.externalNode     = externalNode;
            this.extents          = extents;
        }