Exemplo n.º 1
0
    /// <summary>
    /// Grow the octree to fit in all objects.
    /// </summary>
    /// <param name="direction">Direction to grow.</param>
    void Grow(Vector3 direction)
    {
        int xDirection = direction.x >= 0 ? 1 : -1;
        int yDirection = direction.y >= 0 ? 1 : -1;
        int zDirection = direction.z >= 0 ? 1 : -1;
        BoundsOctreeNode <T> oldRoot = rootNode;
        float   half      = rootNode.BaseLength / 2;
        float   newLength = rootNode.BaseLength * 2;
        Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);

        // Create a new, bigger octree root node
        rootNode = new BoundsOctreeNode <T>(newLength, minSize, looseness, newCenter);

        // Create 7 new octree children to go with the old root as children of the new root
        int rootPos = GetRootPosIndex(xDirection, yDirection, zDirection);

        BoundsOctreeNode <T>[] children = new BoundsOctreeNode <T> [8];
        for (int i = 0; i < 8; i++)
        {
            if (i == rootPos)
            {
                children[i] = oldRoot;
            }
            else
            {
                xDirection  = i % 2 == 0 ? -1 : 1;
                yDirection  = i > 3 ? -1 : 1;
                zDirection  = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
                children[i] = new BoundsOctreeNode <T>(rootNode.BaseLength, minSize, looseness, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
            }
        }

        // Attach the new children to the new root node
        rootNode.SetChildren(children);
    }
Exemplo n.º 2
0
    /// <summary>
    /// Grow the octree to fit in all objects.
    /// </summary>
    /// <param name="direction">Direction to grow.</param>
    void Grow(Vector3 direction)
    {
        int xDirection = direction.x >= 0 ? 1 : -1;
        int yDirection = direction.y >= 0 ? 1 : -1;
        int zDirection = direction.z >= 0 ? 1 : -1;
        BoundsOctreeNode <T> oldRoot = rootNode;
        float   half      = rootNode.BaseLength / 2;
        float   newLength = rootNode.BaseLength * 2;
        Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);



        GameObject go = GameObject.Find("Node " + rootNode.GetHashCode().ToString());

        // Create a new, bigger octree root node
        rootNode = new BoundsOctreeNode <T>(newLength, minSize, looseness, newCenter);

        if (go != null)
        {
            go.transform.position   = newCenter;
            go.transform.localScale = Vector3.one * newLength;
            go.name = "Node " + rootNode.GetHashCode();

            Debug.Log("Node: Change scale #" + rootNode.GetHashCode().ToString());
        }
        else
        {
            GameObject newGameObject = GameObject.Instantiate(GameObject.Find("TempNode"), newCenter, Quaternion.identity);
            newGameObject.transform.localScale = Vector3.one * newLength;
            newGameObject.name = "Node " + rootNode.GetHashCode();

            Debug.Log("Node: New game object #" + rootNode.GetHashCode());
        }

        if (oldRoot.HasAnyObjects())
        {
            // Create 7 new octree children to go with the old root as children of the new root
            int rootPos = GetRootPosIndex(xDirection, yDirection, zDirection);
            BoundsOctreeNode <T>[] children = new BoundsOctreeNode <T> [8];
            for (int i = 0; i < 8; i++)
            {
                if (i == rootPos)
                {
                    children[i] = oldRoot;
                }
                else
                {
                    xDirection  = i % 2 == 0 ? -1 : 1;
                    yDirection  = i > 3 ? -1 : 1;
                    zDirection  = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
                    children[i] = new BoundsOctreeNode <T>(rootNode.BaseLength, minSize, looseness, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
                }
            }

            // Attach the new children to the new root node
            rootNode.SetChildren(children);
        }
    }
Exemplo n.º 3
0
 /// <summary>
 /// Constructor for the bounds octree.
 /// </summary>
 /// <param name="initialWorldSize">Size of the sides of the initial node, in metres. The octree will never shrink smaller than this.</param>
 /// <param name="initialWorldPos">Position of the centre of the initial node.</param>
 /// <param name="minNodeSize">Nodes will stop splitting if the new nodes would be smaller than this (metres).</param>
 /// <param name="loosenessVal">Clamped between 1 and 2. Values > 1 let nodes overlap.</param>
 public BoundsOctree(float initialWorldSize, Vector3 initialWorldPos, float minNodeSize, float loosenessVal)
 {
     if (minNodeSize > initialWorldSize)
     {
         Debug.LogWarning("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize);
         minNodeSize = initialWorldSize;
     }
     Count       = 0;
     initialSize = initialWorldSize;
     minSize     = minNodeSize;
     looseness   = Mathf.Clamp(loosenessVal, 1.0f, 2.0f);
     rootNode    = new BoundsOctreeNode <T>(initialSize, minSize, looseness, initialWorldPos);
 }
Exemplo n.º 4
0
    /// <summary>
    /// Splits the octree into eight children.
    /// </summary>
    void Split()
    {
        float quarter   = BaseLength / 4f;
        float newLength = BaseLength / 2;

        children    = new BoundsOctreeNode <T> [8];
        children[0] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter, quarter, -quarter));
        children[1] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter, quarter, -quarter));
        children[2] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter, quarter, quarter));
        children[3] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter, quarter, quarter));
        children[4] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter, -quarter, -quarter));
        children[5] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter, -quarter, -quarter));
        children[6] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter, -quarter, quarter));
        children[7] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter, -quarter, quarter));
    }
Exemplo n.º 5
0
    /// <summary>
    /// Constructor for the bounds octree.
    /// </summary>
    /// <param name="initialWorldSize">Size of the sides of the initial node, in metres. The octree will never shrink smaller than this.</param>
    /// <param name="initialWorldPos">Position of the centre of the initial node.</param>
    /// <param name="minNodeSize">Nodes will stop splitting if the new nodes would be smaller than this (metres).</param>
    /// <param name="loosenessVal">Clamped between 1 and 2. Values > 1 let nodes overlap.</param>
    public BoundsOctree(float initialWorldSize, Vector3 initialWorldPos, float minNodeSize, float loosenessVal)
    {
        if (minNodeSize > initialWorldSize)
        {
            Console.Error.WriteLine("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize +
                                    " Adjusted to: " + initialWorldSize);
            minNodeSize = initialWorldSize;
        }

        Count       = 0;
        initialSize = initialWorldSize;
        minSize     = minNodeSize;
        looseness   = Utils.Clamp(loosenessVal, 1.0f, 2.0f);
        rootNode    = new BoundsOctreeNode <T>(initialSize, minSize, loosenessVal, initialWorldPos);
    }
Exemplo n.º 6
0
    /// <summary>
    /// Splits the octree into eight children.
    /// </summary>
    void Split()
    {
        Vector3 quarter   = BaseSize / 4f;
        Vector3 newLength = BaseSize / 2;

        children    = new BoundsOctreeNode <T> [8];
        children[0] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter.x, quarter.y, -quarter.z));
        children[1] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter.x, quarter.y, -quarter.z));
        children[2] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter.x, quarter.y, quarter.z));
        children[3] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter.x, quarter.y, quarter.z));
        children[4] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter.x, -quarter.y, -quarter.z));
        children[5] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter.x, -quarter.y, -quarter.z));
        children[6] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(-quarter.x, -quarter.y, quarter.z));
        children[7] = new BoundsOctreeNode <T>(newLength, minSize, looseness, Center + new Vector3(quarter.x, -quarter.y, quarter.z));
    }
Exemplo n.º 7
0
 /// <summary>
 /// Merge all children into this node - the opposite of Split.
 /// Note: We only have to check one level down since a merge will never happen if the children already have children,
 /// since THAT won't happen unless there are already too many objects to merge.
 /// </summary>
 void Merge()
 {
     // Note: We know children != null or we wouldn't be merging
     for (int i = 0; i < 8; i++)
     {
         BoundsOctreeNode <T> curChild = children[i];
         int numObjects = curChild.objects.Count;
         for (int j = numObjects - 1; j >= 0; j--)
         {
             OctreeObject curObj = curChild.objects[j];
             objects.Add(curObj);
         }
     }
     // Remove the child nodes (and the objects in them - they've been added elsewhere now)
     children = null;
 }
Exemplo n.º 8
0
    /// <summary>
    /// Grow the octree to fit in all objects.
    /// </summary>
    /// <param name="direction">Direction to grow.</param>
    // 扩展八叉树的范围,原来的范围*2
    // 会创建7个新的节点,同旧的根节点,一个8个节点
    // 作为新的根节点的孩子
    void Grow(Vector3 direction)
    {
        int xDirection = direction.x >= 0 ? 1 : -1;
        int yDirection = direction.y >= 0 ? 1 : -1;
        int zDirection = direction.z >= 0 ? 1 : -1;
        BoundsOctreeNode <T> oldRoot = rootNode;
        float half = rootNode.BaseLength / 2;

        // 新的根节点大小,是原来的2倍
        float newLength = rootNode.BaseLength * 2;
        // 新的根节点的中心坐标
        Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);

        // Create a new, bigger octree root node
        rootNode = new BoundsOctreeNode <T>(newLength, minSize, looseness, newCenter);

        // 创建其他的7个子节点,连同旧的root,是8个子节点
        // 作为新的根节点的孩子
        if (oldRoot.HasAnyObjects())
        {
            // Create 7 new octree children to go with the old root as children of the new root
            int rootPos = rootNode.BestFitChild(oldRoot.Center);
            BoundsOctreeNode <T>[] children = new BoundsOctreeNode <T> [8];
            for (int i = 0; i < 8; i++)
            {
                if (i == rootPos)
                {
                    children[i] = oldRoot;
                }
                else
                {
                    // i = 0, i%2 = 0
                    // i = 1, i%2 = 1
                    xDirection = i % 2 == 0 ? -1 : 1;

                    // 上下2层
                    yDirection  = i > 3 ? -1 : 1;
                    zDirection  = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
                    children[i] = new BoundsOctreeNode <T>(oldRoot.BaseLength, minSize, looseness, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
                }
            }

            // Attach the new children to the new root node
            rootNode.SetChildren(children);
        }
    }
Exemplo n.º 9
0
    /// <summary>
    /// Constructor for the bounds octree.
    /// </summary>
    /// <param name="initialWorldSize">Size of the sides of the initial node, in metres. The octree will never shrink smaller than this.</param>
    /// <param name="initialWorldPos">Position of the centre of the initial node.</param>
    /// <param name="minNodeSize">Nodes will stop splitting if the new nodes would be smaller than this (metres).</param>
    /// <param name="loosenessVal">Clamped between 1 and 2. Values > 1 let nodes overlap.</param>
    public BoundsOctree(float initialWorldSize, Vector3 initialWorldPos, float minNodeSize, float loosenessVal)
    {
        if (minNodeSize > initialWorldSize)
        {
            Debug.LogWarning("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize);
            minNodeSize = initialWorldSize;
        }
        Count       = 0;
        initialSize = initialWorldSize;
        minSize     = minNodeSize;
        looseness   = Mathf.Clamp(loosenessVal, 1.0f, 2.0f);
        rootNode    = new BoundsOctreeNode <T>(initialSize, minSize, loosenessVal, initialWorldPos);


        GameObject newGameObject = GameObject.Instantiate(GameObject.Find("TempNode"), initialWorldPos, Quaternion.identity);

        newGameObject.transform.localScale = Vector3.one * initialSize;
        newGameObject.name = "Node " + rootNode.GetHashCode();

        Debug.Log("Node: New game object #" + rootNode.GetHashCode());
    }
Exemplo n.º 10
0
    /// <summary>
    /// Grow the octree to fit in all objects.
    /// </summary>
    /// <param name="direction">Direction to grow.</param>
    void Grow(Vector3 direction)
    {
        int xDirection = direction.x >= 0 ? 1 : -1;
        int yDirection = direction.y >= 0 ? 1 : -1;
        int zDirection = direction.z >= 0 ? 1 : -1;
        BoundsOctreeNode <T> oldRoot = rootNode;
        Vector3 half      = rootNode.BaseSize / 2;
        Vector3 newLength = rootNode.BaseSize * 2;
        Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half.x, yDirection * half.y, zDirection * half.z);

        // Create a new, bigger octree root node
        rootNode = new BoundsOctreeNode <T>(newLength, minSize, looseness, newCenter);

        if (oldRoot.HasAnyObjects())
        {
            // Create 7 new octree children to go with the old root as children of the new root
            int rootPos = rootNode.BestFitChild(oldRoot.Center);
            BoundsOctreeNode <T>[] children = new BoundsOctreeNode <T> [8];

            for (int i = 0; i < 8; i++)
            {
                if (i == rootPos)
                {
                    children[i] = oldRoot;
                }
                else
                {
                    xDirection = i % 2 == 0 ? -1 : 1;
                    yDirection = i > 3 ? -1 : 1;
                    zDirection = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;

                    children[i] = new BoundsOctreeNode <T>(oldRoot.BaseSize, minSize, looseness,
                                                           newCenter + new Vector3(xDirection * half.x, yDirection * half.y, zDirection * half.z));
                }
            }

            // Attach the new children to the new root node
            rootNode.SetChildren(children);
        }
    }
Exemplo n.º 11
0
 /// <summary>
 /// Shrink the octree if possible, else leave it the same.
 /// </summary>
 void Shrink()
 {
     rootNode = rootNode.ShrinkIfPossible(initialSize);
 }