mirror of https://github.com/buggins/dlangui.git
dminer optimization
This commit is contained in:
parent
1e14826643
commit
a66f93d81a
|
@ -6,6 +6,7 @@ import dminer.core.world;
|
||||||
import dlangui.graphics.scene.mesh;
|
import dlangui.graphics.scene.mesh;
|
||||||
|
|
||||||
|
|
||||||
|
version = FAST_VISIBILITY_PATH;
|
||||||
|
|
||||||
// Y range: 0..CHUNK_DY-1
|
// Y range: 0..CHUNK_DY-1
|
||||||
immutable int CHUNK_DY = 128;
|
immutable int CHUNK_DY = 128;
|
||||||
|
@ -150,6 +151,7 @@ struct SmallChunk {
|
||||||
protected ulong[8] canPassPlanesX; // 64 bytes WEST to EAST
|
protected ulong[8] canPassPlanesX; // 64 bytes WEST to EAST
|
||||||
protected ulong[8] canPassPlanesY; // 64 bytes DOWN to UP
|
protected ulong[8] canPassPlanesY; // 64 bytes DOWN to UP
|
||||||
protected ulong[8] canPassPlanesZ; // 64 bytes NORTH to SOUTH
|
protected ulong[8] canPassPlanesZ; // 64 bytes NORTH to SOUTH
|
||||||
|
protected ubyte[6] canPassFromTo; // index is FROM direction, ubyte is DirMask of TO direction; 1 means can pass FROM .. TO
|
||||||
//ulong[6][6] canPassFromTo; // 288 bytes
|
//ulong[6][6] canPassFromTo; // 288 bytes
|
||||||
SmallChunk * [6] nearChunks;
|
SmallChunk * [6] nearChunks;
|
||||||
protected Vector3d _pos;
|
protected Vector3d _pos;
|
||||||
|
@ -496,11 +498,11 @@ struct SmallChunk {
|
||||||
canPassPlanesZ[z] = canPassFlags;
|
canPassPlanesZ[z] = canPassFlags;
|
||||||
visiblePlanesZ[z] = visibleFlags;
|
visiblePlanesZ[z] = visibleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// can pass from to
|
// can pass from to
|
||||||
//for (Dir from = Dir.min; from <= Dir.max; ++from) {
|
for (Dir from = Dir.min; from <= Dir.max; ++from) {
|
||||||
// for (Dir to = Dir.min; to <= Dir.max; ++to) {
|
fillCanPassFrom(from);
|
||||||
// }
|
}
|
||||||
//}
|
|
||||||
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;
|
||||||
|
@ -508,6 +510,128 @@ struct SmallChunk {
|
||||||
dirtyMesh = true;
|
dirtyMesh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns DirMask of available pass direction for specified FROM direction
|
||||||
|
ubyte getCanPassFromFlags(Dir dirFrom) {
|
||||||
|
return canPassFromTo[dirFrom];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fillCanPassFrom(Dir dirFrom) {
|
||||||
|
ulong[8] planes;
|
||||||
|
ulong mask = 0xFFFFFFFFFFFFFFFFL;
|
||||||
|
ubyte res = 0;
|
||||||
|
final switch (dirFrom) {
|
||||||
|
case Dir.NORTH:
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
mask = spreadZPlane(mask, canPassPlanesZ[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[0])
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
if (xPlaneFromZplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
if (xPlaneFromZplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
if (yPlaneFromZplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
if (yPlaneFromZplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
break;
|
||||||
|
case Dir.SOUTH:
|
||||||
|
for (int i = 0; i <= 7; i++) {
|
||||||
|
mask = spreadZPlane(mask, canPassPlanesZ[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[7])
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
if (xPlaneFromZplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
if (xPlaneFromZplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
if (yPlaneFromZplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
if (yPlaneFromZplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
break;
|
||||||
|
case Dir.WEST: // x--
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
mask = spreadXPlane(mask, canPassPlanesX[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[0])
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
if (zPlaneFromXplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
if (zPlaneFromXplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
if (yPlaneFromXplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
if (yPlaneFromXplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
break;
|
||||||
|
case Dir.EAST: // x++
|
||||||
|
for (int i = 0; i <= 7; i++) {
|
||||||
|
mask = spreadXPlane(mask, canPassPlanesX[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[7])
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
if (zPlaneFromXplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
if (zPlaneFromXplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
if (yPlaneFromXplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
if (yPlaneFromXplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
break;
|
||||||
|
case Dir.DOWN: // y--
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
mask = spreadYPlane(mask, canPassPlanesY[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[0])
|
||||||
|
res |= DirMask.MASK_DOWN;
|
||||||
|
if (zPlaneFromYplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
if (zPlaneFromYplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
if (xPlaneFromYplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
if (xPlaneFromYplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
break;
|
||||||
|
case Dir.UP: // y--
|
||||||
|
for (int i = 0; i <= 7; i++) {
|
||||||
|
mask = spreadYPlane(mask, canPassPlanesY[i], DirMask.MASK_ALL);
|
||||||
|
if (!mask)
|
||||||
|
break;
|
||||||
|
planes[i] = mask;
|
||||||
|
}
|
||||||
|
if (planes[7])
|
||||||
|
res |= DirMask.MASK_UP;
|
||||||
|
if (zPlaneFromYplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_NORTH;
|
||||||
|
if (zPlaneFromYplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_SOUTH;
|
||||||
|
if (xPlaneFromYplanes(planes, 0))
|
||||||
|
res |= DirMask.MASK_WEST;
|
||||||
|
if (xPlaneFromYplanes(planes, 7))
|
||||||
|
res |= DirMask.MASK_EAST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
canPassFromTo[dirFrom] = res;
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -1206,10 +1330,44 @@ void testPlanes() {
|
||||||
v.testPlanesExtract();
|
v.testPlanesExtract();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version(FAST_VISIBILITY_PATH) {
|
||||||
struct VisibilityCheckChunk {
|
struct VisibilityCheckChunk {
|
||||||
SmallChunk * chunk;
|
SmallChunk * chunk;
|
||||||
ulong[6] maskFrom;
|
ulong[6] maskFrom;
|
||||||
ulong[6] maskTo;
|
ulong[6] maskTo;
|
||||||
|
Vector3d pos;
|
||||||
|
ubyte visitedFromDirMask;
|
||||||
|
ubyte spreadToDirMask;
|
||||||
|
void setMask(ulong mask, Dir fromDir) {
|
||||||
|
maskFrom[fromDir] |= mask;
|
||||||
|
visitedFromDirMask |= (1 << fromDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void traceFrom(Dir fromDir) {
|
||||||
|
ubyte m = chunk ? chunk.getCanPassFromFlags(fromDir) : DirMask.MASK_ALL;
|
||||||
|
for (ubyte dir = 0; dir < 6; dir++) {
|
||||||
|
ubyte flag = cast(ubyte)(1 << dir);
|
||||||
|
if (flag & spreadToDirMask)
|
||||||
|
if (m & flag)
|
||||||
|
maskTo[dir] |= 0xFFFFFFFFFFFFFFFFL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void tracePaths() {
|
||||||
|
for (Dir dirFrom = Dir.min; dirFrom <= Dir.max; dirFrom++) {
|
||||||
|
if ((visitedFromDirMask & (1 << dirFrom)))
|
||||||
|
traceFrom(dirFrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct VisibilityCheckChunk {
|
||||||
|
SmallChunk * chunk;
|
||||||
|
ulong[6] maskFrom;
|
||||||
|
ulong[6] maskTo;
|
||||||
|
Vector3d pos;
|
||||||
ubyte visitedFromDirMask;
|
ubyte visitedFromDirMask;
|
||||||
ubyte spreadToDirMask;
|
ubyte spreadToDirMask;
|
||||||
void setMask(ulong mask, Dir fromDir) {
|
void setMask(ulong mask, Dir fromDir) {
|
||||||
|
@ -1287,6 +1445,14 @@ struct VisibilityCheckChunk {
|
||||||
|
|
||||||
|
|
||||||
void tracePaths() {
|
void tracePaths() {
|
||||||
|
if (!chunk) {
|
||||||
|
// empty chunk - assuming transparent
|
||||||
|
for (ubyte dir = 0; dir < 6; dir++) {
|
||||||
|
if (spreadToDirMask & (1 << dir))
|
||||||
|
maskTo[dir] |= 0xFFFFFFFFFFFFFFFFL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (auto mask = maskFrom[Dir.NORTH]) {
|
if (auto mask = maskFrom[Dir.NORTH]) {
|
||||||
ulong[8] planes;
|
ulong[8] planes;
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
@ -1352,33 +1518,50 @@ struct VisibilityCheckChunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Diamond iterator for visibility check
|
/// Diamond iterator for visibility check
|
||||||
struct VisibilityCheckIterator {
|
struct VisibilityCheckIterator {
|
||||||
World world;
|
World world;
|
||||||
Vector3d startPos;
|
Vector3d startPos;
|
||||||
|
Vector3d camPos;
|
||||||
SmallChunk * startChunk;
|
SmallChunk * startChunk;
|
||||||
ChunkVisitor visitor;
|
ChunkVisitor visitor;
|
||||||
|
int maxDistance;
|
||||||
|
int maxDistanceSquared;
|
||||||
VisibilityCheckChunk[] plannedChunks;
|
VisibilityCheckChunk[] plannedChunks;
|
||||||
VisibilityCheckChunk[] visitedChunks;
|
VisibilityCheckChunk[] visitedChunks;
|
||||||
VisibilityCheckChunk * getOrAddPlannedChunk(SmallChunk * newChunk) {
|
/// get or add planned chunk by position
|
||||||
|
VisibilityCheckChunk * getOrAddPlannedChunk(Vector3d pos) {
|
||||||
foreach(ref p; plannedChunks) {
|
foreach(ref p; plannedChunks) {
|
||||||
if (p.chunk is newChunk)
|
if (p.pos == pos)
|
||||||
return &p;
|
return &p;
|
||||||
}
|
}
|
||||||
VisibilityCheckChunk plan;
|
VisibilityCheckChunk plan;
|
||||||
plan.chunk = newChunk;
|
plan.pos = pos;
|
||||||
plannedChunks ~= plan;
|
plannedChunks ~= plan;
|
||||||
return &plannedChunks[$ - 1];
|
return &plannedChunks[$ - 1];
|
||||||
}
|
}
|
||||||
// step 1: plan visiting chunk
|
// step 1: plan visiting chunk
|
||||||
void planVisitingChunk(int x, int y, int z, Dir fromDir, ulong mask) {
|
void planVisitingChunk(Vector3d p, Dir fromDir, ulong mask) {
|
||||||
|
// mask test
|
||||||
if (!mask)
|
if (!mask)
|
||||||
return;
|
return;
|
||||||
SmallChunk * newChunk = world.getCellChunk(x, y, z);
|
// distance test
|
||||||
if (!newChunk)
|
Vector3d diff = p - camPos;
|
||||||
|
if (diff.squaredLength() > maxDistanceSquared)
|
||||||
return;
|
return;
|
||||||
VisibilityCheckChunk * plan = getOrAddPlannedChunk(newChunk);
|
// direction test (TODO)
|
||||||
|
int dot = diff.dot(cameraDirection);
|
||||||
|
if (dot < 3000)
|
||||||
|
return;
|
||||||
|
//....
|
||||||
|
// plan visiting
|
||||||
|
VisibilityCheckChunk * plan = getOrAddPlannedChunk(p);
|
||||||
|
if (!plan.chunk) {
|
||||||
|
plan.chunk = world.getCellChunk(p.x, p.y, p.z);
|
||||||
|
}
|
||||||
plan.setMask(mask, fromDir);
|
plan.setMask(mask, fromDir);
|
||||||
}
|
}
|
||||||
// step 2: visit all planned chunks: move planned to visited; trace paths; plan new visits
|
// step 2: visit all planned chunks: move planned to visited; trace paths; plan new visits
|
||||||
|
@ -1389,54 +1572,75 @@ struct VisibilityCheckIterator {
|
||||||
foreach (ref p; visitedChunks) {
|
foreach (ref p; visitedChunks) {
|
||||||
visitor.visit(world, p.chunk);
|
visitor.visit(world, p.chunk);
|
||||||
/// set mask of spread directions
|
/// set mask of spread directions
|
||||||
p.spreadToDirMask = calcSpreadMask(p.chunk.position, startPos);
|
p.spreadToDirMask = calcSpreadMask(p.pos, startPos);
|
||||||
p.tracePaths();
|
p.tracePaths();
|
||||||
ubyte mask = p.spreadToDirMask;
|
ubyte mask = p.spreadToDirMask;
|
||||||
Vector3d pos = p.chunk.position;
|
Vector3d pos = p.pos;
|
||||||
|
|
||||||
if ((mask & DirMask.MASK_NORTH) && p.maskTo[Dir.NORTH]) { // z--
|
if ((mask & DirMask.MASK_NORTH) && p.maskTo[Dir.NORTH]) { // z--
|
||||||
planVisitingChunk(pos.x, pos.y, pos.z - 8, Dir.NORTH, p.maskTo[Dir.NORTH]);
|
planVisitingChunk(Vector3d(pos.x, pos.y, pos.z - 8), Dir.NORTH, p.maskTo[Dir.NORTH]);
|
||||||
}
|
}
|
||||||
if ((mask & DirMask.MASK_SOUTH) && p.maskTo[Dir.SOUTH]) { // z++
|
if ((mask & DirMask.MASK_SOUTH) && p.maskTo[Dir.SOUTH]) { // z++
|
||||||
planVisitingChunk(pos.x, pos.y, pos.z + 8, Dir.SOUTH, p.maskTo[Dir.SOUTH]);
|
planVisitingChunk(Vector3d(pos.x, pos.y, pos.z + 8), Dir.SOUTH, p.maskTo[Dir.SOUTH]);
|
||||||
}
|
}
|
||||||
if ((mask & DirMask.MASK_WEST) && p.maskTo[Dir.WEST]) { // x--
|
if ((mask & DirMask.MASK_WEST) && p.maskTo[Dir.WEST]) { // x--
|
||||||
planVisitingChunk(pos.x - 8, pos.y, pos.z, Dir.WEST, p.maskTo[Dir.WEST]);
|
planVisitingChunk(Vector3d(pos.x - 8, pos.y, pos.z), Dir.WEST, p.maskTo[Dir.WEST]);
|
||||||
}
|
}
|
||||||
if ((mask & DirMask.MASK_EAST) && p.maskTo[Dir.EAST]) { // x++
|
if ((mask & DirMask.MASK_EAST) && p.maskTo[Dir.EAST]) { // x++
|
||||||
planVisitingChunk(pos.x + 8, pos.y, pos.z, Dir.EAST, p.maskTo[Dir.EAST]);
|
planVisitingChunk(Vector3d(pos.x + 8, pos.y, pos.z), Dir.EAST, p.maskTo[Dir.EAST]);
|
||||||
}
|
}
|
||||||
if ((mask & DirMask.MASK_DOWN) && p.maskTo[Dir.DOWN]) { // y--
|
if ((mask & DirMask.MASK_DOWN) && p.maskTo[Dir.DOWN]) { // y--
|
||||||
planVisitingChunk(pos.x, pos.y - 8, pos.z, Dir.DOWN, p.maskTo[Dir.DOWN]);
|
planVisitingChunk(Vector3d(pos.x, pos.y - 8, pos.z), Dir.DOWN, p.maskTo[Dir.DOWN]);
|
||||||
}
|
}
|
||||||
if ((mask & DirMask.MASK_UP) && p.maskTo[Dir.UP]) { // y++
|
if ((mask & DirMask.MASK_UP) && p.maskTo[Dir.UP]) { // y++
|
||||||
planVisitingChunk(pos.x, pos.y + 8, pos.z, Dir.UP, p.maskTo[Dir.UP]);
|
planVisitingChunk(Vector3d(pos.x, pos.y + 8, pos.z), Dir.UP, p.maskTo[Dir.UP]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void start(World world, Vector3d startPos) {
|
void start(World world, Vector3d startPos, int maxDistance) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.startChunk = world.getCellChunk(startPos.x, startPos.y, startPos.z);
|
this.startChunk = world.getCellChunk(startPos.x, startPos.y, startPos.z);
|
||||||
this.startPos = this.startChunk.position; // position aligned by 8 cells
|
//if (!startChunk)
|
||||||
|
// return;
|
||||||
|
startPos.x &= ~7;
|
||||||
|
startPos.y &= ~7;
|
||||||
|
startPos.z &= ~7;
|
||||||
|
this.startPos = startPos; // position aligned by 8 cells
|
||||||
plannedChunks.assumeSafeAppend;
|
plannedChunks.assumeSafeAppend;
|
||||||
plannedChunks.length = 0;
|
plannedChunks.length = 0;
|
||||||
visitedChunks.assumeSafeAppend;
|
visitedChunks.assumeSafeAppend;
|
||||||
visitedChunks.length = 0;
|
visitedChunks.length = 0;
|
||||||
|
maxDistanceSquared = maxDistance * maxDistance;
|
||||||
|
this.maxDistance = maxDistance;
|
||||||
}
|
}
|
||||||
void visitVisibleChunks(ChunkVisitor visitor) {
|
Vector3d cameraDirection;
|
||||||
|
void visitVisibleChunks(ChunkVisitor visitor, Vector3d cameraDirection) {
|
||||||
this.visitor = visitor;
|
this.visitor = visitor;
|
||||||
|
this.cameraDirection = cameraDirection;
|
||||||
|
Vector3d cameraOffset = cameraDirection;
|
||||||
|
cameraOffset.x /= 16;
|
||||||
|
cameraOffset.y /= 16;
|
||||||
|
cameraOffset.z /= 16;
|
||||||
|
this.camPos = startPos - cameraOffset;
|
||||||
|
//if (!startChunk)
|
||||||
|
// return;
|
||||||
visitor.visit(world, startChunk);
|
visitor.visit(world, startChunk);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.NORTH))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.NORTH) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x, startPos.y, startPos.z - 8, Dir.NORTH, mask);
|
planVisitingChunk(Vector3d(startPos.x, startPos.y, startPos.z - 8), Dir.NORTH, mask);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.SOUTH))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.SOUTH) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x, startPos.y, startPos.z + 8, Dir.SOUTH, mask);
|
planVisitingChunk(Vector3d(startPos.x, startPos.y, startPos.z + 8), Dir.SOUTH, mask);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.WEST))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.WEST) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x - 8, startPos.y, startPos.z, Dir.WEST, mask);
|
planVisitingChunk(Vector3d(startPos.x - 8, startPos.y, startPos.z), Dir.WEST, mask);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.EAST))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.EAST) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x + 8, startPos.y, startPos.z, Dir.EAST, mask);
|
planVisitingChunk(Vector3d(startPos.x + 8, startPos.y, startPos.z), Dir.EAST, mask);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.DOWN))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.DOWN) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x, startPos.y - 8, startPos.z, Dir.DOWN, mask);
|
planVisitingChunk(Vector3d(startPos.x, startPos.y - 8, startPos.z), Dir.DOWN, mask);
|
||||||
if (auto mask = startChunk.getSideCanPassToMask(Dir.UP))
|
if (auto mask = startChunk ? startChunk.getSideCanPassToMask(Dir.UP) : 0xFFFFFFFFFFFFFFFFL)
|
||||||
planVisitingChunk(startPos.x, startPos.y + 8, startPos.z, Dir.UP, mask);
|
planVisitingChunk(Vector3d(startPos.x, startPos.y + 8, startPos.z), Dir.UP, mask);
|
||||||
|
for (int d = 0; d < maxDistance; d += 5) {
|
||||||
|
if (!plannedChunks.length)
|
||||||
|
break;
|
||||||
|
visitPlannedChunks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,14 @@ struct Vector3d {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dot(ref Vector3d v) {
|
||||||
|
return x * v.x + y * v.y + z * v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
int squaredLength() {
|
||||||
|
return x*x + y*y + z*z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared const Vector3d ZERO3 = Vector3d(0, 0, 0);
|
__gshared const Vector3d ZERO3 = Vector3d(0, 0, 0);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import dminer.core.chunk;
|
||||||
version (Android) {
|
version (Android) {
|
||||||
const int MAX_VIEW_DISTANCE = 60;
|
const int MAX_VIEW_DISTANCE = 60;
|
||||||
} else {
|
} else {
|
||||||
const int MAX_VIEW_DISTANCE = 90;
|
const int MAX_VIEW_DISTANCE = 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
||||||
import dlangui.graphics.scene.node;
|
import dlangui.graphics.scene.node;
|
||||||
private World _world;
|
private World _world;
|
||||||
private ChunkDiamondVisitor _chunkVisitor;
|
private ChunkDiamondVisitor _chunkVisitor;
|
||||||
|
private VisibilityCheckIterator _chunkIterator;
|
||||||
private Vector3d _pos;
|
private Vector3d _pos;
|
||||||
private Node3d _node;
|
private Node3d _node;
|
||||||
private Camera _cam;
|
private Camera _cam;
|
||||||
|
@ -82,14 +83,20 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
||||||
/// override it
|
/// override it
|
||||||
_node = node;
|
_node = node;
|
||||||
//Log.d("drawing Miner scene");
|
//Log.d("drawing Miner scene");
|
||||||
_chunkVisitor.init(_world, MAX_VIEW_DISTANCE, this);
|
_chunkIterator.start(_world, _world.camPosition.pos, MAX_VIEW_DISTANCE);
|
||||||
|
//_chunkVisitor.init(_world, MAX_VIEW_DISTANCE, this);
|
||||||
_pos = _world.camPosition.pos;
|
_pos = _world.camPosition.pos;
|
||||||
_camPosition = _cam.translation;
|
_camPosition = _cam.translation;
|
||||||
_camForwardVector = _cam.forwardVectorWorld;
|
_camForwardVector = _cam.forwardVectorWorld;
|
||||||
_camPosition -= _camForwardVector * 8;
|
_camPosition -= _camForwardVector * 8;
|
||||||
_skippedCount = _drawnCount = 0;
|
_skippedCount = _drawnCount = 0;
|
||||||
long ts = currentTimeMillis();
|
long ts = currentTimeMillis();
|
||||||
_chunkVisitor.visitChunks(_pos);
|
//_chunkVisitor.visitChunks(_pos);
|
||||||
|
Vector3d camVector;
|
||||||
|
camVector.x = cast(int)(_camForwardVector.x * 256);
|
||||||
|
camVector.y = cast(int)(_camForwardVector.y * 256);
|
||||||
|
camVector.z = cast(int)(_camForwardVector.z * 256);
|
||||||
|
_chunkIterator.visitVisibleChunks(this, camVector);
|
||||||
long duration = currentTimeMillis() - ts;
|
long duration = currentTimeMillis() - ts;
|
||||||
Log.d("drawing of Miner scene finished in ", duration, " ms skipped:", _skippedCount, " drawn:", _drawnCount);
|
Log.d("drawing of Miner scene finished in ", duration, " ms skipped:", _skippedCount, " drawn:", _drawnCount);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +106,7 @@ class MinerDrawable : MaterialDrawableObject, ChunkVisitor {
|
||||||
vec3 chunkPos = vec3(p.x + 4, p.y + 4, p.z + 4);
|
vec3 chunkPos = vec3(p.x + 4, p.y + 4, p.z + 4);
|
||||||
vec3 chunkDirection = (chunkPos - _camPosition).normalized;
|
vec3 chunkDirection = (chunkPos - _camPosition).normalized;
|
||||||
float dot = _camForwardVector.dot(chunkDirection);
|
float dot = _camForwardVector.dot(chunkDirection);
|
||||||
//Log.d("chunkPos ", chunkPos, " chunkDir ", chunkDirection, " camDir ");
|
//Log.d("visit() chunkPos ", chunkPos, " chunkDir ", chunkDirection, " camDir ");
|
||||||
if (dot < 0.7) { // cos(45)
|
if (dot < 0.7) { // cos(45)
|
||||||
_skippedCount++;
|
_skippedCount++;
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue