Beispiel #1
0
        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
        }
Beispiel #2
0
 /// <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();
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 /// <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();
 }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        /// <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);
        }
Beispiel #11
0
        public void Recycle()
        {
            if (Entity != null)
            {
                Entity.Recycle();
                Entity = null;
            }

            Left  = null;
            Right = null;
            Top   = null;
            Down  = null;

            AoiPool.Instance.Recycle(this);
        }