Add stride to reduced endpoint
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-05 14:47:08 -05:00
parent 4f639cc6be
commit 0320173800
9 changed files with 94 additions and 9 deletions

View File

@ -12,6 +12,11 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk;
*/ */
public class ChunkData { public class ChunkData {
/**
* No stride
*/
public static final int NO_STRIDE = 0;
//The size of a chunk in virtual data //The size of a chunk in virtual data
public static final int CHUNK_SIZE = ServerTerrainChunk.CHUNK_DIMENSION; public static final int CHUNK_SIZE = ServerTerrainChunk.CHUNK_DIMENSION;
//The size of the data passed into marching cubes/transvoxel algorithm to get a fully connected and seamless chunk //The size of the data passed into marching cubes/transvoxel algorithm to get a fully connected and seamless chunk

View File

@ -47,6 +47,10 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ()); LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
Globals.clientTerrainManager.attachTerrainMessage(message); Globals.clientTerrainManager.attachTerrainMessage(message);
} break; } break;
case SENDREDUCEDCHUNKDATA: {
LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ() + " " + message.getchunkResolution());
Globals.clientTerrainManager.attachTerrainMessage(message);
} break;
case UPDATEVOXEL: { case UPDATEVOXEL: {
// //
//find what all drawcells might be updated by this voxel update //find what all drawcells might be updated by this voxel update

View File

@ -7,6 +7,7 @@ import java.util.function.Consumer;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.net.parser.net.message.TerrainMessage;
@ -32,6 +33,12 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
); );
return null; return null;
} }
case REQUESTREDUCEDCHUNKDATA: {
sendWorldSubChunkAsyncStrided(connectionHandler,
message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()
);
return null;
}
default: { default: {
} break; } break;
} }
@ -185,7 +192,65 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
}; };
//request chunk //request chunk
realm.getServerWorldData().getServerTerrainManager().getChunkAsync(worldX, worldY, worldZ, onLoad); realm.getServerWorldData().getServerTerrainManager().getChunkAsync(worldX, worldY, worldZ, ChunkData.NO_STRIDE, onLoad);
Globals.profiler.endCpuSample();
}
/**
* Sends a subchunk to the client
* @param connectionHandler The connection handler
* @param worldX the world x
* @param worldY the world y
* @param worldZ the world z
* @param stride The stride of the data
*/
static void sendWorldSubChunkAsyncStrided(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ, int stride){
Globals.profiler.beginAggregateCpuSample("TerrainProtocol(server).sendWorldSubChunk");
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
Realm realm = Globals.playerManager.getPlayerRealm(connectionHandler.getPlayer());
if(realm.getServerWorldData().getServerTerrainManager() == null){
return;
}
Consumer<ServerTerrainChunk> onLoad = (ServerTerrainChunk chunk) -> {
//The length along each access of the chunk data. Typically, should be at least 17.
//Because CHUNK_SIZE is 16, 17 adds the necessary extra value. Each chunk needs the value of the immediately following position to generate
//chunk data that connects seamlessly to the next chunk.
int xWidth = chunk.getWeights().length;
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();
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());
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]);
}
}
}
// System.out.println("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ);
LoggerInterface.loggerNetworking.DEBUG("(Server) Send terrain at " + worldX + " " + worldY + " " + worldZ);
connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructsendChunkDataMessage(worldX, worldY, worldZ, buffer.array()));
};
//request chunk
realm.getServerWorldData().getServerTerrainManager().getChunkAsync(worldX, worldY, worldZ, stride, onLoad);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }

View File

@ -22,7 +22,7 @@ public class DefaultChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ) { public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride) {
//Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap. //Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap.
//Hence, width should actually be chunk dimension + 1 //Hence, width should actually be chunk dimension + 1
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];

View File

@ -28,7 +28,7 @@ public class OverworldChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ) { public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride) {
ServerTerrainChunk returnedChunk; ServerTerrainChunk returnedChunk;
//Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap. //Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap.
//Hence, width should actually be chunk dimension + 1 //Hence, width should actually be chunk dimension + 1

View File

@ -65,7 +65,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
} }
@Override @Override
public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ) { public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride) {
Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk"); Globals.profiler.beginAggregateCpuSample("TestGenerationChunkGenerator.generateChunk");
ServerTerrainChunk rVal = null; ServerTerrainChunk rVal = null;
float[][][] weights; float[][][] weights;

View File

@ -13,9 +13,10 @@ public interface ChunkGenerator {
* @param worldX The x component * @param worldX The x component
* @param worldY The y component * @param worldY The y component
* @param worldZ The z component * @param worldZ The z component
* @param stride The stride of the data
* @return The chunk * @return The chunk
*/ */
public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ); public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ, int stride);
/** /**
* Sets the terrain model for the generation algorithm * Sets the terrain model for the generation algorithm

View File

@ -51,6 +51,11 @@ public class ChunkGenerationThread implements Runnable {
* The world z coordinate * The world z coordinate
*/ */
int worldZ; int worldZ;
/**
* The stride of the data
*/
int stride;
/** /**
* The work to do once the chunk is available * The work to do once the chunk is available
@ -65,6 +70,7 @@ public class ChunkGenerationThread implements Runnable {
* @param worldX The world x coordinate * @param worldX The world x coordinate
* @param worldY The world y coordinate * @param worldY The world y coordinate
* @param worldZ The world z coordinate * @param worldZ The world z coordinate
* @param stride The stride of the data
* @param onLoad The work to do once the chunk is available * @param onLoad The work to do once the chunk is available
*/ */
public ChunkGenerationThread( public ChunkGenerationThread(
@ -72,6 +78,7 @@ public class ChunkGenerationThread implements Runnable {
ServerChunkCache chunkCache, ServerChunkCache chunkCache,
ChunkGenerator chunkGenerator, ChunkGenerator chunkGenerator,
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int stride,
Consumer<ServerTerrainChunk> onLoad Consumer<ServerTerrainChunk> onLoad
){ ){
this.chunkDiskMap = chunkDiskMap; this.chunkDiskMap = chunkDiskMap;
@ -80,6 +87,7 @@ public class ChunkGenerationThread implements Runnable {
this.worldX = worldX; this.worldX = worldX;
this.worldY = worldY; this.worldY = worldY;
this.worldZ = worldZ; this.worldZ = worldZ;
this.stride = stride;
this.onLoad = onLoad; this.onLoad = onLoad;
} }
@ -99,7 +107,7 @@ public class ChunkGenerationThread implements Runnable {
} }
//generate if it does not exist //generate if it does not exist
if(chunk == null){ if(chunk == null){
chunk = chunkGenerator.generateChunk(worldX, worldY, worldZ); chunk = chunkGenerator.generateChunk(worldX, worldY, worldZ, stride);
} }
if(chunk != null){ if(chunk != null){
chunkCache.add(worldX, worldY, worldZ, chunk); chunkCache.add(worldX, worldY, worldZ, chunk);

View File

@ -1,5 +1,6 @@
package electrosphere.server.terrain.manager; package electrosphere.server.terrain.manager;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.game.server.world.ServerWorldData; import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.terrain.diskmap.ChunkDiskMap; import electrosphere.server.terrain.diskmap.ChunkDiskMap;
@ -242,7 +243,7 @@ public class ServerTerrainManager {
} }
//generate if it does not exist //generate if it does not exist
if(returnedChunk == null){ if(returnedChunk == null){
returnedChunk = chunkGenerator.generateChunk(worldX, worldY, worldZ); returnedChunk = chunkGenerator.generateChunk(worldX, worldY, worldZ, ChunkData.NO_STRIDE);
} }
this.chunkCache.add(worldX, worldY, worldZ, returnedChunk); this.chunkCache.add(worldX, worldY, worldZ, returnedChunk);
} }
@ -255,11 +256,12 @@ public class ServerTerrainManager {
* @param worldX The world x position * @param worldX The world x position
* @param worldY The world y position * @param worldY The world y position
* @param worldZ The world z position * @param worldZ The world z position
* @param stride The stride of the data
* @param onLoad The logic to run once the chunk is available * @param onLoad The logic to run once the chunk is available
*/ */
public void getChunkAsync(int worldX, int worldY, int worldZ, Consumer<ServerTerrainChunk> onLoad){ public void getChunkAsync(int worldX, int worldY, int worldZ, int stride, Consumer<ServerTerrainChunk> onLoad){
Globals.profiler.beginCpuSample("ServerTerrainManager.getChunkAsync"); Globals.profiler.beginCpuSample("ServerTerrainManager.getChunkAsync");
this.chunkExecutorService.submit(new ChunkGenerationThread(chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, onLoad)); this.chunkExecutorService.submit(new ChunkGenerationThread(chunkDiskMap, chunkCache, chunkGenerator, worldX, worldY, worldZ, stride, onLoad));
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }