Split() protected method

protected Split ( ) : void
return void
示例#1
0
            /// <summary>
            /// Try to add an object, starting at this node
            /// </summary>
            public bool TryAddObj(OctreeObject <T> newObj, bool updateCount)
            {
                OctreeNode childNode = this;//Start here
                int        index;

                while (true)
                {
                    if (!childNode.ContainsBounds(ref newObj.boundsMin, ref newObj.boundsMax))
                    { //Doesn't fit in this node. Put it in the parent node.
                        if (childNode.childIndex == -1)
                        {
                            return(false);
                        }

                        childNode.parent.PutObjectInNode(newObj, updateCount);
                        return(true);
                    }

                    index = childNode.BestFitChild(ref newObj.boundsCenter);
                    if (childNode.isLeaf && childNode.localItemCount >= numObjectsAllowed && childNode.ContainsBounds(ref newObj.doubleBoundsMin, ref newObj.doubleBoundsMax))
                    {
                        childNode.Split();//We hit the limit and we can split. We only split if the object will fit in the new bounds
                    }
                    if (!childNode.isLeaf)
                    { //Drop down another level if we have children
                        childNode = childNode.children[index];
                    }
                    else
                    { //Place it here. We have no children and we're under the limit
                        childNode.PutObjectInNode(newObj, updateCount);
                        return(true);
                    }
                }
            }
示例#2
0
        static void Main(string[] args)
        {
            var bounds = new CubeBounds(Vector.Zero, 2);
            var octree = new Octree <string>(bounds);

            //for (int i = 0; i < 100; i++)
            //{
            //    octree.AddValue(Vector.Random(), "beer");
            //}

            //octree.PrintTree();

            var point = Vector.Zero;
            OctreeNode <string> node = new OctreeNode <string>(bounds, 0);

            node.Split();

            foreach (var child in node.Children)
            {
                Console.Write(child.Index + " ");
                Console.WriteLine(child.Bounds.Contains(point));
            }

            Console.WriteLine(node.GetChildContainingPoint(point).Index);

            Console.ReadKey();
        }
示例#3
0
    // Returns whether the node is changed.
    private bool RemoveInternal(IntBox area, OctreeNode <T> node, int level, IntVector3 corner)
    {
        IntBox nodeArea = new IntBox(corner, corner + ((1 << level) - 1) * IntVector3.one);

        if (area.Contains(nodeArea))
        {
            if (!node.isEmpty)
            {
                node.obj      = default(T);
                node.objCount = 0;
                node.RemoveChildren();
                return(true);
            }
            else
            {
                return(false);
            }
        }
        else if (!node.obj.Equals(default(T)))
        {
            node.Split();
        }

        int        childSize     = 1 << (level - 1);
        IntVector3 childIndexMin = IntVector3.Max((area.min - corner) / childSize, IntVector3.zero);
        IntVector3 childIndexMax = IntVector3.Min((area.max - corner) / childSize, IntVector3.one);
        bool       changed       = false;

        for (int x = childIndexMin.x; x <= childIndexMax.x; x++)
        {
            for (int y = childIndexMin.y; y <= childIndexMax.y; y++)
            {
                for (int z = childIndexMin.z; z <= childIndexMax.z; z++)
                {
                    IntVector3 childIndex = new IntVector3(x, y, z);
                    var        childNode  = node.GetChild(childIndex);
                    if (childNode != null)
                    {
                        long oldChildObjCount = childNode.objCount;
                        bool childChanged     = RemoveInternal(area, childNode, level - 1, corner + childIndex * childSize);
                        if (childChanged)
                        {
                            changed        = true;
                            node.objCount += childNode.objCount - oldChildObjCount;
                            if (childNode.isEmpty)
                            {
                                node.RemoveChild(childIndex);
                            }
                        }
                    }
                }
            }
        }
        return(changed);
    }
示例#4
0
    // Returns whether the node is changed.
    private bool SetInternal(IntBox area, T obj, OctreeNode <T> node, int level, IntVector3 corner)
    {
        IntBox nodeArea = new IntBox(corner, corner + ((1 << level) - 1) * IntVector3.one);

        if (node.obj.Equals(obj))
        {
            return(false);
        }
        else if (area.Contains(nodeArea))
        {
            node.obj      = obj;
            node.objCount = 1 << level;
            node.RemoveChildren();
            return(true);
        }
        else if (node.isFilled)
        {
            node.Split();
        }

        int        childSize     = 1 << (level - 1);
        IntVector3 childIndexMin = IntVector3.Max((area.min - corner) / childSize, IntVector3.zero);
        IntVector3 childIndexMax = IntVector3.Min((area.max - corner) / childSize, IntVector3.one);
        bool       changed       = false;

        for (int x = childIndexMin.x; x <= childIndexMax.x; x++)
        {
            for (int y = childIndexMin.y; y <= childIndexMax.y; y++)
            {
                for (int z = childIndexMin.z; z <= childIndexMax.z; z++)
                {
                    IntVector3 childIndex = new IntVector3(x, y, z);
                    var        childNode  = node.GetChild(childIndex);
                    if (childNode == null)
                    {
                        childNode = node.CreateChild(childIndex);
                    }

                    long oldChildObjCount = childNode.objCount;
                    bool childChanged     = SetInternal(area, obj, childNode, level - 1, corner + childIndex * childSize);
                    if (childChanged)
                    {
                        changed        = true;
                        node.objCount += childNode.objCount - oldChildObjCount;
                        if (childNode.isFilled)
                        {
                            node.MergeIfPossible(obj);
                        }
                    }
                }
            }
        }
        return(changed);
    }
示例#5
0
    // Returns whether the node is changed.
    private bool RemoveInternal(IntVector3 coords, OctreeNode <T> node, int level, IntVector3 corner)
    {
        if (level == 0)
        {
            if (!node.isEmpty)
            {
                node.obj      = default(T);
                node.objCount = 0;
                return(true);
            }
            else
            {
                return(false);
            }
        }
        else if (!node.obj.Equals(default(T)))
        {
            node.Split();
        }

        int        childSize  = 1 << (level - 1);
        IntVector3 childIndex = (coords - corner) / childSize;
        var        childNode  = node.GetChild(childIndex);

        if (childNode == null)
        {
            return(false);
        }

        long oldChildObjCount = childNode.objCount;
        bool changed          = RemoveInternal(coords, childNode, level - 1, corner + childIndex * childSize);

        if (changed)
        {
            node.objCount += childNode.objCount - oldChildObjCount;
            if (childNode.isEmpty)
            {
                node.RemoveChild(childIndex);
            }
        }
        return(changed);
    }
示例#6
0
    // Returns whether the node is changed.
    private bool SetInternal(IntVector3 coords, T obj, OctreeNode <T> node, int level, IntVector3 corner)
    {
        if (node.obj.Equals(obj))
        {
            return(false);
        }
        else if (level == 0)
        {
            node.obj = obj;
            return(true);
        }
        else if (node.isFilled)
        {
            node.Split();
        }

        int        childSize  = 1 << (level - 1);
        IntVector3 childIndex = (coords - corner) / childSize;
        var        childNode  = node.GetChild(childIndex);

        if (childNode == null)
        {
            childNode = node.CreateChild(childIndex);
        }

        long oldChildObjCount = childNode.objCount;
        bool changed          = SetInternal(coords, obj, childNode, level - 1, corner + childIndex * childSize);

        if (changed)
        {
            node.objCount += childNode.objCount - oldChildObjCount;
            if (childNode.isFilled)
            {
                node.MergeIfPossible(obj);
            }
        }
        return(changed);
    }
示例#7
0
    private void AddInternal(Vector3 position, int level, IntVector3 coords, OctreeNode node, OctreeElement element)
    {
        if (node.NodeElementCount >= splitThreshold && level < maxLevel)
        {
            Vector3 center = GetCenter(level, coords);
            node.Split(center);
        }

        node.TotalElementCount++;
        if (!node.IsLeaf)
        {
            Vector3    center     = GetCenter(level, coords);
            int        childIndex = PositionToChildIndex(position, center);
            OctreeNode child      = node.GetOrCreateChild(childIndex);
            AddInternal(position, level + 1, coords * 2 + ChildIndexToCoords(childIndex), child, element);
            return;
        }
        element.position = position;
        element.level    = level;
        element.coords   = coords;
        node.Put(element);
        //Debug.Log(element.ToString() + " is added at " + Time.time);
    }
示例#8
0
        void Test2(OctreeNode<Voxel> node, Func<OctreeNode<Voxel>, bool> func)
        {
            if (node.Level > maxLevel) return;

            if (func(node))
            {
                if (node.Level == maxLevel)
                {
                    node.Fill();
                }
                else
                {

                    if (node.Children == null)
                    {
                        node.Split();
                    }
                    Parallel.ForEach(node.Children, child => Test2(child, func));
                }
            }

            //else
            //{
            //    var result = triangles.Where(t => func(node)).ToList();
            //    if (result.Any())
            //    {
            //        if (node.Children == null)
            //        {
            //            node.Split();
            //        }
            //        Parallel.ForEach(node.Children, child => Test2(child, result, func));
            //    }
            //}
        }
示例#9
0
        void Test(OctreeNode<Voxel> node, IEnumerable<Triangle> triangles)
        {
            if (node.Level > maxLevel) return;

            var result = triangles.Where(t => t.Intersects(node.AABB)).ToList();
            if (result.Any())
            {
                if (node.Level == maxLevel)
                {
                    node.Fill();
                }
                else
                {

                    if (node.Children == null)
                    {
                        node.Split();
                    }
                    Parallel.ForEach(node.Children, child => Test(child, result));
                }

            }
        }
示例#10
0
 void Intersect(OctreeNode<Voxel> node, Triangle tri)
 {
     if(node.Level > maxLevel) return;
     if (tri.Intersects(node.AABB))
     {
         if (node.Level == maxLevel)
         {
             node.Fill();
         }
         else
         {
             if (node.Children == null)
             {
                 node.Split();
             }
             foreach (var child in node.Children)
             {
                 Intersect(child,tri);
             }
         }
     }
 }