stratified updates to client cell manager
Some checks failed
studiorailgun/Renderer/pipeline/pr-master There was a failure building this commit

This commit is contained in:
austin 2024-11-07 11:44:51 -05:00
parent 7493c1128b
commit e6fdac489c
3 changed files with 66 additions and 13 deletions

View File

@ -50,6 +50,26 @@ public class ClientDrawCellManager {
*/ */
public static final double EIGHTH_RES_DIST = 28 * ServerTerrainChunk.CHUNK_DIMENSION; public static final double EIGHTH_RES_DIST = 28 * ServerTerrainChunk.CHUNK_DIMENSION;
/**
* Lod value for a full res chunk
*/
public static final int FULL_RES_LOD = 0;
/**
* Lod value for a half res chunk
*/
public static final int HALF_RES_LOD = 1;
/**
* Lod value for a quarter res chunk
*/
public static final int QUARTER_RES_LOD = 2;
/**
* Lod value for a eighth res chunk
*/
public static final int EIGHTH_RES_LOD = 3;
/** /**
* The octree holding all the chunks to evaluate * The octree holding all the chunks to evaluate
*/ */
@ -95,6 +115,11 @@ public class ClientDrawCellManager {
*/ */
int generated = 0; int generated = 0;
/**
* Tracks whether the cell manager has initialized or not
*/
boolean initialized = false;
/** /**
* Constructor * Constructor
* @param voxelTextureAtlas The voxel texture atlas * @param voxelTextureAtlas The voxel texture atlas
@ -115,12 +140,18 @@ public class ClientDrawCellManager {
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
//the sets to iterate through //the sets to iterate through
updatedLastFrame = true; updatedLastFrame = true;
int attempts = 0;
validCellCount = 0; validCellCount = 0;
while(updatedLastFrame && attempts < UPDATE_ATTEMPTS_PER_FRAME){ //update all full res cells
FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot(); FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos); updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, HALF_RES_LOD);
attempts++; if(!updatedLastFrame && !this.initialized){
this.initialized = true;
}
if(!updatedLastFrame){
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, QUARTER_RES_LOD);
}
if(!updatedLastFrame){
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, EIGHTH_RES_LOD);
} }
} }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
@ -130,9 +161,10 @@ public class ClientDrawCellManager {
* Recursively update child nodes * Recursively update child nodes
* @param node The root node * @param node The root node
* @param playerPos The player's position * @param playerPos The player's position
* @param minLeafLod The minimum LOD required to evaluate a leaf
* @return true if there is work remaining to be done, false otherwise * @return true if there is work remaining to be done, false otherwise
*/ */
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos){ private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos, int minLeafLod){
Vector3d playerRealPos = EntityUtils.getPosition(Globals.playerEntity); Vector3d playerRealPos = EntityUtils.getPosition(Globals.playerEntity);
boolean updated = false; boolean updated = false;
if(this.shouldSplit(playerPos, node)){ if(this.shouldSplit(playerPos, node)){
@ -176,15 +208,20 @@ public class ClientDrawCellManager {
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
updated = true; updated = true;
} else if(shouldRequest(playerPos, node)){ } else if(shouldRequest(playerPos, node, minLeafLod)){
Globals.profiler.beginCpuSample("ClientDrawCellManager.request"); Globals.profiler.beginCpuSample("ClientDrawCellManager.request");
//calculate what to request
DrawCell cell = node.getData(); DrawCell cell = node.getData();
List<DrawCellFace> highResFaces = this.solveHighResFace(node); List<DrawCellFace> highResFaces = this.solveHighResFace(node);
//actually send requests
this.requestChunks(node, highResFaces); this.requestChunks(node, highResFaces);
cell.setHasRequested(true); cell.setHasRequested(true);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
updated = true; updated = true;
} else if(shouldGenerate(playerPos, node)){ } else if(shouldGenerate(playerPos, node, minLeafLod)){
Globals.profiler.beginCpuSample("ClientDrawCellManager.generate"); Globals.profiler.beginCpuSample("ClientDrawCellManager.generate");
int lodLevel = this.getLODLevel(playerRealPos, node); int lodLevel = this.getLODLevel(playerRealPos, node);
List<DrawCellFace> highResFaces = this.solveHighResFace(node); List<DrawCellFace> highResFaces = this.solveHighResFace(node);
@ -205,7 +242,7 @@ public class ClientDrawCellManager {
this.validCellCount++; this.validCellCount++;
List<FloatingChunkTreeNode<DrawCell>> children = new LinkedList<FloatingChunkTreeNode<DrawCell>>(node.getChildren()); List<FloatingChunkTreeNode<DrawCell>> children = new LinkedList<FloatingChunkTreeNode<DrawCell>>(node.getChildren());
for(FloatingChunkTreeNode<DrawCell> child : children){ for(FloatingChunkTreeNode<DrawCell> child : children){
boolean childUpdate = recursivelyUpdateCells(child, playerPos); boolean childUpdate = recursivelyUpdateCells(child, playerPos, minLeafLod);
if(childUpdate == true){ if(childUpdate == true){
updated = true; updated = true;
} }
@ -414,13 +451,15 @@ public class ClientDrawCellManager {
* Checks if this cell should request chunk data * Checks if this cell should request chunk data
* @param pos the player's position * @param pos the player's position
* @param node the node * @param node the node
* @param minLeafLod The minimum LOD required to evaluate a leaf
* @return true if should request chunk data, false otherwise * @return true if should request chunk data, false otherwise
*/ */
public boolean shouldRequest(Vector3d pos, FloatingChunkTreeNode<DrawCell> node){ public boolean shouldRequest(Vector3d pos, FloatingChunkTreeNode<DrawCell> node, int minLeafLod){
return return
node.isLeaf() && node.isLeaf() &&
node.getData() != null && node.getData() != null &&
!node.getData().hasRequested() && !node.getData().hasRequested() &&
(this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod &&
( (
( (
node.getLevel() == this.chunkTree.getMaxLevel() node.getLevel() == this.chunkTree.getMaxLevel()
@ -453,13 +492,15 @@ public class ClientDrawCellManager {
* Checks if this cell should generate * Checks if this cell should generate
* @param pos the player's position * @param pos the player's position
* @param node the node * @param node the node
* @param minLeafLod The minimum LOD required to evaluate a leaf
* @return true if should generate, false otherwise * @return true if should generate, false otherwise
*/ */
public boolean shouldGenerate(Vector3d pos, FloatingChunkTreeNode<DrawCell> node){ public boolean shouldGenerate(Vector3d pos, FloatingChunkTreeNode<DrawCell> node, int minLeafLod){
return return
node.isLeaf() && node.isLeaf() &&
node.getData() != null && node.getData() != null &&
!node.getData().hasGenerated() && !node.getData().hasGenerated() &&
(this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod &&
( (
( (
node.getLevel() == this.chunkTree.getMaxLevel() node.getLevel() == this.chunkTree.getMaxLevel()
@ -788,6 +829,14 @@ public class ClientDrawCellManager {
return generated; return generated;
} }
/**
* Gets whether the client draw cell manager has initialized or not
* @return true if it has initialized, false otherwise
*/
public boolean isInitialized(){
return this.initialized;
}
} }

View File

@ -297,7 +297,11 @@ public class ClientLoading {
Globals.clientSimulation.setLoadingTerrain(true); Globals.clientSimulation.setLoadingTerrain(true);
//wait for all the terrain data to arrive //wait for all the terrain data to arrive
int i = 0; int i = 0;
while(blockForInit && Globals.clientDrawCellManager.updatedLastFrame() && Globals.threadManager.shouldKeepRunning()){ while(
blockForInit &&
!Globals.clientDrawCellManager.isInitialized() &&
Globals.threadManager.shouldKeepRunning()
){
i++; i++;
if(i % DRAW_CELL_UPDATE_RATE == 0){ if(i % DRAW_CELL_UPDATE_RATE == 0){
WindowUtils.updateLoadingWindow("WAITING ON SERVER TO SEND TERRAIN (" + Globals.clientTerrainManager.getAllChunks().size() + ")"); WindowUtils.updateLoadingWindow("WAITING ON SERVER TO SEND TERRAIN (" + Globals.clientTerrainManager.getAllChunks().size() + ")");

View File

@ -24,7 +24,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
/** /**
* The size of the realm for testing generation * The size of the realm for testing generation
*/ */
public static final int GENERATOR_REALM_SIZE = 32; public static final int GENERATOR_REALM_SIZE = 64;
/** /**
* The default biome index * The default biome index