예제 #1
0
        /// <summary>
        /// Adds an item with the given bounds into the octree.
        /// </summary>
        /// <param name="bounds">The bounds of the item.</param>
        /// <param name="value">The item to add.</param>
        /// <returns></returns>
        public BoundsOctreeItem <T> Add(Bounds3 bounds, T value)
        {
            var item = new BoundsOctreeItem <T>(bounds, value);

            if (children == null)
            {
                CreateInitialOctree(item);
                return(item);
            }

            if (Level < item.Level)
            {
                Expand(item);
            }

            var octant = GetOctant(bounds.Center);

            if (children[octant] == null)
            {
                children[octant] = new BoundingOctreeNode <T>(Level, GetOriginIndex3(octant));
            }

            children[octant].Add(item);
            return(item);
        }
예제 #2
0
        public void Add(BoundsOctreeItem <T> item)
        {
            if (!Bounds.Intersects(item.Bounds))
            {
                throw new ArgumentOutOfRangeException();
            }

            if (item.Level > Level)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (item.Level == Level)
            {
                Items.Add(item);
                return;
            }

            var octant = GetOctant(item.Bounds.Center);

            if (children == null)
            {
                if (Items.Count < EdgeThreshold)
                {
                    // Add and continue
                    Items.Add(item);
                    return;
                }

                // Fork children
                children = new BoundingOctreeNode <T> [8];

                for (int i = Items.Count - 1; i >= 0; i--)
                {
                    // Find the target level, if lower, add to child.
                    if (Items[i].Level < Level)
                    {
                        var removed = Items[i];
                        Items.RemoveAt(i);
                        Add(removed);
                    }
                }
            }

            if (children[octant] == null)
            {
                children[octant] = new BoundingOctreeNode <T>(Level - 1, GetChildIndex(octant));
            }

            children[octant].Add(item);
        }
예제 #3
0
        private void CreateInitialOctree(BoundsOctreeItem <T> item)
        {
            Level = item.Level;

            var side = Functions.Pow(2, Level);

            Bounds = new Bounds3(-side, -side, -side, side, side, side);

            children = new BoundingOctreeNode <T> [8];
            var octant = GetOctant(item.Bounds.Center);

            children[octant] = new BoundingOctreeNode <T>(Level, GetOriginIndex3(octant));
            children[octant].Add(item);
        }
예제 #4
0
 private void Expand(BoundsOctreeItem <T> item)
 {
     for (int l = Level; l < item.Level; l++)
     {
         Level += 1;
         for (int i = 0; i < 8; i++)
         {
             if (children[i] != null)
             {
                 var parent = new BoundingOctreeNode <T>(Level, children[i].Index);
                 parent.children = new BoundingOctreeNode <T> [8];
                 parent.children[GetOpposingOctant(i)] = children[i];
                 children[i] = parent;
             }
         }
     }
 }