private void Find(ref AoiEntity node, ref Vector2 area) { node.ViewEntity.Clear(); #region xLinks for (var i = 0; i < 2; i++) { var cur = i == 0 ? node.X.Right : node.X.Left; while (cur != null) { if (Math.Abs(Math.Abs(cur.Value) - Math.Abs(node.X.Value)) > area.X) { break; } else if (Math.Abs(Math.Abs(cur.Entity.Y.Value) - Math.Abs(node.Y.Value)) <= area.Y) { if (Distance( new Vector2(node.X.Value, node.Y.Value), new Vector2(cur.Entity.X.Value, cur.Entity.Y.Value)) <= area.X) { node.ViewEntity.Add(cur.Entity.Key); } } cur = i == 0 ? cur.Right : cur.Left; } } #endregion #region yLinks for (var i = 0; i < 2; i++) { var cur = i == 0 ? node.Y.Right : node.Y.Left; while (cur != null) { if (Math.Abs(Math.Abs(cur.Value) - Math.Abs(node.Y.Value)) > area.Y) { break; } else if (Math.Abs(Math.Abs(cur.Entity.X.Value) - Math.Abs(node.X.Value)) <= area.X) { if (Distance( new Vector2(node.X.Value, node.Y.Value), new Vector2(cur.Entity.X.Value, cur.Entity.Y.Value)) <= area.X) { node.ViewEntity.Add(cur.Entity.Key); } } cur = i == 0 ? cur.Right : cur.Left; } } #endregion }
/// <summary> /// Exit the AoiZone /// </summary> /// <param name="key"></param> /// <param name="node"></param> public void Exit(AoiEntity node) { _xLinks.Remove(node.X.Value); _yLinks.Remove(node.Y.Value); _entityList.Remove(node.Key); node.Recycle(); }
public bool Remove(float target, out AoiEntity entity) { var cur = _header; entity = null; var seen = false; for (var l = _level; l >= 1; --l) { while (cur.Right != null && cur.Right.Value < target) { cur = cur.Right; } if (cur.Right != null && Math.Abs(cur.Right.Value - target) < Limit) { var temp = cur.Right; entity = temp.Entity; cur.Right = cur.Right.Right; temp.Recycle(); seen = true; } cur = cur.Down; } return(seen); }
/// <summary> /// Exit the AoiZone /// </summary> /// <param name="node"></param> public void Exit(AoiEntity node) { _xLinks.Remove(node.X); _yLinks.Remove(node.Y); _entityList.Remove(node.Key); node.Dispose(); }
/// <summary> /// Add node /// </summary> /// <param name="target">target MinValue = -3.402823E+38f</param> /// <param name="entity"></param> /// <returns></returns> public AoiNode Add(float target, AoiEntity entity = null) { var rLayer = 1; if (_header == null) { rLayer = _maxLayer; var tempHeader = _header = new AoiNode(rLayer, target, entity); for (var layer = _maxLayer - 1; layer >= 1; --layer) { _header = _header.Down = new AoiNode(layer, target, top: _header); } _header = tempHeader; return(null); } while (rLayer < _maxLayer && _random.Next(2) == 0) { ++rLayer; } AoiNode cur = _header, insertNode = null, lastLayerNode = null; for (var layer = _maxLayer; layer >= 1; --layer) { while (cur.Right != null && cur.Right.Value < target) { cur = cur.Right; } if (layer <= rLayer) { insertNode = new AoiNode(layer, target, entity: entity, left: cur, right: cur.Right); if (cur.Right != null) { cur.Right.Left = insertNode; } cur.Right = insertNode; if (lastLayerNode != null) { lastLayerNode.Down = insertNode; insertNode.Top = lastLayerNode; } lastLayerNode = insertNode; } cur = cur.Down; } Count++; return(insertNode); }
/// <summary> /// Exit the AoiZone /// </summary> /// <param name="key"></param> /// <param name="node"></param> public void Exit(long key, AoiEntity node) { float x = node.X.Value, y = node.Y.Value; _xLinks.Remove(x); _yLinks.Remove(y); _entityList.Remove(key); }
public AoiLinkedListNode Add(float target, AoiEntity entity) { var rLevel = 1; var addNewHeader = false; while (rLevel <= _level && _random.Next(2) == 0) { ++rLevel; } if (rLevel > _level) { _level = rLevel; addNewHeader = true; _header = AoiPool.Instance.Fetch <AoiLinkedListNode>().Init(target, entity, null, null, null, _header); } AoiLinkedListNode cur = _header, last = null; for (var l = _level; l >= 1; --l) { while (cur.Right != null && cur.Right.Value < target) { cur = cur.Right; } if (l <= rLevel) { var temp = l == rLevel && addNewHeader ? _header : cur.Right = AoiPool.Instance.Fetch <AoiLinkedListNode>().Init(target, entity, cur, cur.Right, null, null); if (last != null) { last.Down = temp; temp.Top = last; } last = temp; if (l == 1) { cur = temp; break; } } cur = cur.Down; } return(cur); }
public AoiNode Add(float target, AoiEntity entity) { var rLevel = 1; while (rLevel <= _level && _random.Next(2) == 0) { ++rLevel; } if (rLevel > _level) { _level = rLevel; _header = AoiPool.Instance.Fetch <AoiNode>().Init(_level, target, entity, null, null, null, _header); } AoiNode cur = _header, last = null; for (var l = _level; l >= 1; --l) { while (cur.Right != null && cur.Right.Value < target) { cur = cur.Right; } if (l <= rLevel) { cur.Right = AoiPool.Instance.Fetch <AoiNode>().Init(l, target, entity, cur, cur.Right, null, null); if (last != null) { last.Down = cur.Right; cur.Right.Top = last; } last = cur.Right; if (l == 1) { cur = cur.Right; break; } } cur = cur.Down; } Count++; return(cur); }
public AoiLinkedListNode Init( float v, AoiEntity p, AoiLinkedListNode l, AoiLinkedListNode r, AoiLinkedListNode t, AoiLinkedListNode d) { Left = l; Right = r; Top = t; Down = d; Value = v; Entity = p; return(this); }
/// <summary> /// Add a new AoiEntity /// </summary> /// <param name="key">key</param> /// <param name="x">X MinValue = -3.402823E+38f</param> /// <param name="y">Y MinValue = -3.402823E+38f</param> /// <returns></returns> public AoiEntity Enter(long key, float x, float y) { if (_entityList.TryGetValue(key, out var entity)) { return(entity); } entity = new AoiEntity(key); entity.X = _xLinks.Add(x, entity); entity.Y = _yLinks.Add(y, entity); _entityList.Add(key, entity); return(entity); }
public void Recycle() { if (Entity != null) { Entity.Recycle(); Entity = null; } Left = null; Right = null; Top = null; Down = null; AoiPool.Instance.Recycle(this); }