mirror of https://github.com/buggins/dlangui.git
dminer fixes
This commit is contained in:
parent
f77ed053cb
commit
416b519f39
|
@ -2,6 +2,8 @@ module dminer.core.chunk;
|
||||||
|
|
||||||
import dminer.core.minetypes;
|
import dminer.core.minetypes;
|
||||||
import dminer.core.blocks;
|
import dminer.core.blocks;
|
||||||
|
import dminer.core.world;
|
||||||
|
import dlangui.graphics.scene.mesh;
|
||||||
|
|
||||||
// Y range: 0..CHUNK_DY-1
|
// Y range: 0..CHUNK_DY-1
|
||||||
immutable int CHUNK_DY = 128;
|
immutable int CHUNK_DY = 128;
|
||||||
|
@ -16,21 +18,16 @@ immutable int CHUNKS_X_MASK = (CHUNKS_X << 1) - 1;
|
||||||
immutable int CHUNKS_Z_MASK = (CHUNKS_Z << 1) - 1;
|
immutable int CHUNKS_Z_MASK = (CHUNKS_Z << 1) - 1;
|
||||||
|
|
||||||
interface CellVisitor {
|
interface CellVisitor {
|
||||||
import dminer.core.world;
|
|
||||||
//void newDirection(ref Position camPosition);
|
//void newDirection(ref Position camPosition);
|
||||||
//void visitFace(World world, ref Position camPosition, Vector3d pos, cell_t cell, Dir face);
|
//void visitFace(World world, ref Position camPosition, Vector3d pos, cell_t cell, Dir face);
|
||||||
void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces);
|
void visit(World world, ref Position camPosition, Vector3d pos, cell_t cell, int visibleFaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChunkCellVisitor {
|
|
||||||
void visit(int x, int y, int z, cell_t cell, int visibleFaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
// vertical stack of chunks with same X, Z, and different Y
|
// vertical stack of chunks with same X, Z, and different Y
|
||||||
struct ChunkStack {
|
struct ChunkStack {
|
||||||
protected int _minChunkY;
|
protected int _minChunkY;
|
||||||
protected int _chunkCount;
|
protected int _chunkCount;
|
||||||
SmallChunk ** _chunks;
|
protected SmallChunk ** _chunks;
|
||||||
/// get chunk from stack by chunk Y index
|
/// get chunk from stack by chunk Y index
|
||||||
SmallChunk * get(int chunkY) {
|
SmallChunk * get(int chunkY) {
|
||||||
int idx = chunkY - _minChunkY;
|
int idx = chunkY - _minChunkY;
|
||||||
|
@ -47,7 +44,7 @@ struct ChunkStack {
|
||||||
if (_chunks[idx]) {
|
if (_chunks[idx]) {
|
||||||
if (_chunks[idx] is item)
|
if (_chunks[idx] is item)
|
||||||
return;
|
return;
|
||||||
SmallChunk.release(_chunks[idx]);
|
_chunks[idx].release;
|
||||||
}
|
}
|
||||||
_chunks[idx] = item;
|
_chunks[idx] = item;
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +97,7 @@ struct ChunkStack {
|
||||||
void clear() {
|
void clear() {
|
||||||
if (_chunkCount) {
|
if (_chunkCount) {
|
||||||
for(int i = 0; i < _chunkCount; i++) {
|
for(int i = 0; i < _chunkCount; i++) {
|
||||||
SmallChunk.release(_chunks[i]);
|
_chunks[i].release;
|
||||||
}
|
}
|
||||||
freeChunks(_chunks);
|
freeChunks(_chunks);
|
||||||
}
|
}
|
||||||
|
@ -115,22 +112,24 @@ struct ChunkStack {
|
||||||
|
|
||||||
/// 8x8x8 chunk
|
/// 8x8x8 chunk
|
||||||
struct SmallChunk {
|
struct SmallChunk {
|
||||||
cell_t[8*8*8] cells; // 512 bytes
|
protected cell_t[8*8*8] cells; // 512 bytes
|
||||||
ubyte[8*8*8] sunlight; // 512 bytes
|
protected ubyte[8*8*8] sunlight; // 512 bytes
|
||||||
ulong[8] opaquePlanesX; // 64 bytes
|
protected ulong[8] opaquePlanesX; // 64 bytes
|
||||||
ulong[8] opaquePlanesY; // 64 bytes
|
protected ulong[8] opaquePlanesY; // 64 bytes
|
||||||
ulong[8] opaquePlanesZ; // 64 bytes
|
protected ulong[8] opaquePlanesZ; // 64 bytes
|
||||||
ulong[8] visiblePlanesX; // 64 bytes
|
protected ulong[8] visiblePlanesX; // 64 bytes
|
||||||
ulong[8] visiblePlanesY; // 64 bytes
|
protected ulong[8] visiblePlanesY; // 64 bytes
|
||||||
ulong[8] visiblePlanesZ; // 64 bytes
|
protected ulong[8] visiblePlanesZ; // 64 bytes
|
||||||
ulong[8] canPassPlanesX; // 64 bytes
|
protected ulong[8] canPassPlanesX; // 64 bytes
|
||||||
ulong[8] canPassPlanesY; // 64 bytes
|
protected ulong[8] canPassPlanesY; // 64 bytes
|
||||||
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;
|
||||||
bool dirty;
|
protected Vector3d pos;
|
||||||
bool empty;
|
private Mesh _minerMesh;
|
||||||
Vector3d pos;
|
protected bool dirty;
|
||||||
|
protected bool dirtyMesh;
|
||||||
|
protected bool empty;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -142,13 +141,26 @@ struct SmallChunk {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release(SmallChunk * obj) {
|
void release() {
|
||||||
if (!obj)
|
if (!(&this))
|
||||||
return;
|
return;
|
||||||
|
compact();
|
||||||
import core.stdc.stdlib : free;
|
import core.stdc.stdlib : free;
|
||||||
free(obj);
|
free(&this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// destroys mesh
|
||||||
|
void compact() {
|
||||||
|
if (_minerMesh) {
|
||||||
|
destroy(_minerMesh);
|
||||||
|
_minerMesh = null;
|
||||||
|
dirtyMesh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calcIndex(int x, int y, int z) {
|
||||||
|
return ((((y&7) << 3) | (z&7)) << 3) | (x&7);
|
||||||
|
}
|
||||||
cell_t getCell(int x, int y, int z) const {
|
cell_t getCell(int x, int y, int z) const {
|
||||||
return cells[((((y&7) << 3) | (z&7)) << 3) | (x&7)];
|
return cells[((((y&7) << 3) | (z&7)) << 3) | (x&7)];
|
||||||
}
|
}
|
||||||
|
@ -186,7 +198,61 @@ struct SmallChunk {
|
||||||
return chunk.getSideCanPassToMask(opposite(dir));
|
return chunk.getSideCanPassToMask(opposite(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findVisibleFaces(ChunkCellVisitor visitor) {
|
void visitVisibleFaces(World world, CellVisitor visitor) {
|
||||||
|
if (dirty)
|
||||||
|
generateMasks();
|
||||||
|
if (empty)
|
||||||
|
return;
|
||||||
|
ubyte[64] visibleFaceFlags;
|
||||||
|
findVisibleFaces(visibleFaceFlags);
|
||||||
|
int index = 0;
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
for (int z = 0; z < 8; z++) {
|
||||||
|
for (int x = 0; x < 8; x++) {
|
||||||
|
int visibleFaces = visibleFaceFlags[index];
|
||||||
|
if (visibleFaces) {
|
||||||
|
visitor.visit(world, world.camPosition, Vector3d(pos.x + x, pos.y + y, pos.z + z), cells[index], visibleFaces);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get mesh for chunk (generate if not exists)
|
||||||
|
Mesh getMesh(World world) {
|
||||||
|
if (dirty)
|
||||||
|
generateMasks();
|
||||||
|
if (empty)
|
||||||
|
return null;
|
||||||
|
if (!_minerMesh) {
|
||||||
|
_minerMesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
|
||||||
|
dirtyMesh = true;
|
||||||
|
}
|
||||||
|
if (dirtyMesh) {
|
||||||
|
_minerMesh.reset();
|
||||||
|
ubyte[64] visibleFaceFlags;
|
||||||
|
findVisibleFaces(visibleFaceFlags);
|
||||||
|
int index = 0;
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
for (int z = 0; z < 8; z++) {
|
||||||
|
for (int x = 0; x < 8; x++) {
|
||||||
|
int visibleFaces = visibleFaceFlags[index];
|
||||||
|
if (visibleFaces) {
|
||||||
|
BlockDef def = BLOCK_DEFS[cells[index]];
|
||||||
|
def.createFaces(world, world.camPosition, Vector3d(pos.x + x, pos.y + y, pos.z + z), visibleFaces, _minerMesh);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_minerMesh.vertexCount)
|
||||||
|
return null;
|
||||||
|
return _minerMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findVisibleFaces(ref ubyte[64] visibleFaceFlags) {
|
||||||
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++) {
|
||||||
|
@ -246,9 +312,10 @@ struct SmallChunk {
|
||||||
visibleFaces |= DirMask.MASK_UP;
|
visibleFaces |= DirMask.MASK_UP;
|
||||||
if (visibleFacesDown[y] & yplanemask)
|
if (visibleFacesDown[y] & yplanemask)
|
||||||
visibleFaces |= DirMask.MASK_DOWN;
|
visibleFaces |= DirMask.MASK_DOWN;
|
||||||
if (visibleFaces) {
|
visibleFaceFlags[calcIndex(x, y, z)] = cast(ubyte)visibleFaces;
|
||||||
visitor.visit(x, y, z, getCell(x, y, z), visibleFaces);
|
//if (visibleFaces) {
|
||||||
}
|
// visitor.visit(pos.x + x, pos.y + y, pos.z + z, getCell(x, y, z), visibleFaces);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +395,9 @@ 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;
|
||||||
|
dirtyMesh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spreadFlags(ulong src, ref ulong[8] planes, ref ulong[8] dst, int start, int end, ubyte spreadMask) {
|
static void spreadFlags(ulong src, ref ulong[8] planes, ref ulong[8] dst, int start, int end, ubyte spreadMask) {
|
||||||
if (start < end) {
|
if (start < end) {
|
||||||
for (int i = start; i <= end; ++i) {
|
for (int i = start; i <= end; ++i) {
|
||||||
|
|
|
@ -18,11 +18,21 @@ class World {
|
||||||
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
_camPosition = Position(Vector3d(0, 13, 0), Vector3d(0, 0, 1));
|
||||||
}
|
}
|
||||||
~this() {
|
~this() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
for(int index = 0; index < _chunkStacks.length; index++) {
|
||||||
|
if (_chunkStacks[index]) {
|
||||||
|
destroy(_chunkStacks[index]);
|
||||||
|
_chunkStacks[index] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@property final ref Position camPosition() { return _camPosition; }
|
@property final ref Position camPosition() { return _camPosition; }
|
||||||
|
|
||||||
|
|
||||||
protected ChunkStack*[CHUNKS_X * 2 * CHUNKS_Z * 2] _chunkStacks;
|
protected ChunkStack*[CHUNKS_X * 2 * CHUNKS_Z * 2] _chunkStacks;
|
||||||
|
|
||||||
//pragma(msg, "stack pointers array size, Kb:");
|
//pragma(msg, "stack pointers array size, Kb:");
|
||||||
//pragma(msg, _chunkStacks.sizeof / 1024);
|
//pragma(msg, _chunkStacks.sizeof / 1024);
|
||||||
final cell_t getCell(int x, int y, int z) {
|
final cell_t getCell(int x, int y, int z) {
|
||||||
|
|
Loading…
Reference in New Issue