DMiner example improvements

This commit is contained in:
Vadim Lopatin 2016-07-27 16:32:55 +03:00
parent f4741bf297
commit ac00749665
3 changed files with 111 additions and 1 deletions

View File

@ -662,3 +662,4 @@ void testDirMaskToSpreadMask() {
} }
Log.d("Source: \n", generateDirMaskSource()); Log.d("Source: \n", generateDirMaskSource());
} }

View File

@ -733,3 +733,35 @@ __gshared const Vector3d[6] DIRECTION_VECTORS = [
Vector3d(0, 1, 0), Vector3d(0, 1, 0),
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];
}
}

View File

@ -7,7 +7,7 @@ import dminer.core.chunk;
version (Android) { version (Android) {
const int MAX_VIEW_DISTANCE_BITS = 6; const int MAX_VIEW_DISTANCE_BITS = 6;
} else { } 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); 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
}
}
}
}