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; }
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; } }
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>()); } }
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; } }