//移除
 public static bool RemoveLeaf(QuadtreeData <GameObject> .Leaf leaf)
 {
     if (_quadtreeObject != null)
     {
         return(_quadtreeObject._quadtree.RemoveLeaf(leaf));
     }
     return(false);
 }
 T[] GetCollisionObjectsFromAChild(Vector2 checkPoint, float checkRadius, QuadtreeData <T> child)
 {
     if (child._field.PointToFieldDistance(checkPoint) <= _maxRadius + checkRadius)      //这里不光要考虑到检测半径,还要考虑到节点最大半径
     {
         return(child.DoCheckCollision(checkPoint, checkRadius));
     }
     return(new T[] { });
 }
 public static GameObject[] CheckCollision(QuadtreeData <GameObject> .Leaf leaf)
 {
     if (_quadtreeObject != null)
     {
         return(quadtreeObject._quadtree.CheckCollision(leaf));
     }
     return(new GameObject[0]);
 }
 void UpdateRoot(QuadtreeData <T> root)
 {
     _root = root;
     if (!DontHaveChildren())
     {
         _upperRightChild.UpdateRoot(root);
         _lowerRightChild.UpdateRoot(root);
         _lowerLeftChild.UpdateRoot(root);
         _upperLeftChild.UpdateRoot(root);
     }
 }
        public QuadtreeData(float top, float right, float bottom, float left, int maxLeafNumber, float minSideLength, QuadtreeData <T> root = null, QuadtreeData <T> parent = null)
        {
            _field = new Field(top, right, bottom, left);

            _maxLeafsNumber = maxLeafNumber;
            _minSideLength  = minSideLength;

            _root = root != null ? root : this;

            _parent = parent;
        }
        void Split()
        {
            DoUpdate();

            float xCenter = (_field.left + _field.right) / 2;
            float yCenter = (_field.bottom + _field.top) / 2;

            _upperRightChild = new QuadtreeData <T>(_field.top, _field.right, yCenter, xCenter, _maxLeafsNumber, _minSideLength, _root, this);
            _lowerRightChild = new QuadtreeData <T>(yCenter, _field.right, _field.bottom, xCenter, _maxLeafsNumber, _minSideLength, _root, this);
            _lowerLeftChild  = new QuadtreeData <T>(yCenter, xCenter, _field.bottom, _field.left, _maxLeafsNumber, _minSideLength, _root, this);
            _upperLeftChild  = new QuadtreeData <T>(_field.top, xCenter, yCenter, _field.left, _maxLeafsNumber, _minSideLength, _root, this);

            foreach (Leaf leaf in _leafs)
            {
                SetLeafToChildren(leaf);
            }
            _leafs = null;
        }
 //存入
 public static void SetLeaf(QuadtreeData <GameObject> .Leaf leaf)
 {
     quadtreeObject._quadtree.SetLeaf(leaf);
 }
        //向上生长
        void UpwardGrouth(Vector2 leafPosition)
        {
            /*
             *  先要明确什么情况下向哪个方向生长
             *
             *  以原范围中心点为基准点
             *  如果叶子在基准点左,向左生长,如果在基准点位置或右边,向右生长
             *  如果叶子在基准点下方,向下生长,如果在基准点位置或上方,向上生长
             */

            Vector2 growthDirection = leafPosition - _field.center;     //方向,正数是上和右

            float newTop     = growthDirection.y >= 0 ? _field.top + _field.height : _field.top;
            float newRight   = growthDirection.x >= 0 ? _field.right + _field.width : _field.right;
            float newBottom  = growthDirection.y >= 0 ? _field.bottom : _field.bottom - _field.height;
            float newLeft    = growthDirection.x >= 0 ? _field.left : _field.left - _field.width;
            float newXCenter = growthDirection.x >= 0 ? _field.right : _field.left;
            float newYCenter = growthDirection.y >= 0 ? _field.top : _field.bottom;

            QuadtreeData <T> newRoot = new QuadtreeData <T>(newTop, newRight, newBottom, newLeft, _maxLeafsNumber, _minSideLength);      //新根节点

            //右上节点,需要存入的情况是向左下方生长,即 x < 0 && y < 0
            if (growthDirection.x >= 0 || growthDirection.y >= 0)       //只要不满足向左下方生长的条件就用创建
            {
                newRoot._upperRightChild = new QuadtreeData <T>(newTop, newRight, newYCenter, newXCenter, _maxLeafsNumber, _minSideLength, newRoot, newRoot);
            }
            else
            {
                newRoot._upperRightChild = this;
            }

            //右下节点,需要存入的情况是向左上方生长,即 x <0 && y >= 0
            if (growthDirection.x >= 0 || growthDirection.y < 0)
            {
                newRoot._lowerRightChild = new QuadtreeData <T>(newYCenter, newRight, newBottom, newXCenter, _maxLeafsNumber, _minSideLength, newRoot, newRoot);
            }
            else
            {
                newRoot._lowerRightChild = this;
            }

            //左下节点,需要存入的情况是向右上方生长,即 x >= 0 && y >= 0
            if (growthDirection.x < 0 || growthDirection.y < 0)
            {
                newRoot._lowerLeftChild = new QuadtreeData <T>(newYCenter, newXCenter, newBottom, newLeft, _maxLeafsNumber, _minSideLength, newRoot, newRoot);
            }
            else
            {
                newRoot._lowerLeftChild = this;
            }

            //左上节点,需要存入的情况是向右下方生长,即 x >= 0 && y < 0
            if (growthDirection.x < 0 || growthDirection.y >= 0)
            {
                newRoot._upperLeftChild = new QuadtreeData <T>(newTop, newXCenter, newYCenter, newLeft, _maxLeafsNumber, _minSideLength, newRoot, newRoot);
            }
            else
            {
                newRoot._upperLeftChild = this;
            }

            _parent = newRoot;              //因为每次向上生长都是由现在的根节点调用的,新的根节点生长完成后旧的根节点的父节点就是新的根节点
            newRoot.UpdateRoot(newRoot);
        }
        //初始化
        private void Awake()
        {
            QuadtreeSetting setting = Resources.Load <QuadtreeSetting>("QuadtreeSetting");

            _quadtree = new QuadtreeData <GameObject>(setting.startTop, setting.startRight, setting.startBottom, setting.startLeft, setting.maxLeafsNumber, setting.minSideLength);
        }
 private void Awake()
 {
     _transform = transform;
     _leaf      = new QuadtreeData <GameObject> .Leaf(gameObject, GetLeafPosition(), _radius);
 }