public void InsertObject(IQuadObject in_obj) { if (_objs_ht.ContainsKey(in_obj.GetId())) { Debug.LogError(string.Format("Object with ID = {0} already exists", in_obj.GetId())); return; } CQuadLeaf current_quad = _initial_quad; int comparator = 1; RectInt object_sides = GetObjectSidesOnQuadMap(in_obj.GetAABB()); for (int i = _tree_depth; i > 0; i--) { int k = comparator << i - 1; int x = (k & object_sides.xMin) > 0 ? 1 : 0; int y = (k & object_sides.yMax) > 0 ? 1 : 0; if (x > 0 != (k & object_sides.xMax) > 0 || y > 0 != (k & object_sides.yMin) > 0) { break; } int index = (y << 1) + x; current_quad = current_quad.GetQuadOrCreateNewIfNonExist(index); } CObj obj = new CObj(in_obj, new AABB2D(object_sides.xMin, object_sides.yMax, object_sides.xMax, object_sides.yMin), current_quad); current_quad.AddObject(obj); _objs_ht.Add(in_obj.GetId(), obj); }
/// <summary> /// 更新指定的对象(一般情况下,由于对象发生了位置变化造成AABB变化后需要更新) /// </summary> /// <param name="quadObject"></param> public void UpdateObject(IQuadObject quadObject) { if (m_ObjectToNodeDic.TryGetValue(quadObject, out var node)) { RemoveObjectFromNode(node, quadObject); QuadNode targetNode = node; while (targetNode != null) { if (targetNode.Bounds.Contains(quadObject.Bounds)) { break; } targetNode = targetNode.ParentNode; } if (targetNode != null) { targetNode = InsertObjectToNode(targetNode, quadObject); if (targetNode != node) { MergeNode(node); } } else { CoreLogger.Error(QuadTree.LOG_TAG, "the object hasn't been added to tree"); } } else { CoreLogger.Error(QuadTree.LOG_TAG, "the object hasn't been added to tree"); } }
private QuadNode InsertObjectToNode(QuadNode node, IQuadObject quadObject) { if (!node.Bounds.Contains(quadObject.Bounds)) { CoreLogger.Error(LOG_TAG, "QuadTree::InsertObjectToNode->Object's bounds is not fit within node bounds"); return(null); } if (node.IsLeaf && node.Depth < m_MaxDepth && node.ObjectCount >= m_NodeSplitThreshold) { SplitNode(node); ResetNodeObjects(node); } if (!node.IsLeaf) { QuadNode[] childNodes = node.ChildNodes; foreach (var childNode in childNodes) { if (childNode.Bounds.Contains(quadObject.Bounds)) { return(InsertObjectToNode(childNode, quadObject)); } } } node.InsertObject(quadObject); m_ObjectToNodeDic[quadObject] = node; return(node); }
/// <summary> /// 向树中插入对象 /// </summary> /// <param name="quadObject"></param> public void InsertObject(IQuadObject quadObject) { if (quadObject.IsBoundsChangeable) { quadObject.OnBoundsChanged += OnHandleObjectBoundsChanged; } InsertObjectToNode(Root, quadObject); }
internal bool TryInsertObject(IQuadObject obj) { if (Bounds.Contains(obj.Bounds)) { InsideObjects.Add(obj); return(true); } return(false); }
public void GetSelectedObjects(Vector3 in_mouse_point, List <IQuadObject> out_selected_objects) { foreach (CObj obj in _objects) { IQuadObject unit = obj.GetQuadObject(); if (unit.GetAABB().Contains(in_mouse_point)) { out_selected_objects.Add(unit); } } }
public void ChangeTreeOnMove(Bounds in_old_object_aabb, IQuadObject in_new_pos_object) { RectInt old_pos_box_sides = GetObjectSidesOnQuadMap(in_old_object_aabb); RectInt new_pos_box_sides = GetObjectSidesOnQuadMap(in_new_pos_object.GetAABB()); if (old_pos_box_sides.EqualSides(new_pos_box_sides)) { return; } DeleteObjectByID(in_new_pos_object.GetId()); InsertObject(in_new_pos_object); }
/// <summary> /// 删除指定的对象 /// </summary> /// <param name="quadObject"></param> public void RemoveObject(IQuadObject quadObject) { if (m_ObjectToNodeDic.TryGetValue(quadObject, out var node)) { if (quadObject.IsBoundsChangeable) { quadObject.OnBoundsChanged -= OnHandleObjectBoundsChanged; } RemoveObjectFromNode(node, quadObject); MergeNode(node); } }
internal void RemoveObject(IQuadObject obj) { InsideObjects.Remove(obj); }
internal void InsertObject(IQuadObject obj) { InsideObjects.Add(obj); }
public CObj(IQuadObject in_quad_obj, AABB2D in_box2D, CQuadLeaf in_leaf) { _quad_obj = in_quad_obj; _box2D = in_box2D; _leaf = in_leaf; }
private void RemoveObjectFromNode(QuadNode node, IQuadObject quadObject) { m_ObjectToNodeDic.Remove(quadObject); node.RemoveObject(quadObject); }
private void OnHandleObjectBoundsChanged(IQuadObject quadObject, AABB2D oldBounds, AABB2D newBounds) { UpdateObject(quadObject); }