/// <summary>
        /// Computes the grid.
        /// </summary>
        /// <param name="geom">The geometry.</param>
        /// <exception cref="ArgumentNullException"><c>geometry</c> is null.</exception>
        public void CreateDistanceGrid(Geom geom)
        {
            if (geom == null)
            {
                throw new ArgumentNullException("geom", "Geometry can't be null");
            }

            //Don't create distancegrid for geometry that already have one.
            //NOTE: This should be used to -update- the geometry's distance grid (if grid cell size has changed).
            if (_distanceGrids.ContainsKey(geom.id))
            {
                return;
            }

            //By default, calculate the gridcellsize from the AABB
            if (geom.GridCellSize <= 0)
            {
                geom.GridCellSize = CalculateGridCellSizeFromAABB(ref geom.AABB);
            }

            //Prepare the geometry. Reset the geometry matrix
            Matrix old = geom.Matrix;

            geom.Matrix = Matrix.Identity;

            //Create data needed for gridcalculations
            AABB  aabb            = new AABB(ref geom.AABB);
            float gridCellSizeInv = 1 / geom.GridCellSize;

            //Note: Physics2d have +2
            int xSize = (int)Math.Ceiling((double)(aabb.Max.X - aabb.Min.X) * gridCellSizeInv) + 1;
            int ySize = (int)Math.Ceiling((double)(aabb.Max.Y - aabb.Min.Y) * gridCellSizeInv) + 1;

            float[,] nodes = new float[xSize, ySize];
            Vector2 vector = aabb.Min;

            for (int x = 0; x < xSize; ++x, vector.X += geom.GridCellSize)
            {
                vector.Y = aabb.Min.Y;
                for (int y = 0; y < ySize; ++y, vector.Y += geom.GridCellSize)
                {
                    nodes[x, y] = geom.GetNearestDistance(ref vector); // shape.GetDistance(vector);
                }
            }
            //restore the geometry
            geom.Matrix = old;

            DistanceGridData distanceGridData = new DistanceGridData();

            distanceGridData.AABB            = aabb;
            distanceGridData.GridCellSize    = geom.GridCellSize;
            distanceGridData.GridCellSizeInv = gridCellSizeInv;
            distanceGridData.Nodes           = nodes;

            _distanceGrids.Add(geom.id, distanceGridData);
        }
Beispiel #2
0
        /// <summary>
        /// Computes the grid.
        /// </summary>
        /// <param name="geometry">The geometry.</param>
        /// <param name="data"><see cref="ColliderData"/> that contains the size of the grid cell.</param>
        /// <exception cref="ArgumentNullException"><c>geometry</c> is null.</exception>
        public void Prepare(Geom geometry, ColliderData data)
        {
            float gridCellSize = data.GridCellSize;

            if (geometry == null)
            {
                throw new ArgumentNullException("geometry", "Geometry can't be null");
            }

            if (gridCellSize <= 0)
            {
                throw new ArgumentNullException("data", "The grid cell size must be larger than 0");
            }

            //Prepare the geometry.
            Matrix old = geometry.Matrix;

            //Note: Changed in 2.1
            //Matrix identity = Matrix.Identity;
            //geometry.Matrix = identity;
            //to:

            geometry.Matrix = Matrix.Identity;

            //Copy the AABB to the grid field
            _aabb            = new AABB(geometry.AABB);
            _gridCellSize    = gridCellSize;
            _gridCellSizeInv = 1 / gridCellSize;

            //Note: Physics2d have +2
            int xSize = (int)Math.Ceiling((double)(_aabb.Max.X - _aabb.Min.X) * _gridCellSizeInv) + 1;
            int ySize = (int)Math.Ceiling((double)(_aabb.Max.Y - _aabb.Min.Y) * _gridCellSizeInv) + 1;

            _nodes = new float[xSize, ySize];
            Vector2 vector = _aabb.Min;

            for (int x = 0; x < xSize; ++x, vector.X += gridCellSize)
            {
                vector.Y = _aabb.Min.Y;
                for (int y = 0; y < ySize; ++y, vector.Y += gridCellSize)
                {
                    _nodes[x, y] = geometry.GetNearestDistance(vector); // shape.GetDistance(vector);
                }
            }
            //restore the geometry
            geometry.Matrix = old;
        }
Beispiel #3
0
        /// <summary>
        /// Computes the grid.
        /// </summary>
        /// <param name="geometry">The geometry.</param>
        /// <param name="gridCellSize">Size of the grid cell.</param>
        public void ComputeGrid(Geom geometry, float gridCellSize)
        {
            //Prepare the geometry.
            Matrix old = geometry.Matrix;

            //TODO: Assign geometry.Matrix to Matrix.Identity directly
            Matrix identity = Matrix.Identity;

            geometry.Matrix = identity;

            //Copy the AABB to the grid field
            _aabb            = new AABB(geometry.AABB);
            _gridCellSize    = gridCellSize;
            _gridCellSizeInv = 1 / gridCellSize;

            //NOTE: Using double cast instead of converting.
            int xSize = (int)Math.Ceiling((double)(_aabb.Max.X - _aabb.Min.X) * _gridCellSizeInv) + 1;
            int ySize = (int)Math.Ceiling((double)(_aabb.Max.Y - _aabb.Min.Y) * _gridCellSizeInv) + 1;

            //TODO: Possible optimization (normal)! If the shape is symmetric in X and Y axis, don't calculate the points, replicate them.
            _nodes  = new float[xSize, ySize];
            _points = new Vector2[xSize * ySize];
            int     i      = 0;
            Vector2 vector = _aabb.Min;

            for (int x = 0; x < xSize; ++x, vector.X += gridCellSize)
            {
                vector.Y = _aabb.Min.Y;
                for (int y = 0; y < ySize; ++y, vector.Y += gridCellSize)
                {
                    _nodes[x, y] = geometry.GetNearestDistance(vector); // shape.GetDistance(vector);
                    _points[i]   = vector;
                    i           += 1;
                }
            }
            //restore the geometry
            geometry.Matrix = old;
        }
Beispiel #4
0
        public void ComputeGrid(Geom geometry, float gridCellSize)
        {
            //prepare the geometry.
            Matrix old      = geometry.Matrix;
            Matrix identity = Matrix.Identity;

            geometry.Matrix = identity;

            _aabb            = new AABB(geometry.AABB);
            _gridCellSize    = gridCellSize;
            _gridCellSizeInv = 1 / gridCellSize;

            //TODO: Possible optimization (minor)! use casting, use _aabb.Width and Height and check if Height==Width instead of calculating twice.
            int xSize = (int)Math.Ceiling(Convert.ToDouble((_aabb.Max.X - _aabb.Min.X) * _gridCellSizeInv)) + 1;
            int ySize = (int)Math.Ceiling(Convert.ToDouble((_aabb.Max.Y - _aabb.Min.Y) * _gridCellSizeInv)) + 1;

            _nodes  = new float[xSize, ySize];
            _points = new Vector2[xSize * ySize];
            int     i      = 0;
            Vector2 vector = _aabb.Min;

            //TODO: Possible optimization (normal)! Cache the grids for later use. (don't recreate a grid of 64x64 if it's already made)

            //TODO: Possible optimization (normal)! If the shape is symmetric in X and Y axis, don't calculate the points, replicate them.
            for (int x = 0; x < xSize; ++x, vector.X += gridCellSize)
            {
                vector.Y = _aabb.Min.Y;
                for (int y = 0; y < ySize; ++y, vector.Y += gridCellSize)
                {
                    _nodes[x, y] = geometry.GetNearestDistance(vector); // shape.GetDistance(vector);
                    _points[i]   = vector;
                    i           += 1;
                }
            }
            //restore the geometry
            geometry.Matrix = old;
        }