dminer fixes

This commit is contained in:
Vadim Lopatin 2016-04-27 11:57:39 +03:00
parent 38899267f1
commit 84895abfb2
2 changed files with 60 additions and 7 deletions

View File

@ -125,22 +125,43 @@ struct SmallChunk {
protected ulong[8] canPassPlanesZ; // 64 bytes protected ulong[8] canPassPlanesZ; // 64 bytes
//ulong[6][6] canPassFromTo; // 288 bytes //ulong[6][6] canPassFromTo; // 288 bytes
SmallChunk * [6] nearChunks; SmallChunk * [6] nearChunks;
protected Vector3d pos; protected Vector3d _pos;
private Mesh _minerMesh; private Mesh _minerMesh;
protected bool dirty; protected bool dirty;
protected bool dirtyMesh; protected bool dirtyMesh;
protected bool empty; protected bool empty;
protected bool visible;
protected bool dirtyVisible;
static SmallChunk * alloc(int x, int y, int z) nothrow @nogc { static SmallChunk * alloc(int x, int y, int z) nothrow @nogc {
import core.stdc.stdlib : malloc; import core.stdc.stdlib : malloc;
SmallChunk * res = cast(SmallChunk *)malloc(SmallChunk.sizeof); SmallChunk * res = cast(SmallChunk *)malloc(SmallChunk.sizeof);
*res = SmallChunk.init; *res = SmallChunk.init;
res.pos.x = x & (~7); res._pos.x = x & (~7);
res.pos.y = y & (~7); res._pos.y = y & (~7);
res.pos.z = z & (~7); res._pos.z = z & (~7);
return res; return res;
} }
/// return chunk position in world (aligned to chunk origin)
@property ref const(Vector3d) position() {
return _pos;
}
/// returns true if chunk contains any visible faces
@property bool hasVisibleFaces() {
if (dirty)
generateMasks();
if (dirtyVisible) {
dirtyVisible = false;
ubyte[64] visibleFaceFlags;
visible = findVisibleFaces(visibleFaceFlags) > 0;
}
return visible;
}
void release() { void release() {
if (!(&this)) if (!(&this))
return; return;
@ -211,7 +232,7 @@ struct SmallChunk {
for (int x = 0; x < 8; x++) { for (int x = 0; x < 8; x++) {
int visibleFaces = visibleFaceFlags[index]; int visibleFaces = visibleFaceFlags[index];
if (visibleFaces) { if (visibleFaces) {
visitor.visit(world, world.camPosition, Vector3d(pos.x + x, pos.y + y, pos.z + z), cells[index], visibleFaces); visitor.visit(world, world.camPosition, Vector3d(_pos.x + x, _pos.y + y, _pos.z + z), cells[index], visibleFaces);
} }
index++; index++;
} }
@ -240,7 +261,7 @@ struct SmallChunk {
int visibleFaces = visibleFaceFlags[index]; int visibleFaces = visibleFaceFlags[index];
if (visibleFaces) { if (visibleFaces) {
BlockDef def = BLOCK_DEFS[cells[index]]; BlockDef def = BLOCK_DEFS[cells[index]];
def.createFaces(world, world.camPosition, Vector3d(pos.x + x, pos.y + y, pos.z + z), visibleFaces, _minerMesh); def.createFaces(world, world.camPosition, Vector3d(_pos.x + x, _pos.y + y, _pos.z + z), visibleFaces, _minerMesh);
} }
index++; index++;
} }
@ -252,7 +273,8 @@ struct SmallChunk {
return _minerMesh; return _minerMesh;
} }
private void findVisibleFaces(ref ubyte[64] visibleFaceFlags) { private int findVisibleFaces(ref ubyte[64] visibleFaceFlags) {
int count = 0;
ulong[8] visibleFacesNorth; ulong[8] visibleFacesNorth;
ulong canPass = getSideCanPassFromMask(Dir.NORTH); ulong canPass = getSideCanPassFromMask(Dir.NORTH);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
@ -313,12 +335,15 @@ struct SmallChunk {
if (visibleFacesDown[y] & yplanemask) if (visibleFacesDown[y] & yplanemask)
visibleFaces |= DirMask.MASK_DOWN; visibleFaces |= DirMask.MASK_DOWN;
visibleFaceFlags[calcIndex(x, y, z)] = cast(ubyte)visibleFaces; visibleFaceFlags[calcIndex(x, y, z)] = cast(ubyte)visibleFaces;
if (visibleFaces)
count++;
//if (visibleFaces) { //if (visibleFaces) {
// visitor.visit(pos.x + x, pos.y + y, pos.z + z, getCell(x, y, z), visibleFaces); // visitor.visit(pos.x + x, pos.y + y, pos.z + z, getCell(x, y, z), visibleFaces);
//} //}
} }
} }
} }
return count;
} }
private void generateMasks() { private void generateMasks() {
// x planes: z,y // x planes: z,y
@ -395,6 +420,7 @@ struct SmallChunk {
dirty = false; dirty = false;
empty = (visiblePlanesZ[0]|visiblePlanesZ[1]|visiblePlanesZ[2]|visiblePlanesZ[3]| empty = (visiblePlanesZ[0]|visiblePlanesZ[1]|visiblePlanesZ[2]|visiblePlanesZ[3]|
visiblePlanesZ[4]|visiblePlanesZ[5]|visiblePlanesZ[6]|visiblePlanesZ[7]) == 0; visiblePlanesZ[4]|visiblePlanesZ[5]|visiblePlanesZ[6]|visiblePlanesZ[7]) == 0;
dirtyVisible = !empty;
dirtyMesh = true; dirtyMesh = true;
} }

View File

@ -197,6 +197,29 @@ class World {
return top; return top;
} }
private void visitChunk(ChunkVisitor visitor, Vector3d pos) {
SmallChunk * chunk = getCellChunk(pos.x, pos.y, pos.z);
if (chunk && chunk.hasVisibleFaces)
visitor.visit(this, chunk);
}
/// visit visible chunks, starting from specified position
void visitVisibleChunks(ChunkVisitor visitor, Vector3d pos, int maxDistance) {
int chunkDist = (maxDistance + 7) >> 3;
visitChunk(visitor, pos);
for (int dist = 1; dist <= chunkDist; dist++) {
int d = dist << 3;
visitChunk(visitor, Vector3d(pos.x - d, pos.y, pos.z));
visitChunk(visitor, Vector3d(pos.x + d, pos.y, pos.z));
visitChunk(visitor, Vector3d(pos.x, pos.y - d, pos.z));
visitChunk(visitor, Vector3d(pos.x, pos.y + d, pos.z));
visitChunk(visitor, Vector3d(pos.x, pos.y, pos.z - d));
visitChunk(visitor, Vector3d(pos.x, pos.y, pos.z + d));
for (int i = 1; i <= dist; i++) {
}
}
}
private: private:
Position _camPosition; Position _camPosition;
@ -204,6 +227,10 @@ private:
DiamondVisitor visitorHelper; DiamondVisitor visitorHelper;
} }
interface ChunkVisitor {
void visit(World world, SmallChunk * chunk);
}
struct DiamondVisitor { struct DiamondVisitor {
int maxDist; int maxDist;
int maxDistBits; int maxDistBits;