Beispiel #1
0
        private OctreeNode <T> ResizeAndAdd(OctreeItem <T> octreeItem)
        {
            OctreeNode <T> oldRoot            = this;
            Vector3        oldRootCenter      = Bounds.GetCenter();
            Vector3        oldRootHalfExtents = Bounds.GetDimensions() * 0.5f;

            Vector3 expandDirection = Vector3.Normalize(octreeItem.Bounds.GetCenter() - oldRootCenter);
            Vector3 newCenter       = oldRootCenter;

            if (expandDirection.X >= 0) // oldRoot = Left
            {
                newCenter.X += oldRootHalfExtents.X;
            }
            else
            {
                newCenter.X -= oldRootHalfExtents.X;
            }

            if (expandDirection.Y >= 0) // oldRoot = Bottom
            {
                newCenter.Y += oldRootHalfExtents.Y;
            }
            else
            {
                newCenter.Y -= oldRootHalfExtents.Y;
            }

            if (expandDirection.Z >= 0) // oldRoot = Far
            {
                newCenter.Z += oldRootHalfExtents.Z;
            }
            else
            {
                newCenter.Z -= oldRootHalfExtents.Z;
            }

            BoundingBox    newRootBounds = new BoundingBox(newCenter - oldRootHalfExtents * 2f, newCenter + oldRootHalfExtents * 2f);
            OctreeNode <T> newRoot       = _nodeCache.GetNode(ref newRootBounds);
            OctreeNode <T> fittingNode   = newRoot.SplitChildren(ref octreeItem.Bounds, oldRoot);

            if (fittingNode != null)
            {
                bool succeeded = fittingNode.CoreAddItem(octreeItem);
                Debug.Assert(succeeded, "Octree node returned from SplitChildren must fit the item given to it.");
                return(newRoot);
            }
            else
            {
                return(newRoot.CoreAddRootItem(octreeItem));
            }
        }
Beispiel #2
0
        private bool CoreAddItem(OctreeItem <T> item)
        {
            if (Bounds.Contains(ref item.Bounds) != ContainmentType.Contains)
            {
                return(false);
            }

            if (_items.Count >= MaxChildren && Children.Length == 0)
            {
                OctreeNode <T> newNode = SplitChildren(ref item.Bounds, null);
                if (newNode != null)
                {
                    bool succeeded = newNode.CoreAddItem(item);
                    Debug.Assert(succeeded, "Octree node returned from SplitChildren must fit the item given to it.");
                    return(true);
                }
            }
            else if (Children.Length > 0)
            {
                foreach (var child in Children)
                {
                    if (child.CoreAddItem(item))
                    {
                        return(true);
                    }
                }
            }

            // Couldn't fit in any children.
#if DEBUG
            foreach (var child in Children)
            {
                Debug.Assert(child.Bounds.Contains(ref item.Bounds) != ContainmentType.Contains);
            }
#endif

            _items.Add(item);
            item.Container = this;

            return(true);
        }