Пример #1
0
    private void Start()
    {
        Rect rect = new Rect();

        rect.min = GameObject.Find("Battleground").GetComponent <MeshRenderer>().bounds.min;
        rect.max = GameObject.Find("Battleground").GetComponent <MeshRenderer>().bounds.max;

        Qtree      = new QuadTreeEternal(rect);
        Qtree.Root = Qtree;

        GameManager.Instance.OnGameRestart += ClearQuadTree;
    }
Пример #2
0
 public QuadTreeEternal(Rect newRect)
 {
     rect       = newRect;
     halfWidth  = rect.width / 2;
     halfHeight = rect.height / 2;
     objects    = new List <CollisionCircle>();
     movedUnits = new List <CollisionCircle>();
     parent     = null;
     childs     = new QuadTreeEternal[4];
     for (int i = 0; i < 4; i++)
     {
         childs[i] = null;
     }
 }
Пример #3
0
    public void Update()
    {
        if (objects.Count == 0)
        {
            //if (parent == null)
            //return;
            if (!hasChilds)
            {
                if (curLife == -1)
                {
                    curLife = maxLifespan;
                }
                else if (curLife > 0)
                {
                    curLife--;
                }
            }
        }
        else
        {
            if (curLife != -1)
            {
                if (maxLifespan <= 64)
                {
                    maxLifespan *= 2;
                }
                curLife = -1;
            }
        }

        movedUnits.Clear();
        movedUnits.AddRange(objects);
        //foreach (ICollidable unit in objects)
        //{
        //	if (unit.Active)
        //		movedUnits.Add(unit);
        //}

        // remove died objects
        int listSize = objects.Count;

        for (int i = 0; i < listSize; i++)
        {
            //if (objects[i].trans == null || objects[i].isDead)
            if (objects[i].IsDead)
            {
                if (movedUnits.Contains(objects[i]))
                {
                    int ind = movedUnits.IndexOf(objects[i]);
                    movedUnits[ind].IsInQt = false;
                    movedUnits.Remove(objects[i]);
                }
                objects[i].IsInQt = false;
                objects.RemoveAt(i--);

                listSize--;
            }
        }

        for (int flags = activeNodes, index = 0; flags > 0; flags >>= 1, index++)
        {
            if ((flags & 1) == 1)
            {
                childs[index].Update();
            }
        }

        for (int i = 0; i < movedUnits.Count; i++)
        {
            QuadTreeEternal currentNode = this;

            while (!RectContainsCircle(rect, movedUnits[i]))
            {
                if (currentNode.parent != null)
                {
                    currentNode = currentNode.parent;
                }
                else
                {
                    break;
                }
            }
            // remove from objects and insert to root in EVERY FRAME
            movedUnits[i].IsInQt = false;
            objects.Remove(movedUnits[i]);

            currentNode.Insert(movedUnits[i]);
        }

        for (int flags = activeNodes, index = 0; flags > 0; flags >>= 1, index++)
        {
            if ((flags & 1) == 1 && childs[index].curLife == 0 && childs[index].objects.Count == 0)
            {
                if (childs[index].objects.Count > 0)
                {
                    Debug.Log(childs[index].objects.Count);
                }
                childs[index] = null;
                activeNodes  ^= (byte)(1 << index);
                if (activeNodes == 0)
                {
                    hasChilds = false;
                }
            }
        }

        //check collisions here
        if (parent == null)
        {
            CheckCollisions(new List <CollisionCircle>());
        }
    }
Пример #4
0
    public void Insert(CollisionCircle obj)
    {
        if (objects.Count < 1 && activeNodes == 0)
        {
            objects.Add(obj);
            obj.IsInQt = true;
            return;
        }

        if (rect.size.x < Vector2.one.x && rect.size.y < Vector2.one.y)
        {
            objects.Add(obj);
            obj.IsInQt = true;
            return;
        }

        Rect[] quadrant = new Rect[4];
        quadrant[0] = (childs[0] != null) ? childs[0].rect : new Rect(rect.x + halfWidth, rect.y, halfWidth, halfHeight);
        quadrant[1] = (childs[1] != null) ? childs[1].rect : new Rect(rect.x, rect.y, halfWidth, halfHeight);
        quadrant[2] = (childs[2] != null) ? childs[2].rect : new Rect(rect.x, rect.y + halfHeight, halfWidth, halfHeight);
        quadrant[3] = (childs[3] != null) ? childs[3].rect : new Rect(rect.x + halfWidth, rect.y + halfHeight, halfWidth, halfHeight);

        if (RectContainsCircle(rect, obj))
        {
            bool found = false;
            for (int i = 0; i < 4; i++)
            {
                if (RectContainsCircle(quadrant[i], obj))
                //if (quadrant[i].Contains(obj.GetPoint()))
                {
                    // using existing child
                    if (childs[i] != null)
                    {
                        childs[i].Insert(obj);
                    }
                    // create new child
                    else
                    {
                        childs[i]        = new QuadTreeEternal(quadrant[i]);
                        childs[i].Root   = Root;
                        childs[i].parent = this;
                        childs[i].level  = level + 1;
                        childs[i].Insert(obj);
                        hasChilds    = true;
                        activeNodes |= (byte)(1 << i);
                    }
                    found = true;
                }
            }
            if (!found)
            {
                objects.Add(obj);
                obj.IsInQt = true;
            }
        }
        else
        {
            // attach object to root if it's outside of battleground boundaries
            //objects.Add(obj);
            obj.IsInQt = false;
        }
    }