mirror of https://github.com/buggins/dlangui.git
new chunks format
This commit is contained in:
parent
29db6b73a5
commit
e31fd88107
|
@ -209,6 +209,7 @@
|
|||
<Folder name="dminer">
|
||||
<Folder name="core">
|
||||
<File path="src\dminer\core\blocks.d" />
|
||||
<File path="src\dminer\core\chunk.d" />
|
||||
<File path="src\dminer\core\generators.d" />
|
||||
<File path="src\dminer\core\minetypes.d" />
|
||||
<File path="src\dminer\core\terrain.d" />
|
||||
|
|
|
@ -4,6 +4,7 @@ import dminer.core.minetypes;
|
|||
import dminer.core.blocks;
|
||||
import dminer.core.world;
|
||||
import dminer.core.terrain;
|
||||
import dminer.core.chunk;
|
||||
|
||||
|
||||
__gshared static short[] TERRAIN_INIT_DATA = [
|
||||
|
|
|
@ -2,6 +2,7 @@ module dminer.core.world;
|
|||
|
||||
import dminer.core.minetypes;
|
||||
import dminer.core.blocks;
|
||||
import dminer.core.chunk;
|
||||
|
||||
version (Android) {
|
||||
const int MAX_VIEW_DISTANCE_BITS = 6;
|
||||
|
@ -10,17 +11,163 @@ version (Android) {
|
|||
}
|
||||
const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS);
|
||||
|
||||
|
||||
static if (USE_NEW_WORLD_IMPL) {
|
||||
|
||||
class World {
|
||||
|
||||
this() {
|
||||
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||
}
|
||||
~this() {
|
||||
}
|
||||
@property final ref Position camPosition() { return _camPosition; }
|
||||
|
||||
|
||||
protected ChunkStack*[CHUNKS_X * 2 * CHUNKS_Z * 2] _chunkStacks;
|
||||
//pragma(msg, "stack pointers array size, Kb:");
|
||||
//pragma(msg, _chunkStacks.sizeof / 1024);
|
||||
final cell_t getCell(int x, int y, int z) {
|
||||
int chunkx = (x >> 3) + CHUNKS_X;
|
||||
int chunkz = (z >> 3) + CHUNKS_Z;
|
||||
if ((chunkx & (~CHUNKS_X_MASK)) || (chunkz & (~CHUNKS_Z_MASK)))
|
||||
return 0; // out of bounds x,z
|
||||
int index = chunkx + (chunkz << (CHUNKS_BITS_X + 1));
|
||||
if (ChunkStack * stack = _chunkStacks[index]) {
|
||||
int chunkY = (y >> 3);
|
||||
if (SmallChunk * chunk = stack.get(chunkY))
|
||||
return chunk.getCell(x, y, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/// get chunk stack for cell by world cell coordinates x, z
|
||||
ChunkStack * getCellChunkStack(int x, int z) {
|
||||
int chunkx = (x >> 3) + CHUNKS_X;
|
||||
int chunkz = (z >> 3) + CHUNKS_Z;
|
||||
if ((chunkx & (~CHUNKS_X_MASK)) || (chunkz & (~CHUNKS_Z_MASK)))
|
||||
return null; // out of bounds x,z
|
||||
int index = chunkx + (chunkz << (CHUNKS_BITS_X + 1));
|
||||
return _chunkStacks[index];
|
||||
}
|
||||
/// get chunk by chunkx = x / 8 + CHUNKS_X, chunky = y / 8, chunkz = z / 8 + CHUNKS_Z
|
||||
SmallChunk * getChunk(int chunkx, int chunky, int chunkz) {
|
||||
if ((chunkx & (~CHUNKS_X_MASK)) || (chunkz & (~CHUNKS_Z_MASK)))
|
||||
return null; // out of bounds x,z
|
||||
int index = chunkx + (chunkz << (CHUNKS_BITS_X + 1));
|
||||
if (ChunkStack * stack = _chunkStacks[index])
|
||||
return stack.get(chunky);
|
||||
return null;
|
||||
}
|
||||
/// get chunk for cell by world cell coordinates x, y, z
|
||||
SmallChunk * getCellChunk(int x, int y, int z) {
|
||||
int chunkx = (x >> 3) + CHUNKS_X;
|
||||
int chunkz = (z >> 3) + CHUNKS_Z;
|
||||
if ((chunkx & (~CHUNKS_X_MASK)) || (chunkz & (~CHUNKS_Z_MASK)))
|
||||
return null; // out of bounds x,z
|
||||
int index = chunkx + (chunkz << (CHUNKS_BITS_X + 1));
|
||||
int chunky = (y >> 3);
|
||||
if (ChunkStack * stack = _chunkStacks[index])
|
||||
return stack.get(chunky);
|
||||
return null;
|
||||
}
|
||||
final void setCell(int x, int y, int z, cell_t value) {
|
||||
int chunkx = (x >> 3) + CHUNKS_X;
|
||||
int chunkz = (z >> 3) + CHUNKS_Z;
|
||||
if ((chunkx & (~CHUNKS_X_MASK)) || (chunkz & (~CHUNKS_Z_MASK)))
|
||||
return; // out of bounds x,z
|
||||
int index = chunkx + (chunkz << (CHUNKS_BITS_X + 1));
|
||||
ChunkStack * stack = _chunkStacks[index];
|
||||
SmallChunk * chunk;
|
||||
if (stack) {
|
||||
int chunkY = (y >> 3);
|
||||
chunk = stack.get(chunkY);
|
||||
if (chunk)
|
||||
chunk.setCell(x, y, z, value);
|
||||
else {
|
||||
// create chunk
|
||||
if (!value)
|
||||
return; // don't create chunk for 0
|
||||
chunk = SmallChunk.alloc();
|
||||
stack.set(chunkY, chunk);
|
||||
chunk.setCell(x, y, z, value);
|
||||
}
|
||||
} else {
|
||||
if (!value)
|
||||
return; // don't create chunk for 0
|
||||
stack = new ChunkStack();
|
||||
_chunkStacks[index] = stack;
|
||||
int chunkY = (y >> 3);
|
||||
chunk = SmallChunk.alloc();
|
||||
stack.set(chunkY, chunk);
|
||||
chunk.setCell(x, y, z, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setCellRange(Vector3d pos, Vector3d sz, cell_t value) {
|
||||
for (int x = 0; x < sz.x; x++)
|
||||
for (int y = 0; y < sz.y; y++)
|
||||
for (int z = 0; z < sz.z; z++)
|
||||
setCell(pos.x + x, pos.y + y, pos.z + z, value);
|
||||
}
|
||||
|
||||
final bool isOpaque(int x, int y, int z) {
|
||||
cell_t cell = getCell(x, y, z);
|
||||
return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY;
|
||||
}
|
||||
|
||||
bool canPass(Vector3d pos) {
|
||||
return canPass(Vector3d(pos.x - 2, pos.y - 3, pos.z - 2), Vector3d(4, 5, 4));
|
||||
}
|
||||
|
||||
bool canPass(Vector3d pos, Vector3d size) {
|
||||
for (int x = 0; x <= size.x; x++)
|
||||
for (int z = 0; z <= size.z; z++)
|
||||
for (int y = 0; y < size.y; y++) {
|
||||
if (isOpaque(pos.x + x, pos.y + y, pos.z + z))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
final void visitVisibleCells(ref Position position, CellVisitor visitor) {
|
||||
visitorHelper.init(this,
|
||||
&position,
|
||||
visitor);
|
||||
visitorHelper.visitAll(maxVisibleRange);
|
||||
}
|
||||
|
||||
/// get max Y position of non-empty cell in region (x +- size, z +- size)
|
||||
int regionHeight(int x, int z, int size) {
|
||||
int top = -1;
|
||||
int delta = size / 8 + 1;
|
||||
for (int dx = x - delta; dx <= x + delta; dx += 8) {
|
||||
for (int dz = z - delta; dz <= z + delta; dz += 8) {
|
||||
if (ChunkStack * stack = getCellChunkStack(x, z)) {
|
||||
if (top < stack.topNonEmptyY)
|
||||
top = stack.topNonEmptyY;
|
||||
}
|
||||
}
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Position _camPosition;
|
||||
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
||||
DiamondVisitor visitorHelper;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
// Layer is 16x16 (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells
|
||||
immutable int CHUNK_DX_SHIFT = 4;
|
||||
immutable int CHUNK_DX = (1<<CHUNK_DX_SHIFT);
|
||||
immutable int CHUNK_DX_MASK = (CHUNK_DX - 1);
|
||||
|
||||
// Y range: 0..CHUNK_DY-1
|
||||
immutable int CHUNK_DY_SHIFT = 7;
|
||||
immutable int CHUNK_DY = (1<<CHUNK_DY_SHIFT);
|
||||
immutable int CHUNK_DY_MASK = (CHUNK_DY - 1);
|
||||
immutable int CHUNK_DY_INV_MASK = ~CHUNK_DY_MASK;
|
||||
|
||||
//extern bool HIGHLIGHT_GRID;
|
||||
|
||||
// Layer is 256x16x16 CHUNK_DY layers = CHUNK_DY * (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells
|
||||
|
@ -100,6 +247,7 @@ public:
|
|||
|
||||
alias ChunkMatrix = InfiniteMatrix!(Chunk *);
|
||||
|
||||
|
||||
/// Voxel World
|
||||
class World {
|
||||
private:
|
||||
|
@ -134,20 +282,6 @@ public:
|
|||
return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY;
|
||||
}
|
||||
|
||||
/// get max Y position of non-empty cell in region (x +- size, z +- size)
|
||||
int regionHeight(int x, int z, int size) {
|
||||
int top = -1;
|
||||
int delta = size / CHUNK_DX + 1;
|
||||
for (int dx = x - delta; dx <= x + delta; dx += CHUNK_DX) {
|
||||
for (int dz = z - delta; dz <= z + delta; dz += CHUNK_DX) {
|
||||
if (Chunk * p = chunks.get(dx >> CHUNK_DX_SHIFT, dz >> CHUNK_DX_SHIFT))
|
||||
if (top < p.getTopNonEmpty)
|
||||
top = p.getTopNonEmpty;
|
||||
}
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
final void setCell(int x, int y, int z, cell_t value) {
|
||||
int chunkx = x >> CHUNK_DX_SHIFT;
|
||||
int chunkz = z >> CHUNK_DX_SHIFT;
|
||||
|
@ -166,6 +300,20 @@ public:
|
|||
setCell(pos.x + x, pos.y + y, pos.z + z, value);
|
||||
}
|
||||
|
||||
/// get max Y position of non-empty cell in region (x +- size, z +- size)
|
||||
int regionHeight(int x, int z, int size) {
|
||||
int top = -1;
|
||||
int delta = size / CHUNK_DX + 1;
|
||||
for (int dx = x - delta; dx <= x + delta; dx += CHUNK_DX) {
|
||||
for (int dz = z - delta; dz <= z + delta; dz += CHUNK_DX) {
|
||||
if (Chunk * p = chunks.get(dx >> CHUNK_DX_SHIFT, dz >> CHUNK_DX_SHIFT))
|
||||
if (top < p.getTopNonEmpty)
|
||||
top = p.getTopNonEmpty;
|
||||
}
|
||||
}
|
||||
return top;
|
||||
}
|
||||
|
||||
bool canPass(Vector3d pos) {
|
||||
return canPass(Vector3d(pos.x - 2, pos.y - 3, pos.z - 2), Vector3d(4, 5, 4));
|
||||
}
|
||||
|
@ -186,6 +334,7 @@ public:
|
|||
visitorHelper.visitAll(maxVisibleRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface CellVisitor {
|
||||
//void newDirection(ref Position camPosition);
|
||||
|
|
|
@ -29,6 +29,7 @@ import dminer.core.minetypes;
|
|||
import dminer.core.blocks;
|
||||
import dminer.core.world;
|
||||
import dminer.core.generators;
|
||||
import dminer.core.chunk;
|
||||
|
||||
mixin APP_ENTRY_POINT;
|
||||
|
||||
|
|
Loading…
Reference in New Issue