diff --git a/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java b/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java index addfd30f..21ffcda9 100644 --- a/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java +++ b/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java @@ -32,10 +32,15 @@ public class ClientTerrainCache { Map cacheMapHalfRes = new ConcurrentHashMap(); /** - * The map of half res chunk key -> chunk data + * The map of quarter res chunk key -> chunk data */ Map cacheMapQuarterRes = new ConcurrentHashMap(); + /** + * The map of eighth res chunk key -> chunk data + */ + Map cacheMapEighthRes = new ConcurrentHashMap(); + /** * The list of keys in the cache */ @@ -154,6 +159,9 @@ public class ClientTerrainCache { case 2: { return cacheMapQuarterRes; } + case 3: { + return cacheMapEighthRes; + } default: { throw new Error("Invalid stride probided! " + stride); } diff --git a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java index ee30cc3e..1d9d0fcf 100644 --- a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java @@ -45,6 +45,11 @@ public class ClientDrawCellManager { */ public static final double QUARTER_RES_DIST = 20 * ServerTerrainChunk.CHUNK_DIMENSION; + /** + * The distance for eighth resolution + */ + public static final double EIGHTH_RES_DIST = 28 * ServerTerrainChunk.CHUNK_DIMENSION; + /** * The octree holding all the chunks to evaluate */ @@ -185,6 +190,9 @@ public class ClientDrawCellManager { List highResFaces = this.solveHighResFace(node); if(containsDataToGenerate(node,highResFaces)){ node.getData().generateDrawableEntity(textureAtlas, lodLevel, highResFaces); + if(node.getData().getFailedGenerationAttempts() > FAILED_GENERATION_ATTEMPT_THRESHOLD){ + node.getData().setHasRequested(false); + } } else if(node.getData() != null){ node.getData().setFailedGenerationAttempts(node.getData().getFailedGenerationAttempts() + 1); if(node.getData().getFailedGenerationAttempts() > FAILED_GENERATION_ATTEMPT_THRESHOLD){ @@ -231,6 +239,11 @@ public class ClientDrawCellManager { node.isLeaf() && node.canSplit() && ( + ( + node.getLevel() < this.chunkTree.getMaxLevel() - 3 && + this.getMinDistance(pos, node) <= EIGHTH_RES_DIST + ) + || ( node.getLevel() < this.chunkTree.getMaxLevel() - 2 && this.getMinDistance(pos, node) <= QUARTER_RES_DIST @@ -386,8 +399,13 @@ public class ClientDrawCellManager { ) || ( + node.getLevel() == this.chunkTree.getMaxLevel() - 3 && this.getMinDistance(pos, node) > QUARTER_RES_DIST ) + || + ( + this.getMinDistance(pos, node) > EIGHTH_RES_DIST + ) ) ; } @@ -415,11 +433,17 @@ public class ClientDrawCellManager { && this.getMinDistance(pos, node) <= QUARTER_RES_DIST ) - || + || ( node.getLevel() == this.chunkTree.getMaxLevel() - 2 && - this.getMinDistance(pos, node) <= QUARTER_RES_DIST + this.getMinDistance(pos, node) <= EIGHTH_RES_DIST + ) + || + ( + node.getLevel() == this.chunkTree.getMaxLevel() - 3 + && + this.getMinDistance(pos, node) <= EIGHTH_RES_DIST ) ) ; @@ -452,7 +476,13 @@ public class ClientDrawCellManager { ( node.getLevel() == this.chunkTree.getMaxLevel() - 2 && - this.getMinDistance(pos, node) <= QUARTER_RES_DIST + this.getMinDistance(pos, node) <= EIGHTH_RES_DIST + ) + || + ( + node.getLevel() == this.chunkTree.getMaxLevel() - 3 + && + this.getMinDistance(pos, node) <= EIGHTH_RES_DIST ) ) ; diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java index 239c04d8..d46a8719 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java @@ -121,8 +121,7 @@ public class DrawCell { boolean success = this.fillInData(lod); Globals.profiler.endCpuSample(); if(!success){ - this.setHasRequested(false); - this.failedGenerationAttempts++; + this.setFailedGenerationAttempts(this.getFailedGenerationAttempts() + 1); return; } if(modelEntity != null){ @@ -135,8 +134,7 @@ public class DrawCell { success = this.fillInFaceData(chunkData,face,lod); Globals.profiler.endCpuSample(); if(!success){ - this.setHasRequested(false); - this.failedGenerationAttempts++; + this.setFailedGenerationAttempts(this.getFailedGenerationAttempts() + 1); return; } } @@ -199,24 +197,39 @@ public class DrawCell { for(int y = 0; y < ChunkData.CHUNK_DATA_GENERATOR_SIZE; y++){ for(int z = 0; z < ChunkData.CHUNK_DATA_GENERATOR_SIZE; z++){ ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( - worldPos.x + x / ChunkData.CHUNK_SIZE * spacingFactor, - worldPos.y + y / ChunkData.CHUNK_SIZE * spacingFactor, - worldPos.z + z / ChunkData.CHUNK_SIZE * spacingFactor, + worldPos.x + (x / ChunkData.CHUNK_SIZE) * spacingFactor, + worldPos.y + (y / ChunkData.CHUNK_SIZE) * spacingFactor, + worldPos.z + (z / ChunkData.CHUNK_SIZE) * spacingFactor, lod ); if(currentChunk == null){ - return false; + Vector3i posToCheck = new Vector3i( + worldPos.x + (x / ChunkData.CHUNK_SIZE) * spacingFactor, + worldPos.y + (y / ChunkData.CHUNK_SIZE) * spacingFactor, + worldPos.z + (z / ChunkData.CHUNK_SIZE) * spacingFactor + ); + if( + posToCheck.x >= 0 && + posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() && + posToCheck.y >= 0 && + posToCheck.y < Globals.clientWorldData.getWorldDiscreteSize() && + posToCheck.z >= 0 && + posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() + ){ + return false; + } + } else { + weights[x][y][z] = currentChunk.getWeight( + x % ChunkData.CHUNK_SIZE, + y % ChunkData.CHUNK_SIZE, + z % ChunkData.CHUNK_SIZE + ); + types[x][y][z] = currentChunk.getType( + x % ChunkData.CHUNK_SIZE, + y % ChunkData.CHUNK_SIZE, + z % ChunkData.CHUNK_SIZE + ); } - weights[x][y][z] = currentChunk.getWeight( - x % ChunkData.CHUNK_SIZE, - y % ChunkData.CHUNK_SIZE, - z % ChunkData.CHUNK_SIZE - ); - types[x][y][z] = currentChunk.getType( - x % ChunkData.CHUNK_SIZE, - y % ChunkData.CHUNK_SIZE, - z % ChunkData.CHUNK_SIZE - ); //checks to see if there is only one type of voxel in this chunk if(!this.multiVoxelType){ @@ -512,7 +525,7 @@ public class DrawCell { * @param attempts The number of failed generation attempts */ public void setFailedGenerationAttempts(int attempts){ - failedGenerationAttempts = failedGenerationAttempts + 1; + this.failedGenerationAttempts = this.failedGenerationAttempts + attempts; } diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerChunkCache.java b/src/main/java/electrosphere/server/terrain/manager/ServerChunkCache.java index 6700cac7..633e49a7 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerChunkCache.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerChunkCache.java @@ -41,6 +41,11 @@ public class ServerChunkCache { */ Map cacheMapQuarterRes = new ConcurrentHashMap(); + /** + * The map of eighth res chunk key -> chunk data + */ + Map cacheMapEighthRes = new ConcurrentHashMap(); + /** * Tracks how recently a chunk has been queries for (used for evicting old chunks from cache) */ @@ -200,6 +205,9 @@ public class ServerChunkCache { case 2: { return cacheMapQuarterRes; } + case 3: { + return cacheMapEighthRes; + } default: { throw new Error("Invalid stride probided! " + stride); }