diff --git a/examples/dminer/src/dminer/core/chunk.d b/examples/dminer/src/dminer/core/chunk.d index 508c22c2..36566d00 100644 --- a/examples/dminer/src/dminer/core/chunk.d +++ b/examples/dminer/src/dminer/core/chunk.d @@ -662,3 +662,4 @@ void testDirMaskToSpreadMask() { } Log.d("Source: \n", generateDirMaskSource()); } + diff --git a/examples/dminer/src/dminer/core/minetypes.d b/examples/dminer/src/dminer/core/minetypes.d index be3fe0e9..e1aff614 100644 --- a/examples/dminer/src/dminer/core/minetypes.d +++ b/examples/dminer/src/dminer/core/minetypes.d @@ -733,3 +733,35 @@ __gshared const Vector3d[6] DIRECTION_VECTORS = [ Vector3d(0, 1, 0), Vector3d(0, -1, 0) ]; + +/// 3d array[+-size, +-size, +-size] of T +struct Array3d(T) { + int _size; + int _sizeBits; + T[] _cells; + void reset(int size) { + if (size == 0) { + // just clear storage + _cells = null; + _size = 0; + _sizeBits = 0; + return; + } + _size = size; + _sizeBits = bitsFor(size) + 1; + int arraySize = 1 << (_sizeBits * 3); + if (_cells.length < arraySize) + _cells.length = arraySize; + foreach(ref cell; _cells) + cell = T.init; + } + ref T opIndex(int x, int y, int z) { + int index = (x + _size) + ((y + _size) << _sizeBits) + ((z + _size) << (_sizeBits + _sizeBits)); + return _cells[index]; + } + T * ptr(int x, int y, int z) { + int index = (x + _size) + ((y + _size) << _sizeBits) + ((z + _size) << (_sizeBits + _sizeBits)); + return &_cells[index]; + } +} + diff --git a/examples/dminer/src/dminer/core/world.d b/examples/dminer/src/dminer/core/world.d index 00f85ea4..bd976d5b 100644 --- a/examples/dminer/src/dminer/core/world.d +++ b/examples/dminer/src/dminer/core/world.d @@ -7,7 +7,7 @@ import dminer.core.chunk; version (Android) { const int MAX_VIEW_DISTANCE_BITS = 6; } else { - const int MAX_VIEW_DISTANCE_BITS = 5; + const int MAX_VIEW_DISTANCE_BITS = 8; } const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS); @@ -489,3 +489,80 @@ struct DiamondVisitor { } } + +struct VisitorCell { + SmallChunk * chunk; + ulong[6] accessible; + bool visited; + int dirFlags; +} + +struct ChunkDiamondVisitor { + World world; + Vector3d pos; + Array3d!VisitorCell cells; + int maxDist; + Vector3dArray oldcells; + Vector3dArray newcells; + void visitCell(VisitorCell * oldCell, int x, int y, int z, Dir direction) { + if (x < -maxDist || x > maxDist || y < -maxDist || y > maxDist || z < -maxDist || z > maxDist) + return; // out of bounds + auto cell = cells.ptr(x, y, z); + if (!cell.visited) { + cell.chunk = world.getCellChunk(pos.x + (x << 3), pos.y + (y << 3), pos.z + (z << 3)); + cell.visited = true; + newcells.append(Vector3d(x, y, z)); + } + cell.dirFlags |= (1 << direction); + } + void visitChunks(World world, Vector3d pos, int distance) { + this.world = world; + this.pos = pos; + this.maxDist = (distance + 7) / 8; + cells.reset(distance); + cells[1,2,3] = VisitorCell.init; + oldcells.clear(); + oldcells.append(Vector3d(0, 0, 0)); + for (int dist = 0; dist < maxDist * 2; dist++) { + if (oldcells.length == 0) + break; + newcells.clear(); + for (int i = 0; i < oldcells.length; i++) { + Vector3d pt = oldcells[i]; + auto oldcell = cells.ptr(pt.x, pt.y, pt.z); + if (pt.x < 0) { + visitCell(oldcell, pt.x - 1, pt.y, pt.z, Dir.WEST); + } else if (pt.x > 0) { + visitCell(oldcell, pt.x + 1, pt.y, pt.z, Dir.EAST); + } else { + visitCell(oldcell, pt.x - 1, pt.y, pt.z, Dir.WEST); + visitCell(oldcell, pt.x + 1, pt.y, pt.z, Dir.EAST); + } + if (pt.y < 0) { + visitCell(oldcell, pt.x, pt.y - 1, pt.z, Dir.DOWN); + } else if (pt.y > 0) { + visitCell(oldcell, pt.x, pt.y + 1, pt.z, Dir.UP); + } else { + visitCell(oldcell, pt.x, pt.y - 1, pt.z, Dir.DOWN); + visitCell(oldcell, pt.x, pt.y + 1, pt.z, Dir.UP); + } + if (pt.z < 0) { + visitCell(oldcell, pt.x, pt.y, pt.z - 1, Dir.WEST); + } else if (pt.z > 0) { + visitCell(oldcell, pt.x, pt.y, pt.z + 1, Dir.EAST); + } else { + visitCell(oldcell, pt.x, pt.y, pt.z - 1, Dir.WEST); + visitCell(oldcell, pt.x, pt.y, pt.z + 1, Dir.EAST); + } + } + newcells.swap(oldcells); + // call visitor for this newly visited cells + for (int i = 0; i < oldcells.length; i++) { + Vector3d pt = oldcells[i]; + auto cell = cells.ptr(pt.x, pt.y, pt.z); + // TODO: call visitor + } + } + } +} +