static void InitiateFloodFill(Cell cell, ref VoxelizationBounds bounds, BufferPool pool, ref CellSet occupiedCells, ref CellSet newlyFilledCells, ref CellList cellsToVisit) { //Check to make sure that this cell isn't already occupied before starting a new fill. if (occupiedCells.Contains(cell)) { return; } cellsToVisit.Add(cell, pool); while (cellsToVisit.Count > 0) { if (cellsToVisit.TryPop(out cell)) { if (!TryFloodFill(cell, ref bounds, pool, ref occupiedCells, ref newlyFilledCells, ref cellsToVisit)) { //The flood fill escaped the voxel bounds. Must be an open area; don't fill. cellsToVisit.Clear(); newlyFilledCells.Clear(); return; } } } //Flood fill completed without reaching the voxel bounds. Dump newly filled cells. for (int i = 0; i < newlyFilledCells.Count; ++i) { occupiedCells.Add(newlyFilledCells[i], pool); } newlyFilledCells.Clear(); }
private static bool TryFloodFill(Cell cell, ref VoxelizationBounds bounds, BufferPool pool, ref CellSet occupiedCells, ref CellSet newlyFilledCells, ref CellList cellsToVisit) { if (cell.X > bounds.X || cell.Y > bounds.Y || cell.Z > bounds.Z || cell.X < -1 || cell.Y < -1 || cell.Z < -1) { //We've escaped the world; the start location was not inside a closed section. Abandon the flood fill. return(false); } if (newlyFilledCells.Contains(cell) || occupiedCells.Contains(cell)) { //We already traversed this cell before or during the current flood fill. return(true); } var cellPool = pool.SpecializeFor <Cell>(); newlyFilledCells.Add(cell, cellPool, pool.SpecializeFor <int>()); cellsToVisit.Add(new Cell { X = cell.X, Y = cell.Y, Z = cell.Z - 1 }, cellPool); cellsToVisit.Add(new Cell { X = cell.X, Y = cell.Y, Z = cell.Z + 1 }, cellPool); cellsToVisit.Add(new Cell { X = cell.X, Y = cell.Y - 1, Z = cell.Z }, cellPool); cellsToVisit.Add(new Cell { X = cell.X, Y = cell.Y + 1, Z = cell.Z }, cellPool); cellsToVisit.Add(new Cell { X = cell.X - 1, Y = cell.Y, Z = cell.Z }, cellPool); cellsToVisit.Add(new Cell { X = cell.X + 1, Y = cell.Y, Z = cell.Z }, cellPool); return(true); }