fix placing character at end of world bounds
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-12-03 21:30:43 -05:00
parent af1daecdac
commit c34de4744b
4 changed files with 29 additions and 66 deletions

View File

@ -1237,6 +1237,7 @@ Fix homogenous flagging on cell managers
Fix more cache key collision cases
Store terrain chunk files in dedicated folder
Start to standardize on doubles for positional data
Fix placing character at end of world bounds

View File

@ -11,6 +11,7 @@ import org.joml.Vector3d;
import electrosphere.client.block.BlockChunkData;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.engine.Globals;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.server.ServerConnectionHandler;
@ -30,10 +31,7 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
public TerrainMessage handleAsyncMessage(ServerConnectionHandler connectionHandler, TerrainMessage message) {
switch(message.getMessageSubtype()){
case REQUESTCHUNKDATA: {
TerrainProtocol.sendWorldSubChunkAsync(connectionHandler,
message.getworldX(), message.getworldY(), message.getworldZ()
);
return null;
throw new Error("Deprecated call!");
}
case REQUESTREDUCEDCHUNKDATA: {
TerrainProtocol.sendWorldSubChunkAsyncStrided(connectionHandler,
@ -150,63 +148,6 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
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
*/
static void sendWorldSubChunkAsync(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
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, ChunkData.NO_STRIDE, onLoad);
Globals.profiler.endCpuSample();
}
/**
* Sends a subchunk to the client
* @param connectionHandler The connection handler
@ -224,6 +165,18 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
return;
}
ServerWorldData serverWorldData = realm.getServerWorldData();
if(worldX + Math.pow(2,stride) * ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE >= serverWorldData.getWorldBoundMax().x){
throw new Error("Requested invalid position! " + worldX);
}
if(worldY + Math.pow(2,stride) * ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE >= serverWorldData.getWorldBoundMax().y){
throw new Error("Requested invalid position! " + worldY);
}
if(worldZ + Math.pow(2,stride) * ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE >= serverWorldData.getWorldBoundMax().z){
throw new Error("Requested invalid position! " + worldZ);
}
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

View File

@ -247,6 +247,10 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
if(finalWorldX > this.serverWorldData.getWorldSizeDiscrete() || finalWorldZ > this.serverWorldData.getWorldSizeDiscrete()){
throw new Error("Invalid world dim! " + finalWorldX + " " + finalWorldZ);
}
heightfield[x][z] = this.getMultisampleElevation(finalWorldX, finalWorldZ, finalChunkX, finalChunkZ);
//calculate real pos

View File

@ -12,9 +12,14 @@ import electrosphere.util.annotation.Exclude;
public class TerrainModel {
/**
* Maximum size of the macro data
* Maximum number of positions that macro data can be interpolated from
*/
public static final int MAX_MACRO_DATA_SIZE = 2048;
public static final int MAX_SAMPLEABLE_MACRO_POSITIONS = 2048;
/**
* Maximum size of the macro data (must be a power of 2 plus 1 -- the plus 1 is so that we have a macro value for the chunks at the very edge of the world)
*/
public static final int MAX_MACRO_DATA_SIZE = MAX_SAMPLEABLE_MACRO_POSITIONS + 2;
/**
@ -23,13 +28,13 @@ public class TerrainModel {
public static final int DEFAULT_MACRO_DATA_SCALE = 32;
/**
* The maximum discrete world size
* The maximum discrete world size.
*/
public static final int MAX_WORLD_SIZE_DISCRETE = MAX_MACRO_DATA_SIZE * DEFAULT_MACRO_DATA_SCALE;
public static final int MAX_WORLD_SIZE_DISCRETE = MAX_SAMPLEABLE_MACRO_POSITIONS * DEFAULT_MACRO_DATA_SCALE;
/**
* The discrete array dimension of the model
* The discrete array dimension of the model (must be a power of 2 plus 1 -- the plus 1 is so that we have a macro value for the chunks at the very edge of the world)
*/
int discreteArrayDimension = MAX_MACRO_DATA_SIZE;