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="dminer">
|
||||||
<Folder name="core">
|
<Folder name="core">
|
||||||
<File path="src\dminer\core\blocks.d" />
|
<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\generators.d" />
|
||||||
<File path="src\dminer\core\minetypes.d" />
|
<File path="src\dminer\core\minetypes.d" />
|
||||||
<File path="src\dminer\core\terrain.d" />
|
<File path="src\dminer\core\terrain.d" />
|
||||||
|
|
|
@ -4,6 +4,7 @@ import dminer.core.minetypes;
|
||||||
import dminer.core.blocks;
|
import dminer.core.blocks;
|
||||||
import dminer.core.world;
|
import dminer.core.world;
|
||||||
import dminer.core.terrain;
|
import dminer.core.terrain;
|
||||||
|
import dminer.core.chunk;
|
||||||
|
|
||||||
|
|
||||||
__gshared static short[] TERRAIN_INIT_DATA = [
|
__gshared static short[] TERRAIN_INIT_DATA = [
|
||||||
|
|
|
@ -2,6 +2,7 @@ module dminer.core.world;
|
||||||
|
|
||||||
import dminer.core.minetypes;
|
import dminer.core.minetypes;
|
||||||
import dminer.core.blocks;
|
import dminer.core.blocks;
|
||||||
|
import dminer.core.chunk;
|
||||||
|
|
||||||
version (Android) {
|
version (Android) {
|
||||||
const int MAX_VIEW_DISTANCE_BITS = 6;
|
const int MAX_VIEW_DISTANCE_BITS = 6;
|
||||||
|
@ -10,21 +11,167 @@ version (Android) {
|
||||||
}
|
}
|
||||||
const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS);
|
const int MAX_VIEW_DISTANCE = (1 << MAX_VIEW_DISTANCE_BITS);
|
||||||
|
|
||||||
// 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
|
static if (USE_NEW_WORLD_IMPL) {
|
||||||
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;
|
class World {
|
||||||
|
|
||||||
// Layer is 256x16x16 CHUNK_DY layers = CHUNK_DY * (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells
|
this() {
|
||||||
struct ChunkLayer {
|
_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);
|
||||||
|
|
||||||
|
//extern bool HIGHLIGHT_GRID;
|
||||||
|
|
||||||
|
// Layer is 256x16x16 CHUNK_DY layers = CHUNK_DY * (CHUNK_DX_SHIFT x CHUNK_DX_SHIFT) cells
|
||||||
|
struct ChunkLayer {
|
||||||
|
|
||||||
cell_t[CHUNK_DX * CHUNK_DX] cells;
|
cell_t[CHUNK_DX * CHUNK_DX] cells;
|
||||||
|
|
||||||
|
@ -37,15 +184,15 @@ struct ChunkLayer {
|
||||||
void set(int x, int z, cell_t cell) {
|
void set(int x, int z, cell_t cell) {
|
||||||
cells.ptr[(z << CHUNK_DX_SHIFT) + x] = cell;
|
cells.ptr[(z << CHUNK_DX_SHIFT) + x] = cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Chunk {
|
struct Chunk {
|
||||||
private:
|
private:
|
||||||
ChunkLayer*[CHUNK_DY] layers;
|
ChunkLayer*[CHUNK_DY] layers;
|
||||||
int bottomLayer = - 1;
|
int bottomLayer = - 1;
|
||||||
int topLayer = -1;
|
int topLayer = -1;
|
||||||
int topNonEmpty = -1;
|
int topNonEmpty = -1;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
~this() {
|
~this() {
|
||||||
for (int i = 0; i < CHUNK_DY; i++)
|
for (int i = 0; i < CHUNK_DY; i++)
|
||||||
|
@ -96,18 +243,19 @@ public:
|
||||||
|
|
||||||
/// srcpos coords x, z are in chunk bounds
|
/// srcpos coords x, z are in chunk bounds
|
||||||
//void getCells(Vector3d srcpos, Vector3d dstpos, Vector3d size, VolumeData & buf);
|
//void getCells(Vector3d srcpos, Vector3d dstpos, Vector3d size, VolumeData & buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
alias ChunkMatrix = InfiniteMatrix!(Chunk *);
|
alias ChunkMatrix = InfiniteMatrix!(Chunk *);
|
||||||
|
|
||||||
/// Voxel World
|
|
||||||
class World {
|
/// Voxel World
|
||||||
private:
|
class World {
|
||||||
|
private:
|
||||||
Position _camPosition;
|
Position _camPosition;
|
||||||
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
||||||
ChunkMatrix chunks;
|
ChunkMatrix chunks;
|
||||||
DiamondVisitor visitorHelper;
|
DiamondVisitor visitorHelper;
|
||||||
public:
|
public:
|
||||||
this() {
|
this() {
|
||||||
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||||
}
|
}
|
||||||
|
@ -134,20 +282,6 @@ public:
|
||||||
return BLOCK_TYPE_OPAQUE.ptr[cell] && cell != BOUND_SKY;
|
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) {
|
final void setCell(int x, int y, int z, cell_t value) {
|
||||||
int chunkx = x >> CHUNK_DX_SHIFT;
|
int chunkx = x >> CHUNK_DX_SHIFT;
|
||||||
int chunkz = z >> 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);
|
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) {
|
bool canPass(Vector3d pos) {
|
||||||
return canPass(Vector3d(pos.x - 2, pos.y - 3, pos.z - 2), Vector3d(4, 5, 4));
|
return canPass(Vector3d(pos.x - 2, pos.y - 3, pos.z - 2), Vector3d(4, 5, 4));
|
||||||
}
|
}
|
||||||
|
@ -185,6 +333,7 @@ public:
|
||||||
visitor);
|
visitor);
|
||||||
visitorHelper.visitAll(maxVisibleRange);
|
visitorHelper.visitAll(maxVisibleRange);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CellVisitor {
|
interface CellVisitor {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import dminer.core.minetypes;
|
||||||
import dminer.core.blocks;
|
import dminer.core.blocks;
|
||||||
import dminer.core.world;
|
import dminer.core.world;
|
||||||
import dminer.core.generators;
|
import dminer.core.generators;
|
||||||
|
import dminer.core.chunk;
|
||||||
|
|
||||||
mixin APP_ENTRY_POINT;
|
mixin APP_ENTRY_POINT;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue