From d06d5d450658d77180daff2eb6f81e8ec0646955 Mon Sep 17 00:00:00 2001 From: austin Date: Mon, 11 Nov 2024 17:07:30 -0500 Subject: [PATCH] homogenous value fixes --- docs/src/progress/renderertodo.md | 7 +- .../client/terrain/cache/ChunkData.java | 5 + .../terrain/cells/ClientDrawCellManager.java | 9 +- .../client/terrain/cells/DrawCell.java | 130 ++++++++++-------- .../terrain/manager/ClientTerrainManager.java | 54 ++++---- .../entity/types/terrain/TerrainChunk.java | 2 +- .../net/server/protocol/TerrainProtocol.java | 35 +++-- .../TestGenerationChunkGenerator.java | 4 +- .../terrain/manager/ServerTerrainChunk.java | 1 + 9 files changed, 136 insertions(+), 111 deletions(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 8cf86f76..29c0374e 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -997,10 +997,9 @@ Potential physics destruction fix Join propagation further up tree Lower client cache size (to fight memory stalling) Manual free button on memory debug window - - -passing chunk data between nodes -storing min lod of children at every level of tree +Passing chunk data between nodes +Fix homogenous value propagating from chunk gen to client cache +Fix homogenous value joining on client diff --git a/src/main/java/electrosphere/client/terrain/cache/ChunkData.java b/src/main/java/electrosphere/client/terrain/cache/ChunkData.java index ff5cc02f..991759e5 100644 --- a/src/main/java/electrosphere/client/terrain/cache/ChunkData.java +++ b/src/main/java/electrosphere/client/terrain/cache/ChunkData.java @@ -22,6 +22,11 @@ public class ChunkData { */ public static final int NOT_HOMOGENOUS = -1; + /** + * The weight of a cell in a homogenous chunk + */ + public static final float HOMOGENOUS_WEIGHT = 1.0f; + /** * The size of the chunk data stored on the client */ diff --git a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java index 21b982cc..be764f03 100644 --- a/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/ClientDrawCellManager.java @@ -320,7 +320,9 @@ public class ClientDrawCellManager { } } if(isHomogenous){ - this.join(node); + WorldOctTreeNode newNode = this.join(node); + newNode.getData().setHasGenerated(true); + newNode.getData().setHomogenous(true); } if((this.chunkTree.getMaxLevel() - node.getLevel()) < minLeafLod){ evaluationMap.put(node,true); @@ -391,7 +393,7 @@ public class ClientDrawCellManager { return node.canSplit() && (node.getLevel() != this.chunkTree.getMaxLevel()) && - (!node.getData().hasGenerated() || !node.getData().isHomogenous()) && + !node.getData().isHomogenous() && (node.getParent() != null || node == this.chunkTree.getRoot()) && ( ( @@ -614,7 +616,7 @@ public class ClientDrawCellManager { * Joins a parent node * @param node The parent node */ - private void join(WorldOctTreeNode node){ + private WorldOctTreeNode join(WorldOctTreeNode node){ Globals.profiler.beginCpuSample("ClientDrawCellManager.join"); //perform op WorldOctTreeNode newLeaf = chunkTree.join(node, DrawCell.generateTerrainCell(node.getMinBound(),node.getData().lod)); @@ -628,6 +630,7 @@ public class ClientDrawCellManager { evaluationMap.put(newLeaf,true); Globals.profiler.endCpuSample(); + return newLeaf; } /** diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java index a7906ab1..15ec72fb 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java @@ -66,7 +66,7 @@ public class DrawCell { /** * Tracks whether this draw cell is flagged as homogenous from the server or not */ - boolean homogenous = true; + boolean homogenous = false; /** * Number of failed generation attempts @@ -251,17 +251,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + 0, + localCoord1, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + 0, + localCoord1, + localCoord2 + ); } - faceWeights[x][y] = currentChunk.getWeight( - 0, - localCoord1, - localCoord2 - ); - faceTypes[x][y] = currentChunk.getType( - 0, - localCoord1, - localCoord2 - ); } break; case X_NEGATIVE: { ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( @@ -277,17 +277,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + 0, + localCoord1, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + 0, + localCoord1, + localCoord2 + ); } - faceWeights[x][y] = currentChunk.getWeight( - 0, - localCoord1, - localCoord2 - ); - faceTypes[x][y] = currentChunk.getType( - 0, - localCoord1, - localCoord2 - ); } break; case Y_POSITIVE: { ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( @@ -303,17 +303,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + 0, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + 0, + localCoord2 + ); } - faceWeights[x][y] = currentChunk.getWeight( - localCoord1, - 0, - localCoord2 - ); - faceTypes[x][y] = currentChunk.getType( - localCoord1, - 0, - localCoord2 - ); } break; case Y_NEGATIVE: { ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( @@ -329,17 +329,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + 0, + localCoord2 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + 0, + localCoord2 + ); } - faceWeights[x][y] = currentChunk.getWeight( - localCoord1, - 0, - localCoord2 - ); - faceTypes[x][y] = currentChunk.getType( - localCoord1, - 0, - localCoord2 - ); } break; case Z_POSITIVE: { ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( @@ -355,17 +355,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + localCoord2, + 0 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + localCoord2, + 0 + ); } - faceWeights[x][y] = currentChunk.getWeight( - localCoord1, - localCoord2, - 0 - ); - faceTypes[x][y] = currentChunk.getType( - localCoord1, - localCoord2, - 0 - ); } break; case Z_NEGATIVE: { ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint( @@ -381,17 +381,17 @@ public class DrawCell { } if(currentChunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ this.homogenous = false; + faceWeights[x][y] = currentChunk.getWeight( + localCoord1, + localCoord2, + 0 + ); + faceTypes[x][y] = currentChunk.getType( + localCoord1, + localCoord2, + 0 + ); } - faceWeights[x][y] = currentChunk.getWeight( - localCoord1, - localCoord2, - 0 - ); - faceTypes[x][y] = currentChunk.getType( - localCoord1, - localCoord2, - 0 - ); } break; } // Vector3i sampleChunkWorldPos = new Vector3i( @@ -473,6 +473,14 @@ public class DrawCell { this.hasGenerated = hasGenerated; } + /** + * Sets whether this draw cell is homogenous or not + * @param hasGenerated true if is homogenous, false otherwise + */ + public void setHomogenous(boolean homogenous) { + this.homogenous = homogenous; + } + /** * Gets whether this draw cell will generate polygons or not * @return true if it has polygons, false otherwise diff --git a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java index 035a81ff..31e60645 100644 --- a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java +++ b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java @@ -123,36 +123,38 @@ public class ClientTerrainManager { ); } break; case SENDREDUCEDCHUNKDATA: { - int[][][] values = new int[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE]; - float[][][] weights = new float[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE]; - ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData()); - FloatBuffer floatBuffer = buffer.asFloatBuffer(); - for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){ - for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){ - for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){ - weights[x][y][z] = floatBuffer.get(); - } - } - } - IntBuffer intView = buffer.asIntBuffer(); - intView.position(floatBuffer.position()); - int firstType = -1; - boolean homogenous = true; - for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){ - for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){ - for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){ - values[x][y][z] = intView.get(); - if(firstType == -1){ - firstType = values[x][y][z]; - } else if(homogenous && firstType == values[x][y][z]){ - homogenous = false; + ChunkData data = new ChunkData(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution(), message.gethomogenousValue()); + if(message.gethomogenousValue() == ChunkData.NOT_HOMOGENOUS){ + int[][][] values = new int[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE]; + float[][][] weights = new float[ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE][ChunkData.CHUNK_DATA_SIZE]; + ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData()); + FloatBuffer floatBuffer = buffer.asFloatBuffer(); + for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){ + for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){ + for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){ + weights[x][y][z] = floatBuffer.get(); } } } + IntBuffer intView = buffer.asIntBuffer(); + intView.position(floatBuffer.position()); + int firstType = -1; + boolean homogenous = true; + for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){ + for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){ + for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){ + values[x][y][z] = intView.get(); + if(firstType == -1){ + firstType = values[x][y][z]; + } else if(homogenous && firstType == values[x][y][z]){ + homogenous = false; + } + } + } + } + data.setVoxelType(values); + data.setVoxelWeight(weights); } - ChunkData data = new ChunkData(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution(),homogenous ? firstType : ChunkData.NOT_HOMOGENOUS); - data.setVoxelType(values); - data.setVoxelWeight(weights); terrainCache.addChunkDataToCache( message.getworldX(), message.getworldY(), message.getworldZ(), data diff --git a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java index a8920194..e40b0520 100644 --- a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java +++ b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java @@ -45,7 +45,7 @@ public class TerrainChunk { Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - if(hasPolygons){ + if(hasPolygons && chunkData.terrainGrid != null && chunkData.textureGrid != null){ generationService.submit(() -> { TerrainChunkData data; try { diff --git a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java index 275b1cf7..622ae5ac 100644 --- a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java @@ -222,31 +222,38 @@ public class TerrainProtocol implements ServerProtocolTemplate { int yWidth = chunk.getWeights()[0].length; int zWidth = chunk.getWeights()[0][0].length; - ByteBuffer buffer = ByteBuffer.allocate(xWidth*yWidth*zWidth*(4+4)); - FloatBuffer floatView = buffer.asFloatBuffer(); + byte[] toSend = null; - for(int x = 0; x < xWidth; x++){ - for(int y = 0; y < yWidth; y++){ - for(int z = 0; z < zWidth; z++){ - floatView.put(chunk.getWeights()[x][y][z]); + if(chunk.getHomogenousValue() == ChunkData.NOT_HOMOGENOUS){ + ByteBuffer buffer = ByteBuffer.allocate(xWidth*yWidth*zWidth*(4+4)); + FloatBuffer floatView = buffer.asFloatBuffer(); + + for(int x = 0; x < xWidth; x++){ + for(int y = 0; y < yWidth; y++){ + for(int z = 0; z < zWidth; z++){ + floatView.put(chunk.getWeights()[x][y][z]); + } } } - } - IntBuffer intView = buffer.asIntBuffer(); - intView.position(floatView.position()); + IntBuffer intView = buffer.asIntBuffer(); + intView.position(floatView.position()); - for(int x = 0; x < xWidth; x++){ - for(int y = 0; y < yWidth; y++){ - for(int z = 0; z < zWidth; z++){ - intView.put(chunk.getValues()[x][y][z]); + for(int x = 0; x < xWidth; x++){ + for(int y = 0; y < yWidth; y++){ + for(int z = 0; z < zWidth; z++){ + intView.put(chunk.getValues()[x][y][z]); + } } } + toSend = buffer.array(); + } else { + toSend = new byte[]{ 0 }; } // System.out.println("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ); LoggerInterface.loggerNetworking.DEBUG("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ); - connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructSendReducedChunkDataMessage(worldX, worldY, worldZ, stride, chunk.getHomogenousValue(), buffer.array())); + connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructSendReducedChunkDataMessage(worldX, worldY, worldZ, stride, chunk.getHomogenousValue(), toSend)); }; //request chunk diff --git a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java index a9d10b3b..a781391f 100644 --- a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java @@ -96,7 +96,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];; int[][][] values = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; - int firstType = -1; + int firstType = -2; boolean homogenous = true; try { //actual generation algo @@ -182,7 +182,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { weights[x][y][z] = voxel.weight; values[x][y][z] = voxel.type; } - if(firstType == -1){ + if(firstType == -2){ firstType = values[x][y][z]; } else if(homogenous && firstType != values[x][y][z]){ homogenous = false; diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java index 94dd9185..d64d0ce0 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java @@ -75,6 +75,7 @@ public class ServerTerrainChunk { this.worldX = worldX; this.worldY = worldY; this.worldZ = worldZ; + this.homogenousValue = homogenousValue; this.weights = weights; this.values = values; }