Exemplo n.º 1
0
    //Method that creates the 8 children of this node. After creating them, it empties its own List of items-
    private bool split()
    {
        float half = halfSpaceLength / 2f;

        if (half >= minimumSize)
        {
            for (int y = 0; y < 2; y++)
            {
                for (int z = 0; z < 2; z++)
                {
                    for (int x = 0; x < 2; x++)
                    {
                        Vector3 childCenter = new Vector3(centerSpace.x + half * Mathf.Pow(-1f, x),
                                                          centerSpace.y + half * Mathf.Pow(-1f, y),
                                                          centerSpace.z + half * Mathf.Pow(-1f, z));

                        _children [4 * y + 2 * z + x] = new octreeNode(this, new List <octreeItem>(nodeElements), half, childCenter, "node");
                    }
                }
            }
            return(true);
        }
        else
        {
            return(false);
        }
    }
Exemplo n.º 2
0
    //Constructor-
    public octreeNode(octreeNode parent, List <octreeItem> potentialItems, float halfLength, Vector3 centerPos, string name)
    {
        this.parent          = parent;
        this.centerSpace     = centerPos;
        this.halfSpaceLength = halfLength;
        this.name            = name + "(" + id++ + ")"; //Only for debugging-

        for (int i = 0; i < potentialItems.Count; i++)
        {
            processItem(potentialItems[i]);
        }

        //Graphic representation of the space-
        drawNodeSpace();
    }
Exemplo n.º 3
0
    //Alternative to push method proposed below:
    private void pushItem(octreeItem item)
    {
        //If the item belongs to this node's elements, then it will not be evaluated:
        if (!nodeElements.Contains(item))
        {
            //If the item has an owner (meaning he is being modified, not created):
            if (item.ownerNodes.Count > 0)
            {
                //If the item's owner is different from this node (caused by items moved or node split)
                if (!ReferenceEquals(this, item.ownerNodes [0]))
                {
                    //You get the previous owner reference:
                    octreeNode prevOwner = item.ownerNodes [0];
                    prevOwner.nodeElements.Remove(item);
                    item.ownerNodes [0] = this;
                    this.nodeElements.Add(item);

                    //If the previous owner was not root, then you have to check wether his parent should merge his children back together:
                    //If the previous owner is the parent of this node, it does not enter here since it means it just split:
                    //Later, a bool could be used to know when we want to dinamically update the tree:
                    while (prevOwner.parent != null && !ReferenceEquals(this.parent, prevOwner))                     //if (prevOwner.parent != null && !ReferenceEquals(this.parent, prevOwner))**##
                    {
                        //We get the parent node of the previous owner, which might get terminated:
                        octreeNode        prevOwnerParent  = prevOwner.parent;
                        List <octreeItem> tempElementsList = new List <octreeItem> ();
                        int totalCount = 0;
                        for (int i = 0; i < 8; i++)
                        {
                            octreeNode child = prevOwnerParent.children [i];
                            totalCount += child.nodeElements.Count;
                            tempElementsList.AddRange(child.nodeElements);
                        }

                        //Here, the prevOwnerParent destroy his children:
                        if (totalCount <= maxNumberOfElements)
                        {
                            for (int i = 0; i < 8; i++)
                            {
                                GameObject.Destroy(prevOwnerParent.children [i].obj);
                                prevOwnerParent.children [i] = null;
                            }

                            //Every item which pointed to these destroyed child nodes must now point to their parent (new owner):
                            for (int i = 0; i < tempElementsList.Count; i++)
                            {
                                tempElementsList [i].ownerNodes [0] = prevOwnerParent;
                                prevOwnerParent.nodeElements.Add(tempElementsList[i]);
                            }
                        }

                        //Now, we should set up the params for the next iteration:
                        prevOwner = prevOwnerParent;                         //Only when using the while()-**##
                    }
                }
            }
            //If the item doesn't have an owner, he must be entering the octree for the first time:
            else
            {
                item.ownerNodes.Add(this);
                this.nodeElements.Add(item);
            }
        }

        //If after adding the element the node is overloaded, it has to split and then empty his list:
        if (nodeElements.Count > maxNumberOfElements)
        {
            if (split())
            {
                nodeElements.Clear();
            }
        }
    }