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;
/**
* 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
*/
@ -95,6 +115,11 @@ public class ClientDrawCellManager {
*/
int generated = 0;
/**
* Tracks whether the cell manager has initialized or not
*/
boolean initialized = false;
/**
* Constructor
* @param voxelTextureAtlas The voxel texture atlas
@ -115,12 +140,18 @@ public class ClientDrawCellManager {
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
//the sets to iterate through
updatedLastFrame = true;
int attempts = 0;
validCellCount = 0;
while(updatedLastFrame && attempts < UPDATE_ATTEMPTS_PER_FRAME){
FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos);
attempts++;
//update all full res cells
FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerPos, HALF_RES_LOD);
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();
@ -130,9 +161,10 @@ public class ClientDrawCellManager {
* Recursively update child nodes
* @param node The root node
* @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
*/
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos){
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3d playerPos, int minLeafLod){
Vector3d playerRealPos = EntityUtils.getPosition(Globals.playerEntity);
boolean updated = false;
if(this.shouldSplit(playerPos, node)){
@ -176,15 +208,20 @@ public class ClientDrawCellManager {
Globals.profiler.endCpuSample();
updated = true;
} else if(shouldRequest(playerPos, node)){
} else if(shouldRequest(playerPos, node, minLeafLod)){
Globals.profiler.beginCpuSample("ClientDrawCellManager.request");
//calculate what to request
DrawCell cell = node.getData();
List<DrawCellFace> highResFaces = this.solveHighResFace(node);
//actually send requests
this.requestChunks(node, highResFaces);
cell.setHasRequested(true);
Globals.profiler.endCpuSample();
updated = true;
} else if(shouldGenerate(playerPos, node)){
} else if(shouldGenerate(playerPos, node, minLeafLod)){
Globals.profiler.beginCpuSample("ClientDrawCellManager.generate");
int lodLevel = this.getLODLevel(playerRealPos, node);
List<DrawCellFace> highResFaces = this.solveHighResFace(node);
@ -205,7 +242,7 @@ public class ClientDrawCellManager {
this.validCellCount++;
List<FloatingChunkTreeNode<DrawCell>> children = new LinkedList<FloatingChunkTreeNode<DrawCell>>(node.getChildren());
for(FloatingChunkTreeNode<DrawCell> child : children){
boolean childUpdate = recursivelyUpdateCells(child, playerPos);
boolean childUpdate = recursivelyUpdateCells(child, playerPos, minLeafLod);
if(childUpdate == true){
updated = true;
}
@ -414,13 +451,15 @@ public class ClientDrawCellManager {
* Checks if this cell should request chunk data
* @param pos the player's position
* @param node the node
* @param minLeafLod The minimum LOD required to evaluate a leaf
* @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
node.isLeaf() &&
node.getData() != null &&
!node.getData().hasRequested() &&
(this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod &&
(
(
node.getLevel() == this.chunkTree.getMaxLevel()
@ -453,13 +492,15 @@ public class ClientDrawCellManager {
* Checks if this cell should generate
* @param pos the player's position
* @param node the node
* @param minLeafLod The minimum LOD required to evaluate a leaf
* @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
node.isLeaf() &&
node.getData() != null &&
!node.getData().hasGenerated() &&
(this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod &&
(
(
node.getLevel() == this.chunkTree.getMaxLevel()
@ -788,6 +829,14 @@ public class ClientDrawCellManager {
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);
//wait for all the terrain data to arrive
int i = 0;
while(blockForInit && Globals.clientDrawCellManager.updatedLastFrame() && Globals.threadManager.shouldKeepRunning()){
while(
blockForInit &&
!Globals.clientDrawCellManager.isInitialized() &&
Globals.threadManager.shouldKeepRunning()
){
i++;
if(i % DRAW_CELL_UPDATE_RATE == 0){
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
*/
public static final int GENERATOR_REALM_SIZE = 32;
public static final int GENERATOR_REALM_SIZE = 64;
/**
* The default biome index