Add client side handling of block endpoints
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
344019885e
commit
749b9c63b4
@ -1148,6 +1148,7 @@ Code formatting on queued asset classes
|
|||||||
Refactoring server side of terrain management
|
Refactoring server side of terrain management
|
||||||
Add server manager for block chunk data & management
|
Add server manager for block chunk data & management
|
||||||
Add endpoint to request strided block data
|
Add endpoint to request strided block data
|
||||||
|
Add client side handling of block endpoint
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
package electrosphere.client.block;
|
package electrosphere.client.block;
|
||||||
|
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -273,6 +275,14 @@ public class BlockChunkData {
|
|||||||
this.worldZ = worldZ;
|
this.worldZ = worldZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the world position of this chunk
|
||||||
|
* @return The world position
|
||||||
|
*/
|
||||||
|
public Vector3i getWorldPos(){
|
||||||
|
return new Vector3i(worldX, worldY, worldZ);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the homogenous value for this chunk
|
* Gets the homogenous value for this chunk
|
||||||
* @return The homogenous value
|
* @return The homogenous value
|
||||||
|
|||||||
296
src/main/java/electrosphere/client/block/ClientBlockManager.java
Normal file
296
src/main/java/electrosphere/client/block/ClientBlockManager.java
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
package electrosphere.client.block;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.client.scene.ClientWorldData;
|
||||||
|
import electrosphere.client.terrain.cells.ClientDrawCellManager;
|
||||||
|
import electrosphere.client.terrain.cells.DrawCell;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
|
import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
|
||||||
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
|
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||||
|
import io.github.studiorailgun.HashUtils;
|
||||||
|
|
||||||
|
public class ClientBlockManager {
|
||||||
|
//queues messages from server
|
||||||
|
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the block manager (eg if adding message from network)
|
||||||
|
*/
|
||||||
|
static Semaphore lock = new Semaphore(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum concurrent block requests
|
||||||
|
*/
|
||||||
|
public static final int MAX_CONCURRENT_REQUESTS = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of frames to wait before flagging a request as failed
|
||||||
|
*/
|
||||||
|
public static final int FAILED_REQUEST_THRESHOLD = 500;
|
||||||
|
|
||||||
|
//The interpolation ratio of block
|
||||||
|
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||||
|
|
||||||
|
//caches chunks from server
|
||||||
|
static final int CACHE_SIZE = 2500 + (int)(ClientDrawCellManager.FULL_RES_DIST * 10) + (int)(ClientDrawCellManager.HALF_RES_DIST * 10);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the cache in bytes
|
||||||
|
*/
|
||||||
|
static final int CACHE_SIZE_IN_MB = (CACHE_SIZE * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * ServerTerrainChunk.CHUNK_DIMENSION * 2 * 4) / 1024 / 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches block data
|
||||||
|
*/
|
||||||
|
BlockChunkCache blockCache;
|
||||||
|
|
||||||
|
//The world data for the client
|
||||||
|
ClientWorldData clientWorldData;
|
||||||
|
|
||||||
|
//The queue of block chunk data to be buffered to gpu
|
||||||
|
// static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new LinkedList<TerrainChunkGenQueueItem>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks what outgoing requests are currently active
|
||||||
|
*/
|
||||||
|
Map<Long,Integer> requestedMap = new HashMap<Long,Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to clear the request map
|
||||||
|
*/
|
||||||
|
List<Long> toClearFailedRequests = new LinkedList<Long>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public ClientBlockManager(){
|
||||||
|
blockCache = new BlockChunkCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles messages that have been received from the server
|
||||||
|
*/
|
||||||
|
public void handleMessages(){
|
||||||
|
Globals.profiler.beginCpuSample("ClientBlockManager.handleMessages");
|
||||||
|
lock.acquireUninterruptibly();
|
||||||
|
List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>();
|
||||||
|
for(TerrainMessage message : messageQueue){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case SENDREDUCEDBLOCKDATA: {
|
||||||
|
//construct return obj
|
||||||
|
BlockChunkData data = new BlockChunkData();
|
||||||
|
data.setWorldX(message.getworldX());
|
||||||
|
data.setWorldY(message.getworldY());
|
||||||
|
data.setWorldZ(message.getworldZ());
|
||||||
|
data.setHomogenousValue((short)message.gethomogenousValue());
|
||||||
|
|
||||||
|
//read main data
|
||||||
|
if(data.getHomogenousValue() == BlockChunkData.NOT_HOMOGENOUS){
|
||||||
|
short[] type = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||||
|
short[] metadata = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
|
||||||
|
ShortBuffer shortBuffer = buffer.asShortBuffer();
|
||||||
|
|
||||||
|
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||||
|
type[i] = shortBuffer.get();
|
||||||
|
}
|
||||||
|
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||||
|
metadata[i] = shortBuffer.get();
|
||||||
|
}
|
||||||
|
data.setType(type);
|
||||||
|
data.setMetadata(metadata);
|
||||||
|
}
|
||||||
|
blockCache.add(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution(), data);
|
||||||
|
//remove from request map
|
||||||
|
this.requestedMap.remove(this.getRequestKey(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()));
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
LoggerInterface.loggerEngine.WARNING("ClientBlockManager: unhandled network message of type" + message.getMessageSubtype());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messageQueue.clear();
|
||||||
|
for(TerrainMessage message : bouncedMessages){
|
||||||
|
messageQueue.add(message);
|
||||||
|
}
|
||||||
|
//evaluate if any terrain chunks have failed to request
|
||||||
|
for(Long key : this.requestedMap.keySet()){
|
||||||
|
int duration = this.requestedMap.get(key);
|
||||||
|
if(duration > FAILED_REQUEST_THRESHOLD){
|
||||||
|
toClearFailedRequests.add(key);
|
||||||
|
} else {
|
||||||
|
this.requestedMap.put(key,duration + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this.toClearFailedRequests.size() > 0){
|
||||||
|
for(Long key : toClearFailedRequests){
|
||||||
|
this.requestedMap.remove(key);
|
||||||
|
}
|
||||||
|
this.toClearFailedRequests.clear();
|
||||||
|
}
|
||||||
|
lock.release();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evicts all cached blocks
|
||||||
|
*/
|
||||||
|
public void evictAll(){
|
||||||
|
this.blockCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a terrain message to the queue of messages that this manager needs to process
|
||||||
|
* @param message The message
|
||||||
|
*/
|
||||||
|
public void attachTerrainMessage(TerrainMessage message){
|
||||||
|
lock.acquireUninterruptibly();
|
||||||
|
messageQueue.add(message);
|
||||||
|
lock.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the block cache contains chunk data at a given world position
|
||||||
|
* @param worldX the x position
|
||||||
|
* @param worldY the y position
|
||||||
|
* @param worldZ the z position
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return true if the data exists, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ, int stride){
|
||||||
|
return blockCache.containsChunk(worldX, worldY, worldZ, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the block cache contains chunk data at a given world position
|
||||||
|
* @param worldPos The vector containing the world-space position
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return true if the data exists, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean containsChunkDataAtWorldPoint(Vector3i worldPos, int stride){
|
||||||
|
return this.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a chunk from the server
|
||||||
|
* @param worldX the world x coordinate of the chunk
|
||||||
|
* @param worldY the world y coordinate of the chunk
|
||||||
|
* @param worldZ the world z coordinate of the chunk
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return true if the request was successfully sent, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean requestChunk(int worldX, int worldY, int worldZ, int stride){
|
||||||
|
boolean rVal = false;
|
||||||
|
lock.acquireUninterruptibly();
|
||||||
|
if(this.requestedMap.size() < MAX_CONCURRENT_REQUESTS && !this.requestedMap.containsKey(this.getRequestKey(worldX, worldY, worldZ, stride))){
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestReducedBlockDataMessage(
|
||||||
|
worldX,
|
||||||
|
worldY,
|
||||||
|
worldZ,
|
||||||
|
stride
|
||||||
|
));
|
||||||
|
this.requestedMap.put(this.getRequestKey(worldX, worldY, worldZ, stride), 0);
|
||||||
|
rVal = true;
|
||||||
|
}
|
||||||
|
lock.release();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the chunk data at a given world position
|
||||||
|
* @param worldX The x component of the world coordinate
|
||||||
|
* @param worldY The y component of the world coordinate
|
||||||
|
* @param worldZ The z component of the world coordinate
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return The chunk data if it exists, otherwise null
|
||||||
|
*/
|
||||||
|
public BlockChunkData getChunkDataAtWorldPoint(int worldX, int worldY, int worldZ, int stride){
|
||||||
|
return blockCache.get(worldX, worldY, worldZ, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the chunk data at a given world position
|
||||||
|
* @param worldPos The world position as a joml vector
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return The chunk data if it exists, otherwise null
|
||||||
|
*/
|
||||||
|
public BlockChunkData getChunkDataAtWorldPoint(Vector3i worldPos, int stride){
|
||||||
|
return this.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues a block chunk to be pushed to GPU based on chunk data
|
||||||
|
* @param data The chunk data (triangles, normals, etc)
|
||||||
|
* @return The model path that is promised to eventually reflect the block model when it makes it to gpu
|
||||||
|
*/
|
||||||
|
public static String queueBlockGridGeneration(BlockMeshData data, DrawCell notifyTarget, Entity toDelete){
|
||||||
|
throw new UnsupportedOperationException("Unimplemented");
|
||||||
|
// String promisedHash = "";
|
||||||
|
// UUID newUUID = UUID.randomUUID();
|
||||||
|
// promisedHash = newUUID.toString();
|
||||||
|
// TerrainChunkGenQueueItem queueItem = new TerrainChunkGenQueueItem(data, promisedHash, atlas, notifyTarget, toDelete);
|
||||||
|
// lock.acquireUninterruptibly();
|
||||||
|
// terrainChunkGenerationQueue.add(queueItem);
|
||||||
|
// lock.release();
|
||||||
|
// return promisedHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes all block data in queue to the gpu and registers the resulting models
|
||||||
|
*/
|
||||||
|
public static void generateBlockChunkGeometry(){
|
||||||
|
throw new UnsupportedOperationException("Unimplemented");
|
||||||
|
// Globals.profiler.beginCpuSample("ClientBlockManager.generateTerrainChunkGeometry");
|
||||||
|
// lock.acquireUninterruptibly();
|
||||||
|
// for(TerrainChunkGenQueueItem queueItem : terrainChunkGenerationQueue){
|
||||||
|
// Model terrainModel = TransvoxelModelGeneration.generateTerrainModel(queueItem.getData(), queueItem.getAtlas());
|
||||||
|
// Globals.assetManager.registerModelToSpecificString(terrainModel, queueItem.getPromisedHash());
|
||||||
|
// if(queueItem.notifyTarget != null){
|
||||||
|
// queueItem.notifyTarget.alertToGeneration();
|
||||||
|
// }
|
||||||
|
// if(queueItem.toDelete != null){
|
||||||
|
// ClientEntityUtils.destroyEntity(queueItem.toDelete);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// terrainChunkGenerationQueue.clear();
|
||||||
|
// lock.release();
|
||||||
|
// Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all chunks in the terrain cache
|
||||||
|
* @return The collection of all chunk data objects
|
||||||
|
*/
|
||||||
|
public Collection<BlockChunkData> getAllChunks(){
|
||||||
|
return blockCache.getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the key for a given request
|
||||||
|
* @param worldX The world x coordinate
|
||||||
|
* @param worldY The world y coordinate
|
||||||
|
* @param worldZ The world z coordinate
|
||||||
|
* @param stride The stride of the data
|
||||||
|
* @return The key
|
||||||
|
*/
|
||||||
|
private Long getRequestKey(int worldX, int worldY, int worldZ, int stride){
|
||||||
|
return (long)HashUtils.cantorHash(worldY, worldZ, worldZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -169,11 +169,15 @@ public class ClientSimulation {
|
|||||||
Globals.profiler.beginCpuSample("ClientSimulation.loadTerrain");
|
Globals.profiler.beginCpuSample("ClientSimulation.loadTerrain");
|
||||||
if(Globals.clientTerrainManager != null){
|
if(Globals.clientTerrainManager != null){
|
||||||
Globals.clientTerrainManager.handleMessages();
|
Globals.clientTerrainManager.handleMessages();
|
||||||
updateTerrainCellManager();
|
this.updateTerrainCellManager();
|
||||||
}
|
}
|
||||||
if(Globals.clientFluidManager != null){
|
if(Globals.clientFluidManager != null){
|
||||||
Globals.clientFluidManager.handleMessages();
|
Globals.clientFluidManager.handleMessages();
|
||||||
updateFluidCellManager();
|
this.updateFluidCellManager();
|
||||||
|
}
|
||||||
|
if(Globals.clientBlockManager != null){
|
||||||
|
Globals.clientBlockManager.handleMessages();
|
||||||
|
this.updateBlockCellManager();
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
@ -181,7 +185,7 @@ public class ClientSimulation {
|
|||||||
/**
|
/**
|
||||||
* Updates the terrain cell manager (specifically position handling)
|
* Updates the terrain cell manager (specifically position handling)
|
||||||
*/
|
*/
|
||||||
void updateTerrainCellManager(){
|
private void updateTerrainCellManager(){
|
||||||
///
|
///
|
||||||
/// C L I E N T C E L L M A N A G E R
|
/// C L I E N T C E L L M A N A G E R
|
||||||
///
|
///
|
||||||
@ -194,12 +198,19 @@ public class ClientSimulation {
|
|||||||
/**
|
/**
|
||||||
* Updates the fluid cell manager (specifically position handling)
|
* Updates the fluid cell manager (specifically position handling)
|
||||||
*/
|
*/
|
||||||
void updateFluidCellManager(){
|
private void updateFluidCellManager(){
|
||||||
//fluid work
|
//fluid work
|
||||||
if(Globals.fluidCellManager != null && Globals.clientWorldData != null){
|
if(Globals.fluidCellManager != null && Globals.clientWorldData != null){
|
||||||
Globals.fluidCellManager.update();
|
Globals.fluidCellManager.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the block cell manager
|
||||||
|
*/
|
||||||
|
private void updateBlockCellManager(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the client simulation is ready to execute
|
* Gets whether the client simulation is ready to execute
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package electrosphere.client.terrain.manager;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -13,6 +14,8 @@ import java.util.concurrent.Semaphore;
|
|||||||
|
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.client.block.BlockChunkCache;
|
||||||
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.client.scene.ClientWorldData;
|
import electrosphere.client.scene.ClientWorldData;
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
import electrosphere.client.terrain.cache.ChunkData;
|
||||||
import electrosphere.client.terrain.cache.ClientTerrainCache;
|
import electrosphere.client.terrain.cache.ClientTerrainCache;
|
||||||
@ -67,6 +70,11 @@ public class ClientTerrainManager {
|
|||||||
|
|
||||||
//used for caching the macro values
|
//used for caching the macro values
|
||||||
ClientTerrainCache terrainCache;
|
ClientTerrainCache terrainCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches block data
|
||||||
|
*/
|
||||||
|
BlockChunkCache blockCache;
|
||||||
|
|
||||||
//The world data for the client
|
//The world data for the client
|
||||||
ClientWorldData clientWorldData;
|
ClientWorldData clientWorldData;
|
||||||
@ -79,6 +87,11 @@ public class ClientTerrainManager {
|
|||||||
*/
|
*/
|
||||||
Map<Long,Integer> requestedMap = new HashMap<Long,Integer>();
|
Map<Long,Integer> requestedMap = new HashMap<Long,Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks what outgoing block requests are currently active
|
||||||
|
*/
|
||||||
|
Map<Long,Integer> requestedBlockMap = new HashMap<Long,Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to clear the request map
|
* Used to clear the request map
|
||||||
*/
|
*/
|
||||||
@ -89,6 +102,7 @@ public class ClientTerrainManager {
|
|||||||
*/
|
*/
|
||||||
public ClientTerrainManager(){
|
public ClientTerrainManager(){
|
||||||
terrainCache = new ClientTerrainCache(CACHE_SIZE);
|
terrainCache = new ClientTerrainCache(CACHE_SIZE);
|
||||||
|
blockCache = new BlockChunkCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -170,6 +184,34 @@ public class ClientTerrainManager {
|
|||||||
//remove from request map
|
//remove from request map
|
||||||
this.requestedMap.remove(this.getRequestKey(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()));
|
this.requestedMap.remove(this.getRequestKey(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()));
|
||||||
} break;
|
} break;
|
||||||
|
case SENDREDUCEDBLOCKDATA: {
|
||||||
|
//construct return obj
|
||||||
|
BlockChunkData data = new BlockChunkData();
|
||||||
|
data.setWorldX(message.getworldX());
|
||||||
|
data.setWorldY(message.getworldY());
|
||||||
|
data.setWorldZ(message.getworldZ());
|
||||||
|
data.setHomogenousValue((short)message.gethomogenousValue());
|
||||||
|
|
||||||
|
//read main data
|
||||||
|
if(data.getHomogenousValue() == BlockChunkData.NOT_HOMOGENOUS){
|
||||||
|
short[] type = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||||
|
short[] metadata = new short[BlockChunkData.TOTAL_DATA_WIDTH];
|
||||||
|
ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData());
|
||||||
|
ShortBuffer shortBuffer = buffer.asShortBuffer();
|
||||||
|
|
||||||
|
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||||
|
type[i] = shortBuffer.get();
|
||||||
|
}
|
||||||
|
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){
|
||||||
|
metadata[i] = shortBuffer.get();
|
||||||
|
}
|
||||||
|
data.setType(type);
|
||||||
|
data.setMetadata(metadata);
|
||||||
|
}
|
||||||
|
blockCache.add(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution(), data);
|
||||||
|
//remove from request map
|
||||||
|
this.requestedBlockMap.remove(this.getRequestKey(message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()));
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
LoggerInterface.loggerEngine.WARNING("ClientTerrainManager: unhandled network message of type" + message.getMessageSubtype());
|
LoggerInterface.loggerEngine.WARNING("ClientTerrainManager: unhandled network message of type" + message.getMessageSubtype());
|
||||||
break;
|
break;
|
||||||
@ -179,7 +221,7 @@ public class ClientTerrainManager {
|
|||||||
for(TerrainMessage message : bouncedMessages){
|
for(TerrainMessage message : bouncedMessages){
|
||||||
messageQueue.add(message);
|
messageQueue.add(message);
|
||||||
}
|
}
|
||||||
//evaluate if any chunks have failed to request
|
//evaluate if any terrain chunks have failed to request
|
||||||
for(Long key : this.requestedMap.keySet()){
|
for(Long key : this.requestedMap.keySet()){
|
||||||
int duration = this.requestedMap.get(key);
|
int duration = this.requestedMap.get(key);
|
||||||
if(duration > FAILED_REQUEST_THRESHOLD){
|
if(duration > FAILED_REQUEST_THRESHOLD){
|
||||||
@ -203,6 +245,7 @@ public class ClientTerrainManager {
|
|||||||
*/
|
*/
|
||||||
public void evictAll(){
|
public void evictAll(){
|
||||||
this.terrainCache.evictAll();
|
this.terrainCache.evictAll();
|
||||||
|
this.blockCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import electrosphere.audio.VirtualAudioSourceManager;
|
|||||||
import electrosphere.audio.collision.HitboxAudioService;
|
import electrosphere.audio.collision.HitboxAudioService;
|
||||||
import electrosphere.audio.movement.MovementAudioService;
|
import electrosphere.audio.movement.MovementAudioService;
|
||||||
import electrosphere.auth.AuthenticationManager;
|
import electrosphere.auth.AuthenticationManager;
|
||||||
|
import electrosphere.client.block.ClientBlockManager;
|
||||||
import electrosphere.client.chemistry.ClientChemistryCollisionCallback;
|
import electrosphere.client.chemistry.ClientChemistryCollisionCallback;
|
||||||
import electrosphere.client.entity.particle.ParticleService;
|
import electrosphere.client.entity.particle.ParticleService;
|
||||||
import electrosphere.client.fluid.cells.FluidCellManager;
|
import electrosphere.client.fluid.cells.FluidCellManager;
|
||||||
@ -349,11 +350,10 @@ public class Globals {
|
|||||||
//client world data
|
//client world data
|
||||||
public static ClientWorldData clientWorldData;
|
public static ClientWorldData clientWorldData;
|
||||||
|
|
||||||
//client terrain manager
|
//client gridded manager
|
||||||
public static ClientTerrainManager clientTerrainManager;
|
public static ClientTerrainManager clientTerrainManager;
|
||||||
|
|
||||||
//client fluid manager
|
|
||||||
public static ClientFluidManager clientFluidManager;
|
public static ClientFluidManager clientFluidManager;
|
||||||
|
public static ClientBlockManager clientBlockManager;
|
||||||
|
|
||||||
//client player data
|
//client player data
|
||||||
public static ClientPlayerData clientPlayerData = new ClientPlayerData();
|
public static ClientPlayerData clientPlayerData = new ClientPlayerData();
|
||||||
@ -501,10 +501,10 @@ public class Globals {
|
|||||||
entityDataCellMapper = new EntityDataCellMapper();
|
entityDataCellMapper = new EntityDataCellMapper();
|
||||||
//nav mesh manager
|
//nav mesh manager
|
||||||
navMeshManager = new NavMeshManager();
|
navMeshManager = new NavMeshManager();
|
||||||
//terrain
|
//gridded managers
|
||||||
Globals.clientTerrainManager = new ClientTerrainManager();
|
Globals.clientTerrainManager = new ClientTerrainManager();
|
||||||
//fluid
|
|
||||||
Globals.clientFluidManager = new ClientFluidManager();
|
Globals.clientFluidManager = new ClientFluidManager();
|
||||||
|
Globals.clientBlockManager = new ClientBlockManager();
|
||||||
//game config
|
//game config
|
||||||
gameConfigDefault = electrosphere.game.data.Config.loadDefaultConfig();
|
gameConfigDefault = electrosphere.game.data.Config.loadDefaultConfig();
|
||||||
gameConfigCurrent = gameConfigDefault;
|
gameConfigCurrent = gameConfigDefault;
|
||||||
|
|||||||
@ -60,6 +60,10 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
|||||||
LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ() + " " + message.getchunkResolution());
|
LoggerInterface.loggerNetworking.DEBUG("(Client) Received terrain at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ() + " " + message.getchunkResolution());
|
||||||
Globals.clientTerrainManager.attachTerrainMessage(message);
|
Globals.clientTerrainManager.attachTerrainMessage(message);
|
||||||
} break;
|
} break;
|
||||||
|
case SENDREDUCEDBLOCKDATA: {
|
||||||
|
LoggerInterface.loggerNetworking.DEBUG("(Client) Received blocks at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ() + " " + message.getchunkResolution());
|
||||||
|
Globals.clientBlockManager.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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user