/// <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); }
/// <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; }
/// <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; }
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; }