//find list of objects near/adjacent to current object public List <GridObjectInterface> checkNeighbouringBlocks(GridObjectInterface obj) { List <GridObjectInterface> neighbours = new List <GridObjectInterface>(); Vector3 gridBlock; int gridX, gridY, gridZ; //loop though adjacent blocks containing objects to test for potential collisions for (int i = 0; i < obj.getCapacity(); i++) { gridBlock = obj.getLocation(i); gridX = (int)(gridBlock.X); gridY = (int)(gridBlock.Y); gridZ = (int)(gridBlock.Z); //check all 8 blocks surrounding object (as well as block object is in) for nearby objects for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { for (int z = -1; z < 2; z++) { checkForDuplicates(neighbours, obj, gridX + x, gridY + y, gridZ + z); } } } } return(neighbours); }
//clear pointers to grid and remove object from grid public void deregisterObject(GridObjectInterface obj) { for (int i = 0; i < obj.getCapacity(); i++) { Vector3 gridBlock = obj.getLocation(i); grid[(int)Math.Round(gridBlock.X), (int)Math.Round(gridBlock.Y), (int)Math.Round(gridBlock.Z)].Remove(obj); } obj.removeAllLocations(); }
//find list of objects near/adjacent to current object public List<GridObjectInterface> checkNeighbouringBlocks(GridObjectInterface obj) { List<GridObjectInterface> neighbours = new List<GridObjectInterface>(); Vector3 gridBlock; int gridX, gridY, gridZ; //loop though adjacent blocks containing objects to test for potential collisions for (int i = 0; i < obj.getCapacity(); i++) { gridBlock = obj.getLocation(i); gridX = (int)(gridBlock.X); gridY = (int)(gridBlock.Y); gridZ = (int)(gridBlock.Z); //check all 8 blocks surrounding object (as well as block object is in) for nearby objects for (int x = -1; x < 2; x++) for (int y = -1; y < 2; y++) for (int z = -1; z < 2; z++) checkForDuplicates(neighbours, obj, gridX + x, gridY + y, gridZ + z); } return neighbours; }
//insert object into grid and update pointers to grid-blocks public void registerObject(GridObjectInterface obj) { Boolean hasMoved = false; //get the width/diameter of object in terms of grid blocks int objectWidth = (int)Math.Ceiling(((obj.getBoundingSphere().Radius * 2) / GRID_BLOCK_SIZE)); Vector3 oldPos = new Vector3(); if (obj is Objects.DynamicObject) { oldPos = ((Objects.DynamicObject)obj).getPreviousPosition; } //convert position coords to grid coords int objX_prev = (int)Math.Round((double)((oldPos.X) / GRID_BLOCK_SIZE)) + grid_offset; int objY_prev = (int)Math.Round((double)((oldPos.Y) / GRID_BLOCK_SIZE)) + grid_offset; int objZ_prev = (int)Math.Round((double)((oldPos.Z) / GRID_BLOCK_SIZE)) + grid_offset; //get object's present coords int texX, texY, texZ; texX = (int)obj.Position.X; texY = (int)obj.Position.Y; texZ = (int)obj.Position.Z; //convert position coords to grid coords int objX = (int)Math.Round((double)(texX / GRID_BLOCK_SIZE)) + grid_offset; int objY = (int)Math.Round((double)(texY / GRID_BLOCK_SIZE)) + grid_offset; int objZ = (int)Math.Round((double)(texZ / GRID_BLOCK_SIZE)) + grid_offset; //check if object has moved out of grid block if (obj.getCapacity() == 0) { hasMoved = true; } else if (((objX + objectWidth / 2) < (objX_prev + objectWidth / 2)) || ((objX - objectWidth / 2) > (objX_prev - objectWidth / 2))) { hasMoved = false; } else if (((objY + objectWidth / 2) < (objY_prev + objectWidth / 2)) || ((objY + objectWidth / 2) > (objY_prev + objectWidth / 2))) { hasMoved = false; } else if (((objZ + objectWidth / 2) < (objZ_prev + objectWidth / 2)) || ((objZ + objectWidth / 2) > (objZ_prev + objectWidth / 2))) { hasMoved = false; } else { hasMoved = true; } hasMoved = true; if (hasMoved) { //remove object from grid first, if its already registered deregisterObject(obj); //register object in grid blocks for (int x = 0; x < objectWidth; x++) { for (int y = 0; y < objectWidth; y++) { for (int z = 0; z < objectWidth; z++) { //convert objects coords to grid coords objX = (int)Math.Round((double)((texX - x * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; objY = (int)Math.Round((double)((texY - y * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; objZ = (int)Math.Round((double)((texZ - z * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; //check that the object is still within the confines of the grid if ((objX >= 0) && (objX < grid.GetLength(0)) && (objY >= 0) && (objY < grid.GetLength(1)) && (objZ >= 0) && (objZ < grid.GetLength(2))) { grid[objX, objY, objZ].Add(obj); obj.setNewLocation(new Vector3(objX, objY, objZ)); } } } } } }
//insert object into grid and update pointers to grid-blocks public void registerObject(GridObjectInterface obj) { Boolean hasMoved = false; //get the width/diameter of object in terms of grid blocks int objectWidth = (int)Math.Ceiling(((obj.getBoundingSphere().Radius * 2) / GRID_BLOCK_SIZE)); Vector3 oldPos = new Vector3(); if(obj is Objects.DynamicObject) oldPos = ((Objects.DynamicObject)obj).getPreviousPosition; //convert position coords to grid coords int objX_prev = (int)Math.Round((double)((oldPos.X) / GRID_BLOCK_SIZE)) + grid_offset; int objY_prev = (int)Math.Round((double)((oldPos.Y) / GRID_BLOCK_SIZE)) + grid_offset; int objZ_prev = (int)Math.Round((double)((oldPos.Z) / GRID_BLOCK_SIZE)) + grid_offset; //get object's present coords int texX, texY, texZ; texX = (int)obj.Position.X; texY = (int)obj.Position.Y; texZ = (int)obj.Position.Z; //convert position coords to grid coords int objX = (int)Math.Round((double)(texX / GRID_BLOCK_SIZE)) + grid_offset; int objY = (int)Math.Round((double)(texY / GRID_BLOCK_SIZE)) + grid_offset; int objZ = (int)Math.Round((double)(texZ / GRID_BLOCK_SIZE)) + grid_offset; //check if object has moved out of grid block if (obj.getCapacity() == 0) hasMoved = true; else if (((objX + objectWidth / 2) < (objX_prev + objectWidth / 2)) || ((objX - objectWidth / 2) > (objX_prev - objectWidth / 2))) { hasMoved = false; } else if (((objY + objectWidth / 2) < (objY_prev + objectWidth / 2)) || ((objY + objectWidth / 2) > (objY_prev + objectWidth / 2))) { hasMoved = false; } else if (((objZ + objectWidth / 2) < (objZ_prev + objectWidth / 2)) || ((objZ + objectWidth / 2) > (objZ_prev + objectWidth / 2))) { hasMoved = false; } else hasMoved = true; hasMoved = true; if (hasMoved) { //remove object from grid first, if its already registered deregisterObject(obj); //register object in grid blocks for (int x = 0; x < objectWidth; x++) for (int y = 0; y < objectWidth; y++) for (int z = 0; z < objectWidth; z++) { //convert objects coords to grid coords objX = (int)Math.Round((double)((texX - x * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; objY = (int)Math.Round((double)((texY - y * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; objZ = (int)Math.Round((double)((texZ - z * GRID_BLOCK_SIZE) / GRID_BLOCK_SIZE)) + grid_offset; //check that the object is still within the confines of the grid if ((objX >= 0) && (objX < grid.GetLength(0)) && (objY >= 0) && (objY < grid.GetLength(1)) && (objZ >= 0) && (objZ < grid.GetLength(2))) { grid[objX, objY, objZ].Add(obj); obj.setNewLocation(new Vector3(objX, objY, objZ)); } } } }