public QuadNode FindUnit(IQuadNodeReferring unit) { if (IsLeaf()) { if (mUnits.Contains(unit)) return this; return null; } // No leaf if (unit.Position.X < mArea.mX + mArea.mWidth / 2) { if (unit.Position.Y < mArea.mY + mArea.mHeight / 2) { return mChild[Orientation.LeftUpper].FindUnit(unit); } /*else*/ { return mChild[Orientation.LeftLower].FindUnit(unit); } } /*else*/ { if (unit.Position.Y < mArea.mY + mArea.mHeight / 2) { return mChild[Orientation.RightUpper].FindUnit(unit); } /*else*/ { return mChild[Orientation.RightLower].FindUnit(unit); } } }
public static QuadNode GetQuadNode(Type type, IQuadNodeReferring unit) { if (type == typeof(CollisionManager)) { return ((ICollidable)unit).GetQuadNodeForCollision(); } if (type == typeof(PlayerFogManager)) { return ((IVisible)unit).GetQuadNodeForPlayerVisibility(); } if (type == typeof(PcFogManager)) { return ((IVisible)unit).GetQuadNodeForPcVisibility(); } throw new Exception("Unknown QuadNode user!"); }
public static void SetQuadNode(Type type, IQuadNodeReferring unit, QuadNode newNode) { if (type == typeof(CollisionManager)) { ((ICollidable)unit).SetQuadNodeForCollision(newNode); } else if (type == typeof(PlayerFogManager)) { ((IVisible)unit).SetQuadNodeForPlayerVisibility(newNode); } else if (type == typeof(PcFogManager)) { ((IVisible)unit).SetQuadNodeForPcVisibility(newNode); } else { throw new Exception("Unknown QuadNode user!"); } }
/// <summary> /// Called by the Position-setter in GameObject.cs /// If the given unit has moved, it may be that it now belongs to /// another quadNode. This method checks that and changes stuff if necessary. /// </summary> /// <param name="unit"></param> public void UpdateUnitPosition(IQuadNodeReferring unit) { QuadNode oldNode = unit.GetQuadNode(mType); if (!oldNode.mArea.Contains(unit.Position)) { oldNode.RemoveUnit(unit); Debug.Assert(unit.GetQuadNode(mType) == null); Root.ReArrangeUnit(unit); } }
/// <summary> /// Removes a unit from quadnode management. /// </summary> /// <param name="unit"></param> public void UnregisterUnit(IQuadNodeReferring unit) { if (unit.GetQuadNode(mType) != null) unit.GetQuadNode(mType).RemoveUnit(unit); }
/// <summary> /// Freshly registers a unit in the quadnode management. /// </summary> /// <param name="unit"></param> public void RegisterUnit(IQuadNodeReferring unit) { Root.AddUnit(unit); }
public void AddUnit(IQuadNodeReferring unit) { ReArrangeUnit(unit); }
public void RemoveUnit(IQuadNodeReferring unit) { Debug.Assert(mUnits.Contains(unit)); Debug.Assert(IsLeaf()); mUnits.Remove(unit); unit.SetQuadNode(mType, null); Debug.Assert(mManager.FilledLeaves.Contains(this)); if (mUnits.Count == 0) mManager.FilledLeaves.Remove(this); if (!IsRoot() && mParent.CanUnite()) mParent.Unite(); }
/// <summary> /// Note: Does not delete the unit from source node! /// Will sink a unit down into a leaf. /// </summary> /// <param name="unit"></param> public void ReArrangeUnit(IQuadNodeReferring unit) { if (IsLeaf()) { mUnits.Add(unit); Debug.Assert(unit.GetQuadNode(mType) == null); unit.SetQuadNode(mType, this); if (mUnits.Count > 0 && !mManager.FilledLeaves.Contains(this)) { mManager.FilledLeaves.Add(this); } if (CanBeDivided()) Subdivide(); } else { // No leaf if (unit.Position.X < mArea.mX + mArea.mWidth / 2) { if (unit.Position.Y < mArea.mY + mArea.mHeight / 2) { mChild[Orientation.LeftUpper].ReArrangeUnit(unit); } else { mChild[Orientation.LeftLower].ReArrangeUnit(unit); } } else { if (unit.Position.Y < mArea.mY + mArea.mHeight / 2) { mChild[Orientation.RightUpper].ReArrangeUnit(unit); } else { mChild[Orientation.RightLower].ReArrangeUnit(unit); } } } }