mirror of https://github.com/buggins/dlangui.git
miner example improvements
This commit is contained in:
parent
83072c5254
commit
c8a9d34534
|
@ -5,6 +5,8 @@ import dminer.core.blocks;
|
||||||
import dminer.core.world;
|
import dminer.core.world;
|
||||||
import dlangui.graphics.scene.mesh;
|
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;
|
||||||
|
|
||||||
|
@ -25,6 +27,10 @@ interface CellVisitor {
|
||||||
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 ChunkVisitor {
|
||||||
|
void visit(World world, SmallChunk * chunk);
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -135,15 +141,15 @@ struct ChunkStack {
|
||||||
struct SmallChunk {
|
struct SmallChunk {
|
||||||
protected cell_t[8*8*8] cells; // 512 bytes
|
protected cell_t[8*8*8] cells; // 512 bytes
|
||||||
protected ubyte[8*8*8] sunlight; // 512 bytes
|
protected ubyte[8*8*8] sunlight; // 512 bytes
|
||||||
protected ulong[8] opaquePlanesX; // 64 bytes
|
protected ulong[8] opaquePlanesX; // 64 bytes WEST to EAST
|
||||||
protected ulong[8] opaquePlanesY; // 64 bytes
|
protected ulong[8] opaquePlanesY; // 64 bytes DOWN to UP
|
||||||
protected ulong[8] opaquePlanesZ; // 64 bytes
|
protected ulong[8] opaquePlanesZ; // 64 bytes NORTH to SOUTH
|
||||||
protected ulong[8] visiblePlanesX; // 64 bytes
|
protected ulong[8] visiblePlanesX; // 64 bytes WEST to EAST
|
||||||
protected ulong[8] visiblePlanesY; // 64 bytes
|
protected ulong[8] visiblePlanesY; // 64 bytes DOWN to UP
|
||||||
protected ulong[8] visiblePlanesZ; // 64 bytes
|
protected ulong[8] visiblePlanesZ; // 64 bytes NORTH to SOUTH
|
||||||
protected ulong[8] canPassPlanesX; // 64 bytes
|
protected ulong[8] canPassPlanesX; // 64 bytes WEST to EAST
|
||||||
protected ulong[8] canPassPlanesY; // 64 bytes
|
protected ulong[8] canPassPlanesY; // 64 bytes DOWN to UP
|
||||||
protected ulong[8] canPassPlanesZ; // 64 bytes
|
protected ulong[8] canPassPlanesZ; // 64 bytes NORTH to SOUTH
|
||||||
//ulong[6][6] canPassFromTo; // 288 bytes
|
//ulong[6][6] canPassFromTo; // 288 bytes
|
||||||
SmallChunk * [6] nearChunks;
|
SmallChunk * [6] nearChunks;
|
||||||
protected Vector3d _pos;
|
protected Vector3d _pos;
|
||||||
|
@ -389,6 +395,40 @@ struct SmallChunk {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
X planes (WEST EAST): z, y
|
||||||
|
z=0 z=1 z=2 z=3 z=4 z=5 z=6 z=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
|
||||||
|
Y planes (DOWN UP): x, z
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
z=0 0 1 2 3 4 5 6 7
|
||||||
|
z=1 8 9 10 11 12 13 14 15
|
||||||
|
z=2 16 17 18 19 29 21 22 23
|
||||||
|
z=3 24 25 26 27 28 29 30 31
|
||||||
|
z=4 32 33 34 35 36 37 38 39
|
||||||
|
z=5 40 41 42 43 44 45 46 47
|
||||||
|
z=6 48 49 50 51 52 53 54 55
|
||||||
|
z=7 56 57 58 59 60 61 62 63
|
||||||
|
|
||||||
|
Z planes (NORTH SOUTH): x, y
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
private void generateMasks() {
|
private void generateMasks() {
|
||||||
// x planes: z,y
|
// x planes: z,y
|
||||||
for(int x = 0; x < 8; x++) {
|
for(int x = 0; x < 8; x++) {
|
||||||
|
@ -707,3 +747,334 @@ void testDirMaskToSpreadMask() {
|
||||||
Log.d("Source: \n", generateDirMaskSource());
|
Log.d("Source: \n", generateDirMaskSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// mask for available spread direction for chunk dest visited from camera chunk position origin
|
||||||
|
ubyte calcSpreadMask(Vector3d dest, Vector3d origin) {
|
||||||
|
ubyte res = 0;
|
||||||
|
if (dest.x < origin.x) {
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
} else if (dest.x > origin.x) {
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
} else {
|
||||||
|
res |= DirMask.MASK_WEST | DirMask.MASK_EAST;
|
||||||
|
}
|
||||||
|
if (dest.y < origin.y) {
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
} else if (dest.y > origin.y) {
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
} else {
|
||||||
|
res |= DirMask.MASK_DOWN | DirMask.MASK_UP;
|
||||||
|
}
|
||||||
|
if (dest.z < origin.z) {
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
} else if (dest.z > origin.z) {
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
} else {
|
||||||
|
res |= DirMask.MASK_NORTH | DirMask.MASK_SOUTH;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Z planes (NORTH SOUTH): x, y
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
|
ulong spreadZPlane(ulong mask, ulong canPassMask, ubyte spreadToDirMask) {
|
||||||
|
ulong res = mask & canPassMask;
|
||||||
|
if (!res)
|
||||||
|
return 0;
|
||||||
|
if (spreadToDirMask & DirMask.MASK_WEST) { // x--
|
||||||
|
res |= ((mask & 0xFEFEFEFEFEFEFEFEL) >> 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_EAST) { // x++
|
||||||
|
res |= ((mask & 0x7f7f7f7f7f7f7f7fL) << 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_UP) { // y++
|
||||||
|
res |= ((mask & 0x00ffffffffffffffL) << 8) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_DOWN) { // y--
|
||||||
|
res |= ((mask & 0xffffffffffffff00L) >> 8) & canPassMask;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
X planes (WEST EAST): z, y
|
||||||
|
z=0 z=1 z=2 z=3 z=4 z=5 z=6 z=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
|
ulong spreadXPlane(ulong mask, ulong canPassMask, ubyte spreadToDirMask) {
|
||||||
|
ulong res = mask & canPassMask;
|
||||||
|
if (!res)
|
||||||
|
return 0;
|
||||||
|
if (spreadToDirMask & DirMask.MASK_NORTH) { // z--
|
||||||
|
res |= ((mask & 0xFEFEFEFEFEFEFEFEL) >> 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_SOUTH) { // z++
|
||||||
|
res |= ((mask & 0x7f7f7f7f7f7f7f7fL) << 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_UP) { // y++
|
||||||
|
res |= ((mask & 0x00ffffffffffffffL) << 8) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_DOWN) { // y--
|
||||||
|
res |= ((mask & 0xffffffffffffff00L) >> 8) & canPassMask;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Y planes (DOWN UP): x, z
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
z=0 0 1 2 3 4 5 6 7
|
||||||
|
z=1 8 9 10 11 12 13 14 15
|
||||||
|
z=2 16 17 18 19 29 21 22 23
|
||||||
|
z=3 24 25 26 27 28 29 30 31
|
||||||
|
z=4 32 33 34 35 36 37 38 39
|
||||||
|
z=5 40 41 42 43 44 45 46 47
|
||||||
|
z=6 48 49 50 51 52 53 54 55
|
||||||
|
z=7 56 57 58 59 60 61 62 63
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
ulong spreadYPlane(ulong mask, ulong canPassMask, ubyte spreadToDirMask) {
|
||||||
|
ulong res = mask & canPassMask;
|
||||||
|
if (!res)
|
||||||
|
return 0;
|
||||||
|
if (spreadToDirMask & DirMask.MASK_WEST) { // x--
|
||||||
|
res |= ((mask & 0xFEFEFEFEFEFEFEFEL) >> 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_EAST) { // x++
|
||||||
|
res |= ((mask & 0x7f7f7f7f7f7f7f7fL) << 1) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_SOUTH) { // z++
|
||||||
|
res |= ((mask & 0x00ffffffffffffffL) << 8) & canPassMask;
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_NORTH) { // z--
|
||||||
|
res |= ((mask & 0xffffffffffffff00L) >> 8) & canPassMask;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Z planes (NORTH SOUTH): x, y
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
|
||||||
|
X planes (WEST EAST): z, y
|
||||||
|
z=0 z=1 z=2 z=3 z=4 z=5 z=6 z=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
|
ulong xPlaneFromZplanes(ref ulong[8] planes, int x) {
|
||||||
|
ulong res = 0;
|
||||||
|
for (int z = 0; z < 8; z++) {
|
||||||
|
ulong n = planes[z]; // one plane == z
|
||||||
|
n = n >> x; // move to low bit
|
||||||
|
n &= 0x0101010101010101L;
|
||||||
|
n = n << z; // move to Z bit
|
||||||
|
res |= n;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Z planes (NORTH SOUTH): x, y
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
|
||||||
|
Y planes (DOWN UP): x, z
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
z=0 0 1 2 3 4 5 6 7
|
||||||
|
z=1 8 9 10 11 12 13 14 15
|
||||||
|
z=2 16 17 18 19 29 21 22 23
|
||||||
|
z=3 24 25 26 27 28 29 30 31
|
||||||
|
z=4 32 33 34 35 36 37 38 39
|
||||||
|
z=5 40 41 42 43 44 45 46 47
|
||||||
|
z=6 48 49 50 51 52 53 54 55
|
||||||
|
z=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
|
ulong yPlaneFromZplanes(ref ulong[8] planes, int y) {
|
||||||
|
ulong res = 0;
|
||||||
|
for (int z = 0; z < 8; z++) {
|
||||||
|
ulong n = planes[z]; // one plane == z
|
||||||
|
n = n >> (y * 3); // move to low byte
|
||||||
|
n &= 0xFF;
|
||||||
|
n = n << (z * 3); // move to Z position
|
||||||
|
res |= n;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VisibilityCheckChunk {
|
||||||
|
SmallChunk * chunk;
|
||||||
|
ulong[6] maskFrom;
|
||||||
|
ulong[6] maskTo;
|
||||||
|
ubyte visitedFromDirMask;
|
||||||
|
ubyte spreadToDirMask;
|
||||||
|
void setMask(ulong mask, Dir fromDir) {
|
||||||
|
maskFrom[fromDir] |= mask;
|
||||||
|
visitedFromDirMask |= (1 << fromDir);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Z planes (NORTH SOUTH): x, y
|
||||||
|
x=0 x=1 x=2 x=3 x=4 x=5 x=6 x=7
|
||||||
|
y=0 0 1 2 3 4 5 6 7
|
||||||
|
y=1 8 9 10 11 12 13 14 15
|
||||||
|
y=2 16 17 18 19 29 21 22 23
|
||||||
|
y=3 24 25 26 27 28 29 30 31
|
||||||
|
y=4 32 33 34 35 36 37 38 39
|
||||||
|
y=5 40 41 42 43 44 45 46 47
|
||||||
|
y=6 48 49 50 51 52 53 54 55
|
||||||
|
y=7 56 57 58 59 60 61 62 63
|
||||||
|
*/
|
||||||
|
void applyZPlanesTrace(ref ulong[8] planes) {
|
||||||
|
if (spreadToDirMask & DirMask.MASK_WEST) { // x--
|
||||||
|
// X planes (WEST EAST): z, y
|
||||||
|
maskTo[Dir.WEST] |= xPlaneFromZplanes(planes, 0);
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_EAST) { // x++
|
||||||
|
// X planes (WEST EAST): z, y
|
||||||
|
maskTo[Dir.EAST] |= xPlaneFromZplanes(planes, 7);
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_DOWN) { // y--
|
||||||
|
// Y planes (DOWN UP): x, z
|
||||||
|
maskTo[Dir.DOWN] |= yPlaneFromZplanes(planes, 0);
|
||||||
|
}
|
||||||
|
if (spreadToDirMask & DirMask.MASK_UP) { // y++
|
||||||
|
// Y planes (DOWN UP): x, z
|
||||||
|
maskTo[Dir.UP] |= yPlaneFromZplanes(planes, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void tracePaths() {
|
||||||
|
if (auto mask = maskFrom[Dir.NORTH]) {
|
||||||
|
ulong[8] planes;
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
mask = spreadZPlane(mask, chunk.canPassPlanesZ[i], spreadToDirMask);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
maskTo[Dir.NORTH] |= planes[0];
|
||||||
|
applyZPlanesTrace(planes);
|
||||||
|
} else if (auto mask = maskFrom[Dir.SOUTH]) {
|
||||||
|
ulong[8] planes;
|
||||||
|
for (int i = 0; i <= 7; i++) {
|
||||||
|
mask = spreadZPlane(mask, chunk.canPassPlanesZ[i], spreadToDirMask);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
maskTo[Dir.SOUTH] |= planes[7];
|
||||||
|
applyZPlanesTrace(planes);
|
||||||
|
}
|
||||||
|
if (auto mask = maskFrom[Dir.DOWN]) {
|
||||||
|
} else if (auto mask = maskFrom[Dir.UP]) {
|
||||||
|
}
|
||||||
|
if (auto mask = maskFrom[Dir.WEST]) {
|
||||||
|
} else if (auto mask = maskFrom[Dir.EAST]) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Diamond iterator for visibility check
|
||||||
|
struct VisibilityCheckIterator {
|
||||||
|
World world;
|
||||||
|
Vector3d startPos;
|
||||||
|
SmallChunk * startChunk;
|
||||||
|
ChunkVisitor visitor;
|
||||||
|
VisibilityCheckChunk[] plannedChunks;
|
||||||
|
VisibilityCheckChunk[] visitedChunks;
|
||||||
|
VisibilityCheckChunk * getOrAddPlannedChunk(SmallChunk * newChunk) {
|
||||||
|
foreach(ref p; plannedChunks) {
|
||||||
|
if (p.chunk is newChunk)
|
||||||
|
return &p;
|
||||||
|
}
|
||||||
|
VisibilityCheckChunk plan;
|
||||||
|
plan.chunk = newChunk;
|
||||||
|
plannedChunks ~= plan;
|
||||||
|
return &plannedChunks[$ - 1];
|
||||||
|
}
|
||||||
|
// step 1: plan visiting chunk
|
||||||
|
void planVisitChunk(int x, int y, int z, Dir fromDir, ulong mask) {
|
||||||
|
if (!mask)
|
||||||
|
return;
|
||||||
|
SmallChunk * newChunk = world.getCellChunk(x, y, z);
|
||||||
|
if (!newChunk)
|
||||||
|
return;
|
||||||
|
VisibilityCheckChunk * plan = getOrAddPlannedChunk(newChunk);
|
||||||
|
plan.setMask(mask, fromDir);
|
||||||
|
}
|
||||||
|
// step 2: visit all planned chunks: move planned to visited; trace paths; plan new visits
|
||||||
|
void visitPlannedChunks() {
|
||||||
|
import std.algorithm : swap;
|
||||||
|
swap(visitedChunks, plannedChunks);
|
||||||
|
plannedChunks.length = 0;
|
||||||
|
foreach (ref p; visitedChunks) {
|
||||||
|
visitor.visit(world, p.chunk);
|
||||||
|
/// set mask of spread directions
|
||||||
|
p.spreadToDirMask = calcSpreadMask(p.chunk.position, startPos);
|
||||||
|
p.tracePaths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void start(World world, Vector3d startPos) {
|
||||||
|
this.world = world;
|
||||||
|
this.startChunk = world.getCellChunk(startPos.x, startPos.y, startPos.z);
|
||||||
|
this.startPos = this.startChunk.position; // position aligned by 8 cells
|
||||||
|
plannedChunks.assumeSafeAppend;
|
||||||
|
plannedChunks.length = 0;
|
||||||
|
visitedChunks.assumeSafeAppend;
|
||||||
|
visitedChunks.length = 0;
|
||||||
|
}
|
||||||
|
void visitVisibleChunks(ChunkVisitor visitor) {
|
||||||
|
this.visitor = visitor;
|
||||||
|
visitor.visit(world, startChunk);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.NORTH))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.NORTH, mask);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.SOUTH))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.SOUTH, mask);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.WEST))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.WEST, mask);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.EAST))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.EAST, mask);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.UP))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.UP, mask);
|
||||||
|
if (auto mask = startChunk.getSideCanPassToMask(Dir.DOWN))
|
||||||
|
planVisitChunk(startPos.x, startPos.y, startPos.z, Dir.DOWN, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,13 +10,31 @@ immutable cell_t VISITED_OCCUPIED = 254;
|
||||||
immutable cell_t BOUND_BOTTOM = 253;
|
immutable cell_t BOUND_BOTTOM = 253;
|
||||||
immutable cell_t BOUND_SKY = 252;
|
immutable cell_t BOUND_SKY = 252;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
World coordinates
|
||||||
|
|
||||||
|
A UP
|
||||||
|
|
|
||||||
|
| / NORTH
|
||||||
|
| /
|
||||||
|
WEST |/
|
||||||
|
-----------|-----------> EAST
|
||||||
|
/|
|
||||||
|
/ |
|
||||||
|
SOUTH/ |
|
||||||
|
L |
|
||||||
|
| DOWN
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// World direction
|
||||||
enum Dir : ubyte {
|
enum Dir : ubyte {
|
||||||
NORTH = 0,
|
NORTH = 0, /// z--
|
||||||
SOUTH,
|
SOUTH, /// z++
|
||||||
EAST,
|
EAST, /// x++
|
||||||
WEST,
|
WEST, /// x--
|
||||||
UP,
|
UP, /// y++
|
||||||
DOWN,
|
DOWN, /// y--
|
||||||
}
|
}
|
||||||
|
|
||||||
// 26 direction masks based on Dir
|
// 26 direction masks based on Dir
|
||||||
|
@ -64,10 +82,15 @@ struct Vector2d {
|
||||||
|
|
||||||
immutable Vector2d ZERO2 = Vector2d(0, 0);
|
immutable Vector2d ZERO2 = Vector2d(0, 0);
|
||||||
|
|
||||||
|
/// Integer 3d vector: x,y,z
|
||||||
struct Vector3d {
|
struct Vector3d {
|
||||||
|
/// WEST-EAST
|
||||||
int x;
|
int x;
|
||||||
|
/// DOWN-UP
|
||||||
int y;
|
int y;
|
||||||
|
/// NORTH-SOUTH
|
||||||
int z;
|
int z;
|
||||||
|
|
||||||
this(int xx, int yy, int zz) {
|
this(int xx, int yy, int zz) {
|
||||||
x = xx;
|
x = xx;
|
||||||
y = yy;
|
y = yy;
|
||||||
|
@ -249,152 +272,6 @@ alias CellArray = Array!(cell_t);
|
||||||
alias Vector2dArray = Array!(Vector2d);
|
alias Vector2dArray = Array!(Vector2d);
|
||||||
alias Vector3dArray = Array!(Vector3d);
|
alias Vector3dArray = Array!(Vector3d);
|
||||||
|
|
||||||
/*
|
|
||||||
/// array with support of both positive and negative indexes
|
|
||||||
struct InfiniteArray(T) {
|
|
||||||
private:
|
|
||||||
T[] dataPlus;
|
|
||||||
T[] dataMinus;
|
|
||||||
int minIdx;
|
|
||||||
int maxIdx;
|
|
||||||
public:
|
|
||||||
@property int minIndex() { return minIdx; }
|
|
||||||
@property int maxIndex() { return maxIdx; }
|
|
||||||
void disposeFunction(T p) {
|
|
||||||
destroy(p);
|
|
||||||
}
|
|
||||||
~this() {
|
|
||||||
foreach(p; dataPlus)
|
|
||||||
if (p !is T.init)
|
|
||||||
disposeFunction(p);
|
|
||||||
foreach(p; dataMinus)
|
|
||||||
if (p !is T.init)
|
|
||||||
disposeFunction(p);
|
|
||||||
}
|
|
||||||
T get(int index) {
|
|
||||||
if (index >= 0) {
|
|
||||||
if (index >= maxIdx)
|
|
||||||
return T.init;
|
|
||||||
return dataPlus[index];
|
|
||||||
} else {
|
|
||||||
if (index <= minIdx)
|
|
||||||
return T.init;
|
|
||||||
return dataMinus[-index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void set(int index, T value) {
|
|
||||||
if (index >= 0) {
|
|
||||||
if (index >= maxIdx) {
|
|
||||||
// extend array
|
|
||||||
if (index <= dataPlus.length) {
|
|
||||||
int oldsize = dataPlus.length;
|
|
||||||
int newsize = 1024;
|
|
||||||
while (newsize <= index)
|
|
||||||
newsize <<= 1;
|
|
||||||
dataPlus.length = newsize;
|
|
||||||
dataPlus.assumeSafeAppend;
|
|
||||||
for(int i = oldsize; i < newsize; i++)
|
|
||||||
dataPlus[i] = T.init;
|
|
||||||
}
|
|
||||||
maxIdx = index + 1;
|
|
||||||
}
|
|
||||||
if (dataPlus[index] !is T.init && dataPlus[index] !is value)
|
|
||||||
disposeFunction(dataPlus[index]);
|
|
||||||
dataPlus[index] = value;
|
|
||||||
} else {
|
|
||||||
if (index <= minIdx) {
|
|
||||||
// extend array
|
|
||||||
if (-index <= dataMinus.length) {
|
|
||||||
int oldsize = dataMinus.length;
|
|
||||||
int newsize = 1024;
|
|
||||||
while (newsize <= -index)
|
|
||||||
newsize <<= 1;
|
|
||||||
dataMinus.length = newsize;
|
|
||||||
dataMinus.assumeSafeAppend;
|
|
||||||
for(int i = oldsize; i < newsize; i++)
|
|
||||||
dataMinus[i] = T.init;
|
|
||||||
}
|
|
||||||
maxIdx = index - 1;
|
|
||||||
}
|
|
||||||
if (dataMinus[-index] !is T.init && dataMinus[-index] !is value)
|
|
||||||
disposeFunction(dataMinus[-index]);
|
|
||||||
dataMinus[-index] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InfiniteMatrix(T) {
|
|
||||||
private:
|
|
||||||
int _size = 0;
|
|
||||||
int _sizeShift = 0;
|
|
||||||
int _sizeShiftMul2 = 0;
|
|
||||||
int _sizeMask = 0;
|
|
||||||
int _invSizeMask = 0;
|
|
||||||
T[] _data;
|
|
||||||
void resize(int newSizeShift) {
|
|
||||||
int newSize = (1<<newSizeShift);
|
|
||||||
T[] newdata;
|
|
||||||
newdata.length = newSize * 2 * newSize * 2;
|
|
||||||
newdata[0 .. $] = null;
|
|
||||||
for (int y = -_size; y < _size; y++) {
|
|
||||||
for (int x = -_size; x < _size; x++) {
|
|
||||||
T v = get(x, y);
|
|
||||||
if (x < -newSize || x >= newSize || y < -newSize || y >= newSize) {
|
|
||||||
// destory: // outside new size
|
|
||||||
destroy(v);
|
|
||||||
} else {
|
|
||||||
// move
|
|
||||||
newdata[((y + newSize) << (newSizeShift + 1)) | (x + newSize)] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_data = newdata;
|
|
||||||
_size = newSize;
|
|
||||||
_sizeShift = newSizeShift;
|
|
||||||
_sizeShiftMul2 = _sizeShift + 1;
|
|
||||||
_sizeMask = (1 << _sizeShiftMul2) - 1;
|
|
||||||
_invSizeMask = ~_sizeMask;
|
|
||||||
}
|
|
||||||
int calcIndex(int x, int y) {
|
|
||||||
return (y << _sizeShiftMul2) + x;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
@property int size() { return _size; }
|
|
||||||
T get(int x, int y) {
|
|
||||||
if (!_data)
|
|
||||||
return null;
|
|
||||||
x += _size;
|
|
||||||
y += _size;
|
|
||||||
if (!((x | y) & ~_sizeMask)) {
|
|
||||||
return _data.ptr[(y << _sizeShiftMul2) + x]; //calcIndex(x, y)
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
void set(int x, int y, T v) {
|
|
||||||
if (x < -_size || x >= _size || y < -_size || y >= _size) {
|
|
||||||
int newSizeShift = _sizeShift < 6 ? 6 : _sizeShift + 1;
|
|
||||||
for (; ;newSizeShift++) {
|
|
||||||
int sz = 1 << newSizeShift;
|
|
||||||
if (x < -sz || x >= sz || y < -sz || y >= sz)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
resize(newSizeShift);
|
|
||||||
}
|
|
||||||
x += _size;
|
|
||||||
y += _size;
|
|
||||||
int index = calcIndex(x, y);
|
|
||||||
if (_data.ptr[index])
|
|
||||||
destroy(_data.ptr[index]);
|
|
||||||
_data.ptr[index] = v;
|
|
||||||
}
|
|
||||||
~this() {
|
|
||||||
foreach(ref v; _data)
|
|
||||||
if (v)
|
|
||||||
destroy(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
struct Position {
|
struct Position {
|
||||||
|
|
|
@ -219,10 +219,6 @@ private:
|
||||||
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
int maxVisibleRange = MAX_VIEW_DISTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChunkVisitor {
|
|
||||||
void visit(World world, SmallChunk * chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VisitorCell {
|
struct VisitorCell {
|
||||||
SmallChunk * chunk;
|
SmallChunk * chunk;
|
||||||
ulong[6] accessible;
|
ulong[6] accessible;
|
||||||
|
|
|
@ -430,6 +430,7 @@ class UiWidget : VerticalLayout { //, CellVisitor
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePositionMessage() {
|
void updatePositionMessage() {
|
||||||
|
import std.string : format;
|
||||||
Widget w = childById("lblPosition");
|
Widget w = childById("lblPosition");
|
||||||
string dir = _world.camPosition.direction.dir.to!string;
|
string dir = _world.camPosition.direction.dir.to!string;
|
||||||
dstring s = format("pos(%d,%d) h=%d fps:%d %s [F]lying: %s [U]pdateMesh: %s", _world.camPosition.pos.x, _world.camPosition.pos.z, _world.camPosition.pos.y,
|
dstring s = format("pos(%d,%d) h=%d fps:%d %s [F]lying: %s [U]pdateMesh: %s", _world.camPosition.pos.x, _world.camPosition.pos.z, _world.camPosition.pos.y,
|
||||||
|
|
Loading…
Reference in New Issue