root/src/BRAINSFramework/Spatial/SpatialTable.cs

User picture

Author: conkerjo

Revision: 30 («Previous)


File Size: 4.56 KB

(July 18, 2009 09:44 UTC) Almost 3 years ago

Missing Files

 
Show/hide line numbers
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Brains.Framework;
using Microsoft.Xna.Framework;

namespace Brains.Spatial
{
    public class SpatialTable
    {
         public Dictionary<int, List<Agent>> Buckets;
        
        public float SceneWidth;
        public float SceneHeight;
        public float CellSize;
        public int Rows;
        public int Cols;

        private List<int> bucketsObjIsIn = new List<int>(4);
        private List<int> tmpIds = new List<int>(4);
        private List<Agent> objects = new List<Agent>();

        public SpatialTable()
        {
        }
        
        //Called on Load
        public void Setup(int scenewidth, int sceneheight, int cellsize)
        {
            Cols= scenewidth / cellsize;
            Rows= sceneheight / cellsize;
            
            Buckets = new Dictionary<int, List<Agent>>();

            SceneWidth = scenewidth;
            SceneHeight = sceneheight;
            CellSize = cellsize;
        }
        
        //Called when the object is created and every frame to update
        internal void RegisterObject(Agent obj)
        {
            
            tmpIds= GetIdForObj(obj);
            for (int i = 0; i < tmpIds.Count; i++)
            {
                if (!Buckets.Keys.Contains(tmpIds[i]))
                    Buckets.Add(tmpIds[i], new List<Agent>());

                ((List<Agent>)Buckets[tmpIds[i]]).Add(obj);
                List<Agent> b = (List<Agent>)Buckets[tmpIds[i]];
            }
        }

        //Called every update
        internal void ClearBuckets()
        {
            foreach (var item in Buckets)
            {
                item.Value.Clear();
            }
        }

        public List<int> GetIdForObj(Agent obj)
        {

            bucketsObjIsIn.Clear();

            Vector2 min = new Vector2(
                obj.Position.X - (obj.Radius),
                obj.Position.Y - (obj.Radius));
            Vector2 max = new Vector2(
                obj.Position.X + (obj.Radius),
                obj.Position.Y + (obj.Radius));

            float width = SceneWidth / CellSize;
            //TopLeft
            AddBucket(min,width,bucketsObjIsIn);
            //TopRight
            AddBucket(new Vector2(max.X, min.Y), width, bucketsObjIsIn);
            //BottomRight
            AddBucket(new Vector2(max.X, max.Y), width, bucketsObjIsIn);
            //BottomLeft
            AddBucket(new Vector2(min.X, max.Y), width, bucketsObjIsIn);

            return bucketsObjIsIn;
        }

        private void AddBucket(Vector2 vector,float width,List<int> buckettoaddto)
        {
            int cellPosition = (int)(
                                    (Math.Floor(vector.X / CellSize)) +
                                    (Math.Floor(vector.Y / CellSize)) *
                                    width
                                  );
            //float conv = 1f / CellSize;
            //int cellPosition = (int)(vector.X * conv + vector.Y * conv * width);
            if(!buckettoaddto.Contains(cellPosition))
                buckettoaddto.Add(cellPosition);
            
        }


        internal List<Agent> GetNearbyItems(Agent agent, int distance)
        {
            Vector2 min = new Vector2(
              agent.Position.X - (agent.Radius),
              agent.Position.Y - (agent.Radius));
            Vector2 max = new Vector2(
                agent.Position.X + (agent.Radius),
                agent.Position.Y + (agent.Radius));
            Vector2 topLeftCell = new Vector2(
                            (int)Math.Floor(min.X / CellSize),
                            (int)Math.Floor(min.Y / CellSize));
            Vector2 bottomRight = new Vector2(
                            (int)Math.Floor(max.X / CellSize),
                            (int)Math.Floor(max.Y / CellSize));
            List<Agent> _agents = new List<Agent>();
            for (int y = (int)topLeftCell.Y; y <= bottomRight.Y; y++)
            {
                for (int x = (int)topLeftCell.X; x <= bottomRight.X; x++)
                {
                    int cellPosition = (int)(
                                    x +
                                    y *
                                    Cols
                                  );
                    if(Buckets.Keys.Contains(cellPosition))
                        _agents.AddRange(this.Buckets[cellPosition]);
                }
            }
            return _agents;
        }
    }
}