diff --git a/net/terrain.json b/net/terrain.json index 1607ac24..8b629c3f 100644 --- a/net/terrain.json +++ b/net/terrain.json @@ -33,6 +33,14 @@ "name" : "worldMaxY", "type" : "FIXED_INT" }, + + + { + "name" : "value", + "type" : "FIXED_FLOAT" + }, + + { "name" : "worldX", "type" : "FIXED_INT" @@ -45,26 +53,8 @@ "name" : "worldZ", "type" : "FIXED_INT" }, - { - "name" : "value", - "type" : "FIXED_FLOAT" - }, - - - - { - "name" : "locationX", - "type" : "FIXED_INT" - }, - { - "name" : "locationY", - "type" : "FIXED_INT" - }, - { - "name" : "locationZ", - "type" : "FIXED_INT" - }, + { @@ -82,215 +72,18 @@ - - - - { - "name" : "macroValue00", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue01", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue02", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue03", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue04", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue10", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue11", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue12", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue13", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue14", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue20", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue21", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue22", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue23", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue24", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue30", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue31", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue32", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue33", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue34", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue40", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue41", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue42", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue43", - "type" : "FIXED_FLOAT" - }, - { - "name" : "macroValue44", - "type" : "FIXED_FLOAT" - }, - - - - { - "name" : "randomizerValue00", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue01", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue02", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue03", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue04", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue10", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue11", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue12", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue13", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue14", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue20", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue21", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue22", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue23", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue24", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue30", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue31", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue32", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue33", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue34", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue40", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue41", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue42", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue43", - "type" : "FIXED_LONG" - }, - { - "name" : "randomizerValue44", - "type" : "FIXED_LONG" - }, { "name" : "chunkData", "type" : "BYTE_ARRAY" + }, + + { + "name" : "terrainWeight", + "type" : "FIXED_FLOAT" + }, + { + "name" : "terrainValue", + "type" : "FIXED_INT" } ], "messageTypes" : [ @@ -319,87 +112,10 @@ }, { "messageName" : "Update", - "data" : [ - "locationX", - "locationY", - "locationZ" - ] - }, - { - "messageName" : "chunkLoadStart", "data" : [ "worldX", "worldY", - "value" - ] - }, - { - "messageName" : "MacroValue", - "data" : [ - "worldX", - "worldY", - "macroValue00", - "macroValue01", - "macroValue02", - "macroValue03", - "macroValue04", - "macroValue10", - "macroValue11", - "macroValue12", - "macroValue13", - "macroValue14", - "macroValue20", - "macroValue21", - "macroValue22", - "macroValue23", - "macroValue24", - "macroValue30", - "macroValue31", - "macroValue32", - "macroValue33", - "macroValue34", - "macroValue40", - "macroValue41", - "macroValue42", - "macroValue43", - "macroValue44", - "randomizerValue00", - "randomizerValue01", - "randomizerValue02", - "randomizerValue03", - "randomizerValue04", - "randomizerValue10", - "randomizerValue11", - "randomizerValue12", - "randomizerValue13", - "randomizerValue14", - "randomizerValue20", - "randomizerValue21", - "randomizerValue22", - "randomizerValue23", - "randomizerValue24", - "randomizerValue30", - "randomizerValue31", - "randomizerValue32", - "randomizerValue33", - "randomizerValue34", - "randomizerValue40", - "randomizerValue41", - "randomizerValue42", - "randomizerValue43", - "randomizerValue44" - ] - }, - { - "messageName" : "heightMapModification", - "data" : [ - "value", - "worldX", - "worldY", - "worldZ", - "locationX", - "locationY", - "locationZ" + "worldZ" ] }, { diff --git a/pom.xml b/pom.xml index 63b5477d..359b3493 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,15 @@ 0.1 + + + + + org.ode4j + core + 0.5.0 + + diff --git a/src/main/java/electrosphere/client/culling/ClientEntityCullingManager.java b/src/main/java/electrosphere/client/culling/ClientEntityCullingManager.java index 8605248e..e685b7f7 100644 --- a/src/main/java/electrosphere/client/culling/ClientEntityCullingManager.java +++ b/src/main/java/electrosphere/client/culling/ClientEntityCullingManager.java @@ -43,9 +43,9 @@ public class ClientEntityCullingManager { public void clearOutOfBoundsEntities(){ if(Globals.commonWorldData != null && Globals.playerEntity != null && Globals.clientPlayerData != null){ Vector3d playerCharacterPos = EntityUtils.getPosition(Globals.playerEntity); - int playerCharacterWorldX = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.x); - int playerCharacterWorldY = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.y); - int playerCharacterWorldZ = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.z); + int playerCharacterWorldX = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.x); + int playerCharacterWorldY = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.y); + int playerCharacterWorldZ = Globals.clientWorldData.convertRealToWorld(playerCharacterPos.z); if( playerCharacterWorldX != Globals.clientPlayerData.getWorldPos().x|| playerCharacterWorldY != Globals.clientPlayerData.getWorldPos().y || @@ -59,22 +59,14 @@ public class ClientEntityCullingManager { //common world data is initialized with the collision data //if this is null then the engine hasn't fully started up yet if(position != null){ - int worldX = Globals.commonWorldData.convertRealToWorld(position.x); - int worldY = Globals.commonWorldData.convertRealToWorld(position.z); - if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){ - //if we're running the server we need to just hide the entity - //otherwise delete it - if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ - recursiveHide(entity); - } else { - scene.recursiveDeregister(entity); - } + int worldX = Globals.clientWorldData.convertRealToWorld(position.x); + int worldZ = Globals.clientWorldData.convertRealToWorld(position.z); + if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldZ)){ + //we need to just hide the entity + recursiveHide(entity); } else { - //if the entity is within range, we're running server, - //and it's not set to visible, make it visible - if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ - recursiveShow(entity); - } + //if the entity is within range and it's not set to visible, make it visible + recursiveShow(entity); } } } diff --git a/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java b/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java index 68b94418..9768b3c3 100644 --- a/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java +++ b/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java @@ -1,7 +1,9 @@ package electrosphere.client.foliagemanager; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; @@ -42,6 +44,15 @@ public class ClientFoliageManager { //Used to prevent concurrent usage of grassEntities set boolean ready = false; + //The list of voxel type ids that should have grass generated on top of them + static final List grassGeneratingVoxelIds = new ArrayList(); + + //FoliageCells that are active and have foliage that is being drawn + Set activeCells = new HashSet(); + //The maximum distance a cell can be away from the player before being destroyed + static final float CELL_DISTANCE_MAX = 25f; + //The maximum number of foliage cells + static final int CELL_COUNT_MAX = 100; @@ -59,6 +70,9 @@ public class ClientFoliageManager { }; modelMatrixAttribute = new ShaderAttribute(attributeIndices); attributes.put(modelMatrixAttribute,HomogenousBufferTypes.MAT4F); + + //set grass generating voxel ids + grassGeneratingVoxelIds.add(2); } //shader paths @@ -119,14 +133,6 @@ public class ClientFoliageManager { grassPosition.set(getNewPosition(playerPosition)); grassRotation.set(getNewRotation()); } - //update uniforms - // instancedActor.setUniform("position", grassPosition); - // instancedActor.setUniform("rotation", new Vector4d( - // grassRotation.x, - // grassRotation.y, - // grassRotation.z, - // grassRotation.w)); - // instancedActor.setUniform("scale", new Vector3d(EntityUtils.getScale(grassEntity))); modelMatrix = modelMatrix.identity(); Vector3f cameraModifiedPosition = new Vector3f((float)grassPosition.x,(float)grassPosition.y,(float)grassPosition.z).sub(cameraCenter); @@ -137,7 +143,7 @@ public class ClientFoliageManager { instancedActor.setAttribute(modelMatrixAttribute, modelMatrix); //draw - instancedActor.draw(Globals.renderingEngine.getRenderPipelineState()); + // instancedActor.draw(Globals.renderingEngine.getRenderPipelineState()); } } } @@ -166,13 +172,6 @@ public class ClientFoliageManager { } - - - - - - - /** * Makes an already created entity a drawable, instanced entity (client only) by backing it with an InstancedActor * @param entity The entity @@ -188,6 +187,19 @@ public class ClientFoliageManager { Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAW_INSTANCED); } + + /** + * Evaluate all foliage cells to see if any should be deconstructed and any new ones should be created + */ + protected void evaluateFoliageCells(){ + Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity); + for(FoliageCell activeCell : activeCells){ + //if cell is outside of range of player, disable cell + if(activeCell.position.distance(playerPosition) > CELL_DISTANCE_MAX){ + //TODO: destroy cell + } + } + } diff --git a/src/main/java/electrosphere/client/foliagemanager/FoliageCell.java b/src/main/java/electrosphere/client/foliagemanager/FoliageCell.java new file mode 100644 index 00000000..12e3366c --- /dev/null +++ b/src/main/java/electrosphere/client/foliagemanager/FoliageCell.java @@ -0,0 +1,18 @@ +package electrosphere.client.foliagemanager; + +import java.util.Set; + +import org.joml.Vector3d; + +import electrosphere.entity.Entity; + +/** + * Contains a set of foliage entities and groups them together. + */ +public class FoliageCell { + //position of the foliage cell + Vector3d position; + //constituent entities + Set containedEntities; + +} diff --git a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java index 86ed2e94..47e03b78 100644 --- a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java +++ b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java @@ -3,7 +3,6 @@ package electrosphere.client.scene; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.Scene; import electrosphere.game.collision.CollisionEngine; diff --git a/src/main/java/electrosphere/client/scene/ClientWorldData.java b/src/main/java/electrosphere/client/scene/ClientWorldData.java index 5d80b51f..f6ab1b31 100644 --- a/src/main/java/electrosphere/client/scene/ClientWorldData.java +++ b/src/main/java/electrosphere/client/scene/ClientWorldData.java @@ -1,11 +1,5 @@ package electrosphere.client.scene; -import electrosphere.game.server.world.*; -import electrosphere.server.datacell.ServerDataCell; -import electrosphere.server.terrain.manager.ServerTerrainManager; - -import java.util.List; -import org.joml.Vector2f; import org.joml.Vector3f; /** @@ -44,7 +38,13 @@ public class ClientWorldData { int worldDiscreteSize; - public ClientWorldData(Vector3f worldMinPoint, Vector3f worldMaxPoint, int dynamicInterpolationRatio, float randomDampener, int worldDiscreteSize) { + public ClientWorldData( + Vector3f worldMinPoint, + Vector3f worldMaxPoint, + int dynamicInterpolationRatio, + float randomDampener, + int worldDiscreteSize + ) { this.worldMinPoint = worldMinPoint; this.worldMaxPoint = worldMaxPoint; this.dynamicInterpolationRatio = dynamicInterpolationRatio; @@ -84,4 +84,12 @@ public class ClientWorldData { return chunk * dynamicInterpolationRatio; } + public int convertRealToWorld(double real){ + return convertRealToChunkSpace(real); + } + + public double convertWorldToReal(int world){ + return convertChunkToRealSpace(world); + } + } diff --git a/src/main/java/electrosphere/client/sim/ClientFunctions.java b/src/main/java/electrosphere/client/sim/ClientFunctions.java index 2548ed54..0e61536c 100644 --- a/src/main/java/electrosphere/client/sim/ClientFunctions.java +++ b/src/main/java/electrosphere/client/sim/ClientFunctions.java @@ -3,10 +3,8 @@ package electrosphere.client.sim; import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; import electrosphere.entity.EntityUtils; -import electrosphere.entity.types.camera.CameraEntityUtils; import org.joml.Vector3d; -import org.joml.Vector3f; /** * @@ -45,7 +43,6 @@ public class ClientFunctions { public static void loadTerrain(){ if(Globals.clientTerrainManager != null){ Globals.clientTerrainManager.handleMessages(); - Globals.clientTerrainManager.ejectLoadedChunks(); updateCellManager(); } } @@ -59,7 +56,7 @@ public class ClientFunctions { newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity); } //Cell manager do your things - Globals.drawCellManager.calculateDeltas(oldPlayerCharacterPosition, newPlayerCharacterPosition); + Globals.drawCellManager.calculateDeltas(newPlayerCharacterPosition); Globals.drawCellManager.update(); } } diff --git a/src/main/java/electrosphere/client/terrain/cache/ChunkData.java b/src/main/java/electrosphere/client/terrain/cache/ChunkData.java new file mode 100644 index 00000000..38ebaa66 --- /dev/null +++ b/src/main/java/electrosphere/client/terrain/cache/ChunkData.java @@ -0,0 +1,52 @@ +package electrosphere.client.terrain.cache; + +import electrosphere.server.terrain.manager.ServerTerrainChunk; + +/** + * A container of data about a chunk of terrain + */ +public class ChunkData { + + //The size of a chunk + public static final int CHUNK_SIZE = ServerTerrainChunk.CHUNK_DIMENSION; + + //What type of terrain is in this voxel, eg stone vs dirt vs grass, etc + int[][][] voxelType; + //How much of that terrain type is in this voxel + float[][][] voxelWeight; + + + /** + * Gets the voxel type array in this container + * @return The voxel type array + */ + public int[][][] getVoxelType(){ + return voxelType; + } + + /** + * Sets the voxel type array in this container + * @param voxelType The voxel type array + */ + public void setVoxelType(int[][][] voxelType){ + this.voxelType = voxelType; + } + + /** + * Gets the voxel weight array in this container + * @return The voxel weight array + */ + public float[][][] getVoxelWeight(){ + return voxelWeight; + } + + /** + * Sets the voxel weight array in this container + * @param voxelWeight The voxel weight array + */ + public void setVoxelWeight(float[][][] voxelWeight){ + this.voxelWeight = voxelWeight; + } + + +} diff --git a/src/main/java/electrosphere/client/terrain/cache/ChunkModification.java b/src/main/java/electrosphere/client/terrain/cache/ChunkModification.java deleted file mode 100644 index 7628a198..00000000 --- a/src/main/java/electrosphere/client/terrain/cache/ChunkModification.java +++ /dev/null @@ -1,48 +0,0 @@ -package electrosphere.client.terrain.cache; - -/** - * - * @author amaterasu - */ -public class ChunkModification { - int worldX; - int worldY; - int locationX; - int locationY; - float value; - - public ChunkModification(int worldX, int worldY, int locationX, int locationY, float value) { - this.worldX = worldX; - this.worldY = worldY; - this.locationX = locationX; - this.locationY = locationY; - this.value = value; - } - - public int getWorldX() { - return worldX; - } - - public int getLocationX() { - return locationX; - } - - public int getLocationY() { - return locationY; - } - - public float getValue() { - return value; - } - - public int getWorldY() { - return worldY; - } - - public float[][] applyModification(float[][] heightmap){ - heightmap[locationX][locationY] = value; - return heightmap; - } - - -} diff --git a/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java b/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java index 2b6f6ebf..91aae55b 100644 --- a/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java +++ b/src/main/java/electrosphere/client/terrain/cache/ClientTerrainCache.java @@ -1,73 +1,40 @@ package electrosphere.client.terrain.cache; -import electrosphere.client.scene.ClientWorldData; -import electrosphere.game.terrain.processing.TerrainInterpolator; -import electrosphere.server.terrain.models.TerrainModel; - -import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Acts as a cache in front of terrain model to streamline receiving chunks + */ public class ClientTerrainCache { - /* - Acts as a cache in front of terrain model to streamline receiving heightmaps - on both client and server - */ - - - - ClientWorldData clientWorldData; - - + //cache capacity int cacheSize; - Map cacheMap = new ConcurrentHashMap (); + //the map of chunk key -> chunk data + Map cacheMap = new ConcurrentHashMap(); + //the list of keys in the cache List cacheList = new CopyOnWriteArrayList(); - + /** + * Constructor + * @param cacheSize The capacity of the cache + */ public ClientTerrainCache(int cacheSize){ this.cacheSize = cacheSize; } -// TerrainChunkValues getChunkValuesAtPoint(int x, int y){ -// if(terrainModel != null){ -// return new TerrainChunkValues( -// terrainModel.getMacroValuesAtPosition(x, y), -// terrainModel.getRandomizerValuesAtPosition(x, y) -// ); -// } else { -// return new TerrainChunkValues( -// new float[3][3], -// new long[3][3] -// ); -// } -// } - - - //USED TO ADD macro values - public void addChunkValuesToCache(int x, int y, float[][] macroValues, long[][] randomizer){ -// TerrainChunkValues chunk = new TerrainChunkValues(macroValues, randomizer); - assert clientWorldData != null; - - float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk( - macroValues, - randomizer, - clientWorldData.getDynamicInterpolationRatio(), - clientWorldData.getRandomDampener() - ); - - cacheMap.put(getKey(x,y),heightmap); - while(cacheList.size() > cacheSize){ - String currentChunk = cacheList.remove(0); - cacheMap.remove(currentChunk); - } - } - - public void addFloatsToCache(int x, int y, float[][] values){ - cacheMap.put(getKey(x,y),values); + /** + * Adds a chunk data to the terrain cache + * @param worldX The x world position + * @param worldY The y world position + * @param worldZ The z world position + * @param chunkData The chunk data to add at the specified positions + */ + public void addChunkDataToCache(int worldX, int worldY, int worldZ, ChunkData chunkData){ + cacheMap.put(getKey(worldX,worldY,worldZ),chunkData); while(cacheList.size() > cacheSize){ String currentChunk = cacheList.remove(0); cacheMap.remove(currentChunk); @@ -75,29 +42,41 @@ public class ClientTerrainCache { } - - public String getKey(int x, int y){ - return x + "-" + y; + /** + * Generates a key for the cache based on the position provided + * @param worldX The x world position + * @param worldY The y world position + * @param worldZ The z world position + * @return The cache key + */ + public String getKey(int worldX, int worldY, int worldZ){ + return worldX + "_" + worldY + "_" + worldZ; } - - public boolean containsHeightmapAtChunkPoint(int x, int y){ - return cacheMap.containsKey(getKey(x,y)); + /** + * Checks whether the cache contains chunk data at a given world point + * @param worldX The x world position + * @param worldY The y world position + * @param worldZ The z world position + * @return True if the cache contains chunk data at the specified point, false otherwise + */ + public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){ + return cacheMap.containsKey(getKey(worldX,worldY,worldZ)); } - //ALL RETRIEVE - public float[][] getHeightmapAtChunkPoint(int x, int y){ - return cacheMap.get(getKey(x,y)); - } - - - - - public void setClientWorldData(ClientWorldData clientWorldData){ - this.clientWorldData = clientWorldData; + /** + * Gets chunk data at the given world point + * @param worldX The x world position + * @param worldY The y world position + * @param worldZ The z world position + * @return The chunk data if it exists, null otherwise + */ + public ChunkData getSubChunkDataAtPoint(int worldX, int worldY, int worldZ){ + return cacheMap.get(getKey(worldX,worldY,worldZ)); } + } diff --git a/src/main/java/electrosphere/client/terrain/cache/LoadingChunk.java b/src/main/java/electrosphere/client/terrain/cache/LoadingChunk.java deleted file mode 100644 index ad36b016..00000000 --- a/src/main/java/electrosphere/client/terrain/cache/LoadingChunk.java +++ /dev/null @@ -1,83 +0,0 @@ -package electrosphere.client.terrain.cache; - -import electrosphere.client.scene.ClientWorldData; -import electrosphere.game.terrain.processing.TerrainInterpolator; -import java.util.ArrayList; -import java.util.List; - -/** - * - * @author amaterasu - */ -public class LoadingChunk { - - int worldX, worldY; - int totalNumMessages; - int numReceivedMessages = 0; - - ClientWorldData clientWorldData; - - float[][] macroValues; - long[][] randomizer; - List modification = new ArrayList(); - - public LoadingChunk(int worldX, int worldY, int numMessages, ClientWorldData clientWorldData){ - this.worldX = worldX; - this.worldY = worldY; - this.totalNumMessages = numMessages; - this.clientWorldData = clientWorldData; - } - - public void addMacroValues(float[][] macroValues){ - this.macroValues = macroValues; - } - - public void addRandomizer(long[][] randomizer){ - this.randomizer = randomizer; - } - - public void addModification(int worldX, int worldY, int locationX, int locationY, float value){ -// System.out.println("Client add modification"); - ChunkModification newModification = new ChunkModification(worldX, worldY, locationX, locationY, value); - modification.add(newModification); - } - - public void incrementMessageCount(){ - numReceivedMessages++; - } - - public boolean isComplete(){ - return numReceivedMessages >= totalNumMessages && macroValues != null && randomizer != null; - } - - public float[][] exportFloats(){ - float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk( - macroValues, - randomizer, - clientWorldData.getDynamicInterpolationRatio(), - clientWorldData.getRandomDampener() - ); - if(modification != null){ - for(ChunkModification modification : modification){ -// System.out.println("Apply modification"); - heightmap = modification.applyModification(heightmap); - } - } - return heightmap; - } - - public int getWorldX() { - return worldX; - } - - public int getWorldY() { - return worldY; - } - - public ClientWorldData getClientWorldData(){ - return this.clientWorldData; - } - - - -} diff --git a/src/main/java/electrosphere/client/terrain/cache/LoadingChunkCache.java b/src/main/java/electrosphere/client/terrain/cache/LoadingChunkCache.java deleted file mode 100644 index f112a4de..00000000 --- a/src/main/java/electrosphere/client/terrain/cache/LoadingChunkCache.java +++ /dev/null @@ -1,50 +0,0 @@ -package electrosphere.client.terrain.cache; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * - * @author amaterasu - */ -public class LoadingChunkCache { - Map cacheMap = new ConcurrentHashMap(); - List cacheList = new CopyOnWriteArrayList(); - - - public LoadingChunkCache(){ - } - - - //USED TO ADD macro values - public void addLoadingChunkToCache(LoadingChunk chunk){ - cacheMap.put(getKey(chunk.worldX, chunk.worldY),chunk); - } - - public LoadingChunk fetch(String key){ - return cacheMap.get(key); - } - - - public String getKey(int worldX, int worldY){ - return worldX + "-" + worldY; - } - - public boolean containsKey(String key){ - return cacheMap.containsKey(key); - } - - public Collection getChunks(){ - return cacheMap.values(); - } - - public void remove(LoadingChunk chunk){ - cacheMap.remove(getKey(chunk.worldX,chunk.worldY)); - cacheList.remove(getKey(chunk.worldX,chunk.worldY)); - } - -} diff --git a/src/main/java/electrosphere/client/terrain/cells/ClientDataCell.java b/src/main/java/electrosphere/client/terrain/cells/ClientDataCell.java deleted file mode 100644 index e142055b..00000000 --- a/src/main/java/electrosphere/client/terrain/cells/ClientDataCell.java +++ /dev/null @@ -1,27 +0,0 @@ -package electrosphere.client.terrain.cells; - -import electrosphere.entity.Entity; -import java.util.LinkedList; -import java.util.List; - -/** - * - * @author amaterasu - */ -public class ClientDataCell { - List entities = new LinkedList(); - - - public ClientDataCell(){ - - } - - public void addEntity(Entity e){ - entities.add(e); - } - - public void removeEntity(Entity e){ - entities.remove(e); - } - -} diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java index c17b17be..24d26ffd 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java @@ -1,12 +1,16 @@ package electrosphere.client.terrain.cells; +import electrosphere.client.terrain.cache.ChunkData; +import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.collision.dispatch.CollisionObject; import electrosphere.dynamics.RigidBody; import electrosphere.engine.Globals; +import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.terrain.TerrainChunk; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.terrain.processing.TerrainInterpolator; @@ -24,20 +28,19 @@ import java.util.LinkedList; import java.util.List; import org.joml.Quaternionf; +import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector3i; /** * * @author satellite */ public class DrawCell { - int cellX; - int cellY; + //the position of the draw cell in world coordinates + Vector3i worldPos; - float[][] heightmap; - float[][] texturemap; - - int dynamicInterpolationRatio; + ChunkData data; Entity modelEntity; @@ -64,31 +67,17 @@ public class DrawCell { /** - * Catches for this function: drawArray's dimensions need to be equal to drawWidth and 1 greater than cellWidth - * because the model creation code for terrain heightmaps sucks :D - * 06/03/2021 - * - * - * ITS NOT EVEN UP TO DATE! - * 06/13/2021 - * - * //@param drawArray + * Constructs a drawcell object */ public static DrawCell generateTerrainCell( - int cellX, - int cellY, - float[][] heightmap, - float[][] texturemap, - int dynamicInterpolationRatio, + Vector3i worldPos, + ChunkData data, ShaderProgram program ){ DrawCell rVal = new DrawCell(); - rVal.cellX = cellX; - rVal.cellY = cellY; + rVal.worldPos = worldPos; rVal.program = program; - rVal.dynamicInterpolationRatio = dynamicInterpolationRatio; - rVal.heightmap = heightmap; - rVal.texturemap = texturemap; + rVal.data = data; return rVal; } @@ -96,52 +85,63 @@ public class DrawCell { * Generates a drawable entity based on this chunk * @param stride The stride between indices used to generate "sparse" meshes */ - public void generateDrawableEntity(int stride){ + public void generateDrawableEntity(){ if(modelEntity != null){ Globals.clientScene.deregisterEntity(modelEntity); } - Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride); - Mesh terrainMesh = terrainModel.meshes.get(0); - List textureList = new LinkedList(); - textureList.add(groundTextureOne); - textureList.add(groundTextureTwo); - textureList.add(groundTextureThree); - textureList.add(groundTextureFour); - List uniformList = new LinkedList(); - uniformList.add("groundTextures[0]"); - uniformList.add("groundTextures[1]"); - uniformList.add("groundTextures[2]"); - uniformList.add("groundTextures[3]"); - String terrainModelPath = Globals.assetManager.registerModel(terrainModel); - modelEntity = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(modelEntity, terrainModelPath); - EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList)); - modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); - modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); - LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio); - EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio)); + modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(data.getVoxelWeight(), data.getVoxelType()); + // TerrainChunk.createTerrainChunkEntity(); + // Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride); + // Mesh terrainMesh = terrainModel.meshes.get(0); + // List textureList = new LinkedList(); + // textureList.add(groundTextureOne); + // textureList.add(groundTextureTwo); + // textureList.add(groundTextureThree); + // textureList.add(groundTextureFour); + // List uniformList = new LinkedList(); + // uniformList.add("groundTextures[0]"); + // uniformList.add("groundTextures[1]"); + // uniformList.add("groundTextures[2]"); + // uniformList.add("groundTextures[3]"); + // String terrainModelPath = Globals.assetManager.registerModel(terrainModel); + // modelEntity = EntityCreationUtils.createClientSpatialEntity(); + // EntityCreationUtils.makeEntityDrawable(modelEntity, terrainModelPath); + // EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList)); + // modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); + // modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); + // LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio); + // EntityUtils.getPosition(modelEntity).set(getRealPos()); + ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos()); } public void retireCell(){ EntityUtils.cleanUpEntity(modelEntity); } - - public void generatePhysics(){ - //if we're in no-graphics mode, need to generate the entity - if(modelEntity == null){ - modelEntity = EntityCreationUtils.createClientSpatialEntity(); - modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); - EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio)); - } - //then actually perform the attach - physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap,false); - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(modelEntity); -// System.out.println("generate physics"); + + protected Vector3d getRealPos(){ + return new Vector3d( + worldPos.x * ChunkData.CHUNK_SIZE, + worldPos.y * ChunkData.CHUNK_SIZE, + worldPos.z * ChunkData.CHUNK_SIZE + ); } - public void destroyPhysics(){ - Globals.clientSceneWrapper.getCollisionEngine().deregisterCollidableEntity(modelEntity); - Globals.clientSceneWrapper.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject); - } +// public void generatePhysics(){ +// //if we're in no-graphics mode, need to generate the entity +// if(modelEntity == null){ +// modelEntity = EntityCreationUtils.createClientSpatialEntity(); +// modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); +// EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio)); +// } +// //then actually perform the attach +// physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap,false); +// Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(modelEntity); +// // System.out.println("generate physics"); +// } + +// public void destroyPhysics(){ +// Globals.clientSceneWrapper.getCollisionEngine().deregisterCollidableEntity(modelEntity); +// Globals.clientSceneWrapper.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject); +// } } diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java index fc7e7456..8aa88d4c 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java @@ -1,20 +1,25 @@ package electrosphere.client.terrain.cells; import electrosphere.client.scene.ClientWorldData; +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; +import electrosphere.entity.EntityUtils; import electrosphere.game.terrain.processing.TerrainInterpolator; -import electrosphere.game.collision.CommonWorldData; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.renderer.ShaderProgram; import electrosphere.server.terrain.manager.ServerTerrainManager; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.joml.Vector2i; import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector3i; /** * @@ -26,41 +31,40 @@ public class DrawCellManager { //the center of this cell manager's array in cell space int cellX; int cellY; + int cellZ; //the dimensions of the world that this cell manager can handles int cellWidth; - int cellHeight; //the width of a minicell in this manager int miniCellWidth; //all currently displaying mini cells - DrawCell[][] cells; - boolean[][] valid; - boolean[][] drawable; - boolean[][] updateable; - boolean[][] hasRequested; - boolean[][] needsPhysics; - boolean[][] hasPhysics; + Set cells; + Map keyCellMap = new HashMap(); + Set hasNotRequested; + Set hasRequested; + Set drawable; + Set undrawable; + Set updateable; ShaderProgram program; - int drawRadius = 5; + // int drawRadius = 5; int drawStepdownInterval = 3; int drawStepdownValue = 25; + + double drawRadius = 200; int physicsRadius = 3; int worldBoundDiscreteMin = 0; int worldBoundDiscreteMax = 0; - - //metadata about the game world - CommonWorldData commonWorldData; - + //client terrain manager // ClientTerrainManager clientTerrainManager; @@ -80,600 +84,273 @@ public class DrawCellManager { * @param discreteX The initial discrete position X coordinate * @param discreteY The initial discrete position Y coordinate */ - public DrawCellManager(CommonWorldData commonWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){ - this.commonWorldData = commonWorldData; - worldBoundDiscreteMax = (int)(commonWorldData.getWorldBoundMin().x / commonWorldData.getDynamicInterpolationRatio() * 1.0f); - // this.clientTerrainManager = clientTerrainManager; - cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1]; - valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - drawable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - updateable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - hasRequested = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - needsPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1]; - hasPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1]; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[x][y] = false; - drawable[x][y] = false; - updateable[x][y] = false; - hasRequested[x][y] = false; - } - } - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = true; - hasPhysics[x][y] = false; - } - } + public DrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){ + worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f); + cells = new HashSet(); + hasNotRequested = new HashSet(); + drawable = new HashSet(); + undrawable = new HashSet(); + updateable = new HashSet(); + hasRequested = new HashSet(); + cellX = discreteX; cellY = discreteY; + cellZ = discreteZ; program = Globals.terrainShaderProgram; - drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius(); + // drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius(); drawStepdownInterval = Globals.userSettings.getGameplayPhysicsCellRadius(); physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius(); + invalidateAllCells(); + update = true; } DrawCellManager(){ } - - public int getCellX(){ - return cellX; - } - - public int getCellY(){ - return cellY; - } - - public void setCellX(int x){ - cellX = x; - } - - public void setCellY(int y){ - cellY = y; - } - public void setCell(Vector2i cellPos){ + public void setCell(Vector3i cellPos){ cellX = cellPos.x; cellY = cellPos.y; + cellZ = cellPos.z; } - void updateInvalidCell(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < drawRadius * 2 + 1; y++){ - targetY = y; - if(!valid[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - - if(found){ - int currentCellX = cellX - drawRadius + targetX; - int currentCellY = cellY - drawRadius + targetY; - + void updateUnrequestedCell(){ + if(hasNotRequested.size() > 0){ + String targetKey = hasNotRequested.iterator().next(); + hasNotRequested.remove(targetKey); + Vector3i worldPos = getVectorFromKey(targetKey); + // Vector3i vector = getVectorFromKey(targetKey); + // int currentCellX = cellX - drawRadius + vector.x; + // int currentCellY = cellY - drawRadius + vector.y; + // int currentCellZ = cellZ - drawRadius + vector.z; if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ - if(containsHeightmapAtDiscretePoint(currentCellX, currentCellY)){ - cells[targetX][targetY] = DrawCell.generateTerrainCell( - currentCellX, - currentCellY, - getHeightmapAtPoint(currentCellX, currentCellY), - getTextureMapAtPoint(currentCellX, currentCellY), - commonWorldData.getDynamicInterpolationRatio(), - program - ); - valid[targetX][targetY] = true; - drawable[targetX][targetY] = false; - updateable[targetX][targetY] = false; - hasRequested[targetX][targetY] = false; - hasPhysics[targetX][targetY] = false; - needsPhysics[targetX][targetY] = true; -// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } - } else { - if(hasRequested[targetX][targetY] == false){ - //client should request macro values from server - Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkMessage(currentCellX, currentCellY)); - hasRequested[targetX][targetY] = true; - } - } - } else { - valid[targetX][targetY] = true; - drawable[targetX][targetY] = false; - updateable[targetX][targetY] = false; - hasRequested[targetX][targetY] = false; - hasPhysics[targetX][targetY] = false; - needsPhysics[targetX][targetY] = true; + worldPos.x >= 0 && + worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.y >= 0 && + worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.z >= 0 && + worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() + ){ + // if(!hasRequested.contains(targetKey)){ + //client should request chunk data from server + Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage( + worldPos.x, + worldPos.y, + worldPos.z + )); + undrawable.add(targetKey); + hasRequested.add(targetKey); + // } } } } + /** + * Makes one of the undrawable cells drawable + */ void makeCellDrawable(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < drawRadius * 2 + 1; y++){ - targetY = y; - if(valid[x][y] && !drawable[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - if(found){ - int currentCellX = cellX - drawRadius + targetX; - int currentCellY = cellY - drawRadius + targetY; + if(undrawable.size() > 0){ + String targetKey = undrawable.iterator().next(); + Vector3i worldPos = getVectorFromKey(targetKey); if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ - //physics radius calculation -// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } - //calculation for stride - int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius));//Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); - int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); - while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){ - stride = stride + 1; + worldPos.x >= 0 && + worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.y >= 0 && + worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.z >= 0 && + worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() + ){ + if(containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z)){ + DrawCell cell = DrawCell.generateTerrainCell( + worldPos, + Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z), + program + ); + cells.add(cell); + keyCellMap.put(targetKey,cell); + // undrawable.add(targetKey); + undrawable.remove(targetKey); + drawable.add(targetKey); + //make drawable entity + keyCellMap.get(targetKey).generateDrawableEntity(); } - //make drawable entity - cells[targetX][targetY].generateDrawableEntity(stride); } - drawable[targetX][targetY] = true; } } + /** + * Updates a cell that can be updated + */ void updateCellModel(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < drawRadius * 2 + 1; y++){ - targetY = y; - if(updateable[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - - if(found){ - int currentCellX = cellX - drawRadius + targetX; - int currentCellY = cellY - drawRadius + targetY; + if(updateable.size() > 0){ + String targetKey = updateable.iterator().next(); + updateable.remove(targetKey); + Vector3i worldPos = getVectorFromKey(targetKey); if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() + worldPos.x >= 0 && + worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.y >= 0 && + worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.z >= 0 && + worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() ){ // if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){ // needsPhysics[targetX][targetY] = true; // } - int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); - int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); - while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){ - stride = stride + 1; - } - cells[targetX][targetY].generateDrawableEntity(stride); + // int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); + // int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); + // while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){ + // stride = stride + 1; + // } + keyCellMap.get(targetKey).generateDrawableEntity(); } - updateable[targetX][targetY] = false; - drawable[targetX][targetY] = true; + drawable.add(targetKey); } } - public boolean containsInvalidCell(){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - for(int x = 0;x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(!valid[x][y]){ - return true; - } - } - } -// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -// return cells[0][0] == null || cells[1][0] == null || cells[0][1] == null | cells[1][1] == null; -// } - return false; + public boolean containsUnrequestedCell(){ + return hasNotRequested.size() > 0; } public boolean containsUndrawableCell(){ - for(int x = 0;x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(!drawable[x][y] && this.generateDrawables){ - return true; - } - } - } - return false; + return undrawable.size() > 0; } public boolean containsUpdateableCell(){ - for(int x = 0;x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(updateable[x][y] && this.generateDrawables){ - return true; - } - } - } - return false; - } - - public boolean containsPhysicsNeedingCell(){ - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - if(needsPhysics[x][y]){ - return true; - } - } - } - return false; - } - - public void addPhysicsToCell(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - targetY = y; -// System.out.println(x + " <=>w " + y); - if(needsPhysics[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - - if(found){ - int currentCellX = cellX - physicsRadius + targetX; - int currentCellY = cellY - physicsRadius + targetY; - if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ -// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } -// int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); -// int stride = Math.min(clientWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); -// while(clientWorldData.getDynamicInterpolationRatio() % stride != 0){ -// stride = stride + 1; -// } -// if(cells[targetX][targetY + drawRadius] != null){ - // System.out.println(targetX + " - " + targetY); - cells[targetX + drawRadius - physicsRadius][targetY + drawRadius - physicsRadius].generatePhysics(); -// } else { -// System.out.println("Current cell is null: " + currentCellX + " - " + currentCellY); -// } - } - needsPhysics[targetX][targetY] = false; - hasPhysics[targetX][targetY] = true; - } + return updateable.size() > 0; } - public void shiftChunksNegX(){ - //retire old graphics - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(cells[drawRadius * 2][y] != null){ - cells[drawRadius * 2][y].retireCell(); - } - } - //shift draw array - for(int x = drawRadius * 2; x > 0; x--){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - cells[x][y] = cells[x-1][y]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x-1][y]; - } - } - //invalidate edge of draw array - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[0][y] = false; - hasRequested[0][y] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = physicsRadius * 2; x > 0; x--){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = needsPhysics[x-1][y]; - hasPhysics[x][y] = hasPhysics[x-1][y]; - } - } - //invalidate edge of physics array - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[0][y] = true; - hasPhysics[0][y] = false; - } - } - - public void shiftChunksPosX(){ - //retire old graphics - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(cells[0][y] != null){ - cells[0][y].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - cells[x][y] = cells[x+1][y]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x+1][y]; - } - } - //invalidate edge of draw array - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[drawRadius * 2][y] = false; - hasRequested[drawRadius * 2][y] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = needsPhysics[x+1][y]; - hasPhysics[x][y] = hasPhysics[x+1][y]; - } - } - //invalidate edge of physics array - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[physicsRadius * 2][y] = true; - hasPhysics[physicsRadius * 2][y] = false; - } - } - - public void shiftChunksNegY(){ - //retire cells - for(int x = 0; x < drawRadius * 2 + 1; x++){ - if(cells[x][drawRadius * 2] != null){ - cells[x][drawRadius * 2].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = drawRadius * 2; y > 0; y--){ - cells[x][y] = cells[x][y-1]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x][y-1]; - } - } - //invalidate edge of draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - valid[x][0] = false; - hasRequested[x][0] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = physicsRadius * 2; y > 0; y--){ - needsPhysics[x][y] = needsPhysics[x][y-1]; - hasPhysics[x][y] = hasPhysics[x][y-1]; - } - } - //invalidate edge of physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - needsPhysics[x][0] = true; - hasPhysics[x][0] = false; - } - } - - public void shiftChunksPosY(){ - //retire old graphics - for(int x = 0; x < drawRadius * 2 + 1; x++){ - if(cells[x][0] != null){ - cells[x][0].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2; y++){ - cells[x][y] = cells[x][y+1]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x][y+1]; - } - } - //invalidate edge of draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - valid[x][drawRadius * 2] = false; - hasRequested[x][drawRadius * 2] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][0]){ - if(cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2; y++){ - needsPhysics[x][y] = needsPhysics[x][y+1]; - hasPhysics[x][y] = hasPhysics[x][y+1]; - } - } - //invalidate edge of physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - needsPhysics[x][physicsRadius * 2] = true; - hasPhysics[x][physicsRadius * 2] = false; - } - } public int transformRealSpaceToCellSpace(double input){ - return (int)(input / commonWorldData.getDynamicInterpolationRatio()); + return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio()); } - + /** + * Clears the valid set and adds all keys to invalid set + */ public void invalidateAllCells(){ - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[x][y] = false; + drawable.clear(); + hasNotRequested.clear(); + clearOutOfBoundsCells(); + queueNewCells(); + } + + /** + * Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly + * @param position The position of the player entity on current frame + */ + public void calculateDeltas(Vector3d position){ + //check if any not requested cells no longer need to be requested + clearOutOfBoundsCells(); + //check if any cells should be added + queueNewCells(); + } + + /** + * Clears all cells outside of draw radius + */ + private void clearOutOfBoundsCells(){ + Set cellsToRemove = new HashSet(); + for(DrawCell cell : cells){ + Vector3d realPos = cell.getRealPos(); + if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawRadius){ + cellsToRemove.add(cell); + } + } + for(DrawCell cell : cellsToRemove){ + cells.remove(cell); + String key = getCellKey(cell.worldPos.x, cell.worldPos.y, cell.worldPos.z); + hasNotRequested.remove(key); + drawable.remove(key); + undrawable.remove(key); + updateable.remove(key); + keyCellMap.remove(key); + hasRequested.remove(key); + } + } + + /** + * Queues new cells that are in bounds but not currently accounted for + */ + private void queueNewCells(){ + if(Globals.playerEntity != null && Globals.clientWorldData != null){ + Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); + for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){ + for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){ + for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_SIZE){ + Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z); + Vector3i worldPos = new Vector3i( + Globals.clientWorldData.convertRealToChunkSpace(newPos.x), + Globals.clientWorldData.convertRealToChunkSpace(newPos.y), + Globals.clientWorldData.convertRealToChunkSpace(newPos.z) + ); + Vector3d chunkRealSpace = new Vector3d( + Globals.clientWorldData.convertChunkToRealSpace(worldPos.x), + Globals.clientWorldData.convertChunkToRealSpace(worldPos.y), + Globals.clientWorldData.convertChunkToRealSpace(worldPos.z) + ); + if( + playerPos.distance(chunkRealSpace) < drawRadius && + worldPos.x >= 0 && + worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.y >= 0 && + worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() && + worldPos.z >= 0 && + worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() + ){ + String key = getCellKey( + Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.x), + Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.y), + Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.z) + ); + if(!keyCellMap.containsKey(key) && !hasNotRequested.contains(key) && !undrawable.contains(key) && !drawable.contains(key) && + !hasRequested.contains(key)){ + hasNotRequested.add(key); + } + } + } + } } } } - public void calculateDeltas(Vector3d oldPosition, Vector3d newPosition){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - if(transformRealSpaceToCellSpace(newPosition.x()) < transformRealSpaceToCellSpace(oldPosition.x())){ - shiftChunksNegX(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } else if(transformRealSpaceToCellSpace(newPosition.x()) > transformRealSpaceToCellSpace(oldPosition.x())){ - shiftChunksPosX(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } - - if(transformRealSpaceToCellSpace(newPosition.z()) < transformRealSpaceToCellSpace(oldPosition.z())){ - shiftChunksNegY(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } else if(transformRealSpaceToCellSpace(newPosition.z()) > transformRealSpaceToCellSpace(oldPosition.z())){ - shiftChunksPosY(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } -// } - } - + /** + * Updates cells that need updating in this manager + */ public void update(){ if(update){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - if(containsInvalidCell()){ - updateInvalidCell(); + if(containsUnrequestedCell() && !containsUndrawableCell()){ + updateUnrequestedCell(); } else if(containsUndrawableCell()){ makeCellDrawable(); } else if(containsUpdateableCell()){ updateCellModel(); - } else if(containsPhysicsNeedingCell()){ - addPhysicsToCell(); } } -// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -// if(cells[0][0] == null){ -// int arenaChunkWidth = 100; -// cells[0][0] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 0, -// 0, -// arenaChunkWidth, -// program -// ); -// cells[0][0].generateDrawableEntity(1); -// } else if(cells[0][1] == null){ -// int arenaChunkWidth = 100; -// cells[0][1] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 0, -// 1, -// arenaChunkWidth, -// program -// ); -// cells[0][1].generateDrawableEntity(1); -// } else if(cells[1][0] == null){ -// int arenaChunkWidth = 100; -// cells[1][0] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 1, -// 0, -// arenaChunkWidth, -// program -// ); -// cells[1][0].generateDrawableEntity(1); -// } else if(cells[1][1] == null){ -// int arenaChunkWidth = 100; -// cells[1][1] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 1, -// 1, -// arenaChunkWidth, -// program -// ); -// cells[1][1].generateDrawableEntity(1); -// } -// } - } - -// public float getElevationAtRealPoint(float realPointX, float realPointY){ -//// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ -// return terrainManager.getHeightAtPosition(realPointX, realPointY); -//// } -//// if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -//// return 0; -//// } -//// return 0; -// } - - - public boolean canValidateCell(){ - boolean rVal = false; - return rVal; } + + /** + * Splits a cell key into its constituent coordinates in array format. + * @param cellKey The cell key to split + * @return The coordinates in array format + */ + // private int[] splitKeyToCoordinates(String cellKey){ + // int[] rVal = new int[3]; + // String[] components = cellKey.split("_"); + // for(int i = 0; i < 3; i++){ + // rVal[i] = Integer.parseInt(components[i]); + // } + // return rVal; + // } public boolean coordsInPhysicsSpace(int worldX, int worldY){ return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius; @@ -683,38 +360,44 @@ public class DrawCellManager { this.generateDrawables = generate; } - boolean containsHeightmapAtDiscretePoint(int currentCellX, int currentCellY){ + boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){ if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.containsHeightmapAtDiscretePoint(currentCellX, currentCellY); + return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldX,worldY,worldZ); } return true; } - float[][] getHeightmapAtPoint(int currentCellX, int currentCellY){ - if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY); - } - return Globals.serverTerrainManager.getChunk(currentCellX, currentCellY).getHeightMap(); + /** + * Gets the chunk data at a given point + * @param worldX The world position x component of the cell + * @param worldY The world position y component of the cell + * @param worldZ The world position z component of the cell + * @return The chunk data at the specified points + */ + ChunkData getChunkDataAtPoint(int worldX, int worldY, int worldZ){ + return Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldX,worldY,worldZ); } - float[][] getTextureMapAtPoint(int currentCellX, int currentCellY){ - if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.getTextureMapAtPoint(currentCellX,currentCellY); - } else { - //hacky fix to +2 to this, I think the interpolation ratio was different for server/client data - //now that we're merging/ambiguous within this class, it's out of bounds-ing unless I +2 - //TODO: investigate - float[][] rVal = new float[commonWorldData.getDynamicInterpolationRatio() + 2][commonWorldData.getDynamicInterpolationRatio() + 2]; - rVal[1][1] = 1; - rVal[2][1] = 1; - rVal[3][1] = 1; - rVal[4][1] = 1; - rVal[5][1] = 1; - rVal[5][2] = 1; - rVal[6][1] = 1; - rVal[6][2] = 1; - return rVal; - } + + /** + * Gets a unique key for the cell + * @param worldX The world position x component of the cell + * @param worldY The world position y component of the cell + * @param worldZ The world position z component of the cell + * @return The key + */ + private String getCellKey(int worldX, int worldY, int worldZ){ + return worldX + "_" + worldY + "_" + worldZ; + } + + /** + * Parses a vector3i from the cell key + * @param key The cell key + * @return The vector3i containing the components of the cell key + */ + private Vector3i getVectorFromKey(String key){ + String[] keyComponents = key.split("_"); + return new Vector3i(Integer.parseInt(keyComponents[0]),Integer.parseInt(keyComponents[1]),Integer.parseInt(keyComponents[2])); } diff --git a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java index 5950e9d9..5b21831c 100644 --- a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java +++ b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java @@ -1,27 +1,34 @@ package electrosphere.client.terrain.manager; import electrosphere.client.scene.ClientWorldData; +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ClientTerrainCache; -import electrosphere.client.terrain.cache.LoadingChunk; -import electrosphere.client.terrain.cache.LoadingChunkCache; import electrosphere.engine.Globals; import electrosphere.entity.types.terrain.TerrainChunkData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.renderer.Model; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration; +import electrosphere.server.terrain.manager.ServerTerrainManager; -import java.util.Collections; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; +/** + * Manages terrain storage and access on the client + */ public class ClientTerrainManager { //queues messages from server List messageQueue = new CopyOnWriteArrayList(); + //The interpolation ratio of terrain + public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO; //caches chunks from server static final int CACHE_SIZE = 50; @@ -29,18 +36,17 @@ public class ClientTerrainManager { //used for caching the macro values ClientTerrainCache terrainCache; - //used for caching loading chunks that are still streaming over the net - LoadingChunkCache loadingChunkCache; - - + //The world data for the client ClientWorldData clientWorldData; + //The queue of terrain chunk data to be buffered to gpu static List terrainChunkGenerationQueue = new CopyOnWriteArrayList(); - + /** + * Constructor + */ public ClientTerrainManager(){ terrainCache = new ClientTerrainCache(CACHE_SIZE); - loadingChunkCache = new LoadingChunkCache(); } @@ -49,89 +55,35 @@ public class ClientTerrainManager { for(TerrainMessage message : messageQueue){ messageQueue.remove(message); switch(message.getMessageSubtype()){ - case MACROVALUE: -// terrainCache.addChunkValuesToCache(message.getlocationX(), message.getlocationY(), macroValues, randomizer); - if(loadingChunkCache.containsKey(loadingChunkCache.getKey(message.getworldX(), message.getworldY()))){ - float[][] macroValues = new float[5][5]; - long[][] randomizer = new long[5][5]; - //macro values - macroValues[0][0] = message.getmacroValue00(); - macroValues[0][1] = message.getmacroValue01(); - macroValues[0][2] = message.getmacroValue02(); - macroValues[0][3] = message.getmacroValue03(); - macroValues[0][4] = message.getmacroValue04(); - macroValues[1][0] = message.getmacroValue10(); - macroValues[1][1] = message.getmacroValue11(); - macroValues[1][2] = message.getmacroValue12(); - macroValues[1][3] = message.getmacroValue13(); - macroValues[1][4] = message.getmacroValue14(); - macroValues[2][0] = message.getmacroValue20(); - macroValues[2][1] = message.getmacroValue21(); - macroValues[2][2] = message.getmacroValue22(); - macroValues[2][3] = message.getmacroValue23(); - macroValues[2][4] = message.getmacroValue24(); - macroValues[3][0] = message.getmacroValue30(); - macroValues[3][1] = message.getmacroValue31(); - macroValues[3][2] = message.getmacroValue32(); - macroValues[3][3] = message.getmacroValue33(); - macroValues[3][4] = message.getmacroValue34(); - macroValues[4][0] = message.getmacroValue40(); - macroValues[4][1] = message.getmacroValue41(); - macroValues[4][2] = message.getmacroValue42(); - macroValues[4][3] = message.getmacroValue43(); - macroValues[4][4] = message.getmacroValue44(); - //randomizer - randomizer[0][0] = message.getrandomizerValue00(); - randomizer[0][1] = message.getrandomizerValue01(); - randomizer[0][2] = message.getrandomizerValue02(); - randomizer[0][3] = message.getrandomizerValue03(); - randomizer[0][4] = message.getrandomizerValue04(); - randomizer[1][0] = message.getrandomizerValue10(); - randomizer[1][1] = message.getrandomizerValue11(); - randomizer[1][2] = message.getrandomizerValue12(); - randomizer[1][3] = message.getrandomizerValue13(); - randomizer[1][4] = message.getrandomizerValue14(); - randomizer[2][0] = message.getrandomizerValue20(); - randomizer[2][1] = message.getrandomizerValue21(); - randomizer[2][2] = message.getrandomizerValue22(); - randomizer[2][3] = message.getrandomizerValue23(); - randomizer[2][4] = message.getrandomizerValue24(); - randomizer[3][0] = message.getrandomizerValue30(); - randomizer[3][1] = message.getrandomizerValue31(); - randomizer[3][2] = message.getrandomizerValue32(); - randomizer[3][3] = message.getrandomizerValue33(); - randomizer[3][4] = message.getrandomizerValue34(); - randomizer[4][0] = message.getrandomizerValue40(); - randomizer[4][1] = message.getrandomizerValue41(); - randomizer[4][2] = message.getrandomizerValue42(); - randomizer[4][3] = message.getrandomizerValue43(); - randomizer[4][4] = message.getrandomizerValue44(); - LoadingChunk inProgressChunk = loadingChunkCache.fetch(loadingChunkCache.getKey(message.getworldX(), message.getworldY())); - inProgressChunk.addMacroValues(macroValues); - inProgressChunk.addRandomizer(randomizer); - inProgressChunk.incrementMessageCount(); - } else { - bouncedMessages.add(message); + case SENDCHUNKDATA: { + int[][][] values = new int[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; + float[][][] weights = new float[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE]; + ByteBuffer buffer = ByteBuffer.wrap(message.getchunkData()); + FloatBuffer floatBuffer = buffer.asFloatBuffer(); + for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ + for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ + for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ + weights[x][y][z] = floatBuffer.get(); + } + } } - break; - case CHUNKLOADSTART: - if(clientWorldData != null){ - LoadingChunk newChunk = new LoadingChunk(message.getworldX(),message.getworldY(),(int)message.getvalue(),clientWorldData); - loadingChunkCache.addLoadingChunkToCache(newChunk); - newChunk.incrementMessageCount(); - } else { - bouncedMessages.add(message); + IntBuffer intView = buffer.asIntBuffer(); + intView.position(floatBuffer.position()); + for(int x = 0; x < ChunkData.CHUNK_SIZE; x++){ + for(int y = 0; y < ChunkData.CHUNK_SIZE; y++){ + for(int z = 0; z < ChunkData.CHUNK_SIZE; z++){ + values[x][y][z] = intView.get(); + } + } } - break; - case HEIGHTMAPMODIFICATION: - if(loadingChunkCache.containsKey(loadingChunkCache.getKey(message.getworldX(), message.getworldY()))){ - LoadingChunk inProgressChunk = loadingChunkCache.fetch(loadingChunkCache.getKey(message.getworldX(), message.getworldY())); - inProgressChunk.addModification(message.getworldX(), message.getworldZ(), message.getlocationX(), message.getlocationZ(), message.getvalue()); - inProgressChunk.incrementMessageCount(); - } else { - bouncedMessages.add(message); - } - break; + ChunkData data = new ChunkData(); + data.setVoxelType(values); + data.setVoxelWeight(weights); + terrainCache.addChunkDataToCache( + message.getworldX(), message.getworldY(), message.getworldZ(), + data + ); + } break; default: LoggerInterface.loggerEngine.WARNING("ClientTerrainManager: unhandled network message of type" + message.getMessageSubtype()); break; @@ -146,88 +98,30 @@ public class ClientTerrainManager { messageQueue.add(message); } - public boolean containsHeightmapAtDiscretePoint(int x, int y){ - return terrainCache.containsHeightmapAtChunkPoint(x, y); + public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){ + return terrainCache.containsChunkDataAtWorldPoint(worldX, worldY, worldZ); } - public boolean containsHeightmapAtRealPoint(double x, double z){ + public boolean containsChunkDataAtRealPoint(double x, double y, double z){ assert clientWorldData != null; - return terrainCache.containsHeightmapAtChunkPoint(clientWorldData.convertRealToChunkSpace(x), clientWorldData.convertRealToChunkSpace(z)); + return terrainCache.containsChunkDataAtWorldPoint( + clientWorldData.convertRealToChunkSpace(x), + clientWorldData.convertRealToChunkSpace(y), + clientWorldData.convertRealToChunkSpace(z) + ); } - public float[][] getHeightmapAtPoint(int x, int y){ - return terrainCache.getHeightmapAtChunkPoint(x, y); + public ChunkData getChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){ + return terrainCache.getSubChunkDataAtPoint(worldX, worldY, worldZ); } - public double getHeightAtPosition(double x, double y){ - assert clientWorldData != null; - //get chunk coordinate space of input x,y - int chunkX = (int)Math.floor(x / clientWorldData.getDynamicInterpolationRatio()); - int chunkY = (int)Math.floor(y / clientWorldData.getDynamicInterpolationRatio()); - //get local coordinate space of input x,y - double localX = x - chunkX * clientWorldData.getDynamicInterpolationRatio(); - double localY = y - chunkY * clientWorldData.getDynamicInterpolationRatio(); - //get chunk elevation map - float[][] chunkElevationMap = getHeightmapAtPoint(chunkX,chunkY); - //floored variants of local values - int localXf = (int)Math.floor(localX); - int localYf = (int)Math.floor(localY); - - /* - Average some inner value. - - 01 11 - 0.3 0.4 0.5 - 0.1 0.2 0.3 - 00 10 - */ - //interp elevation from map - float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0]; - float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0]; - float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1]; - float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1]; - - double rVal = - (1-(localX-localXf))*(1-(localY-localYf)) * elevation00 + - ( (localX-localXf))*(1-(localY-localYf)) * elevation10 + - (1-(localX-localXf))*( (localY-localYf)) * elevation01 + - ( (localX-localXf))*( (localY-localYf)) * elevation11 - ; - - return rVal; - } - - public float[][] getTextureMapAtPoint(int x, int y){ - assert clientWorldData != null; - float[][] rVal = new float[clientWorldData.getDynamicInterpolationRatio()][clientWorldData.getDynamicInterpolationRatio()]; - rVal[1][1] = 1; - rVal[2][1] = 1; - rVal[3][1] = 1; - rVal[4][1] = 1; - rVal[5][1] = 1; - rVal[5][2] = 1; - rVal[6][1] = 1; - rVal[6][2] = 1; - return rVal; - } - - public void ejectLoadedChunks(){ - if(clientWorldData != null){ - List chunksToEject = new LinkedList(); - for(LoadingChunk chunk : loadingChunkCache.getChunks()){ - if(chunk.isComplete() && chunk.getClientWorldData() != null){ - float[][] heightMap = chunk.exportFloats(); - terrainCache.addFloatsToCache(chunk.getWorldX(), chunk.getWorldY(), heightMap); - chunksToEject.add(chunk); - } - } - for(LoadingChunk loadedChunk : chunksToEject){ - loadingChunkCache.remove(loadedChunk); - } - } - } + /** + * Queues a terrain 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 terrain model when it makes it to gpu + */ public static String queueTerrainGridGeneration(TerrainChunkData data){ String promisedHash = ""; UUID newUUID = UUID.randomUUID(); @@ -237,6 +131,9 @@ public class ClientTerrainManager { return promisedHash; } + /** + * Pushes all terrain data in queue to the gpu and registers the resulting models + */ public static void generateTerrainChunkGeometry(){ for(TerrainChunkGenQueueItem queueItem : terrainChunkGenerationQueue){ Model terrainModel = TerrainChunkModelGeneration.generateTerrainModel(queueItem.getData()); @@ -244,14 +141,5 @@ public class ClientTerrainManager { } terrainChunkGenerationQueue.clear(); } - - /** - * Sets the client world data that this terrain manager references - * @param clientWorldData The client world data - */ - public void setClientWorldData(ClientWorldData clientWorldData){ - this.clientWorldData = clientWorldData; - this.terrainCache.setClientWorldData(clientWorldData); - } } diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index ecfed984..6bc29d88 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -31,7 +31,7 @@ import electrosphere.entity.Entity; import electrosphere.entity.Scene; import electrosphere.entity.types.hitbox.HitboxManager; import electrosphere.game.collision.CollisionEngine; -import electrosphere.game.collision.CommonWorldData; +import electrosphere.game.collision.CollisionWorldData; import electrosphere.game.config.UserSettings; import electrosphere.game.server.structure.virtual.StructureManager; import electrosphere.game.server.world.MacroData; @@ -64,7 +64,6 @@ import electrosphere.server.ai.AIManager; import electrosphere.server.datacell.EntityDataCellMapper; import electrosphere.server.datacell.GriddedDataCellManager; import electrosphere.server.datacell.RealmManager; -import electrosphere.server.datacell.physics.DataCellPhysicsManager; import electrosphere.server.db.DatabaseController; import electrosphere.server.pathfinding.NavMeshManager; import electrosphere.server.simulation.MacroSimulation; @@ -157,7 +156,6 @@ public class Globals { public static ServerWorldData serverWorldData; public static RealmManager realmManager; public static EntityDataCellMapper entityDataCellMapper; - public static DataCellPhysicsManager dataCellPhysicsManager; // //Player manager @@ -299,7 +297,7 @@ public class Globals { public static int openInventoriesCount = 0; //collision world data - public static CommonWorldData commonWorldData; + public static CollisionWorldData commonWorldData; //structure manager public static StructureManager structureManager; diff --git a/src/main/java/electrosphere/engine/loadingthreads/ArenaLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ArenaLoading.java index 364ccebb..8ed49334 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ArenaLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ArenaLoading.java @@ -36,8 +36,6 @@ public class ArenaLoading { LoadingUtils.initAuthenticationManager(); //initialize the server thread (server only) LoadingUtils.initServerThread(); - //collision engine - LoadingUtils.initCommonWorldData(Globals.RUN_SERVER); //init gridded datacell manager LoadingUtils.initGriddedRealm(); //initialize the "virtual" objects simulation diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 4d11c87f..0b0ef5d9 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -75,10 +75,6 @@ public class ClientLoading { loadingWindow.setVisible(true); //disable menu input Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT); - //collision engine - if(!Globals.RUN_SERVER){ - LoadingUtils.initCommonWorldData(Globals.RUN_SERVER); - } //initialize the "real" objects simulation initClientSimulation(); //initialize the cell manager (client) @@ -212,14 +208,20 @@ public class ClientLoading { } static void initDrawCellManager(){ + while(Globals.clientWorldData == null){ + try { + TimeUnit.MILLISECONDS.sleep(10); + } catch (InterruptedException ex) { + } + } //initialize draw cell manager - Globals.drawCellManager = new DrawCellManager(Globals.commonWorldData, Globals.clientTerrainManager, 0, 0); + Globals.drawCellManager = new DrawCellManager(Globals.clientTerrainManager, 0, 0, 0); //set our draw cell manager to actually generate drawable chunks Globals.drawCellManager.setGenerateDrawables(true); //Alerts the client simulation that it should start loading terrain Globals.clientSimulation.setLoadingTerrain(true); //wait for all the terrain data to arrive - while(Globals.drawCellManager.containsInvalidCell()){ + while(Globals.drawCellManager.containsUnrequestedCell()){ // Globals.drawCellManager.updateInvalidCell(); try { TimeUnit.MILLISECONDS.sleep(10); @@ -237,12 +239,12 @@ public class ClientLoading { // System.out.println("undrawable"); } - while(Globals.drawCellManager.containsPhysicsNeedingCell()){ - try { - TimeUnit.MILLISECONDS.sleep(10); - } catch (InterruptedException ex) { - } - } + // while(Globals.drawCellManager.containsPhysicsNeedingCell()){ + // try { + // TimeUnit.MILLISECONDS.sleep(10); + // } catch (InterruptedException ex) { + // } + // } // System.out.println("Draw Cell Manager ready"); } diff --git a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java index a3d62216..d587af19 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java @@ -29,7 +29,7 @@ public class DebugSPWorldLoading { WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); loadingWindow.setVisible(true); - Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0); + Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0); if(!SaveUtils.getSaves().contains("random_sp_world")){ // //the juicy server GENERATION part @@ -63,8 +63,6 @@ public class DebugSPWorldLoading { LoadingUtils.initLocalConnection(); //initialize the "real" objects simulation LoadingUtils.initMicroSimulation(); - //collision engine - LoadingUtils.initCommonWorldData(Globals.RUN_SERVER); //init game specific stuff (ie different skybox colors) LoadingUtils.initGameGraphicalEntities(); //set simulations to ready if they exist diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java index b1270871..1ae859cb 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java @@ -20,7 +20,7 @@ import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.state.movement.ApplyRotationTree; import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureUtils; -import electrosphere.game.collision.CommonWorldData; +import electrosphere.game.collision.CollisionWorldData; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.game.server.town.Town; @@ -54,7 +54,7 @@ public class LoadingUtils { Actually initialize the terrain manager */ float randomDampener = 0.0f; //0.25f; - Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0); + Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,randomDampener,0); if(Globals.RUN_SERVER){ if(Globals.userSettings.gameplayGenerateWorld()){ Globals.serverTerrainManager.generate(); @@ -108,32 +108,32 @@ public class LoadingUtils { Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); } - static void initCommonWorldData(boolean FLAG_INIT_SERVER){ - if(Globals.commonWorldData == null){ - if(FLAG_INIT_SERVER){ - Globals.commonWorldData = new CommonWorldData(Globals.serverWorldData, Globals.serverTerrainManager); - if(Globals.macroSimulation != null){ - Town startTown = Globals.macroData.getTowns().get(0); - Vector2i firstPos = startTown.getPositions().get(0); - // double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth(); - // double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth(); - double startX = Globals.commonWorldData.convertWorldToReal(firstPos.x); - double startZ = Globals.commonWorldData.convertWorldToReal(firstPos.y); - Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ); - } - } else { - //basically wait for the client to receive the world metadata - while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){ - try { - TimeUnit.MILLISECONDS.sleep(5); - } catch (InterruptedException ex) { - } - } - //then create common world data - Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager); - } - } - } + // static void initCommonWorldData(boolean FLAG_INIT_SERVER){ + // if(Globals.commonWorldData == null){ + // if(FLAG_INIT_SERVER){ + // Globals.commonWorldData = new CommonWorldData(Globals.serverWorldData, Globals.serverTerrainManager); + // if(Globals.macroSimulation != null){ + // Town startTown = Globals.macroData.getTowns().get(0); + // Vector2i firstPos = startTown.getPositions().get(0); + // // double startX = firstPos.x * Globals.serverTerrainManager.getChunkWidth(); + // // double startZ = firstPos.y * Globals.serverTerrainManager.getChunkWidth(); + // double startX = Globals.commonWorldData.convertWorldToReal(firstPos.x); + // double startZ = Globals.commonWorldData.convertWorldToReal(firstPos.y); + // Globals.spawnPoint.set((float)startX,(float)Globals.commonWorldData.getElevationAtPoint(new Vector3d(startX,0,startZ)),(float)startZ); + // } + // } else { + // //basically wait for the client to receive the world metadata + // while(!Globals.clientConnection.getClientProtocol().hasReceivedWorld()){ + // try { + // TimeUnit.MILLISECONDS.sleep(5); + // } catch (InterruptedException ex) { + // } + // } + // //then create common world data + // Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager); + // } + // } + // } diff --git a/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java index 72641cbf..53ef2bd8 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java @@ -15,7 +15,7 @@ public class ServerLoading { // } //TODO: Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,randomDampener,0); - Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0); + Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0); SaveUtils.loadSave(Globals.currentSaveName); // LoadingUtils.initTerrainDataCellManager(); //TODO: set spawnpoint @@ -32,8 +32,6 @@ public class ServerLoading { LoadingUtils.initMacroSimulation(); //initialize the "real" objects simulation LoadingUtils.initMicroSimulation(); - //collision engine - LoadingUtils.initCommonWorldData(Globals.RUN_SERVER); //init game specific stuff (ie different skybox colors) LoadingUtils.initGameGraphicalEntities(); //set simulations to ready if they exist diff --git a/src/main/java/electrosphere/entity/EntityCreationUtils.java b/src/main/java/electrosphere/entity/EntityCreationUtils.java index 6fbfb992..a21464a6 100644 --- a/src/main/java/electrosphere/entity/EntityCreationUtils.java +++ b/src/main/java/electrosphere/entity/EntityCreationUtils.java @@ -103,4 +103,20 @@ public class EntityCreationUtils { Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE); } + /** + * MAkes an already created entity a drawable entity (client only) by backing it with an Actor + * @param entity The entity + * @param modelPath The model path for the model to back the actor + */ + public static void makeEntityDrawablePreexistingModel(Entity entity, String modelPath){ + entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath)); + entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); + entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity()); + entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1)); + entity.putData(EntityDataStrings.DATA_STRING_DRAW, true); + entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true); + Globals.clientScene.registerEntity(entity); + Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE); + } + } diff --git a/src/main/java/electrosphere/entity/EntityUtils.java b/src/main/java/electrosphere/entity/EntityUtils.java index fb52bf9b..a840f285 100644 --- a/src/main/java/electrosphere/entity/EntityUtils.java +++ b/src/main/java/electrosphere/entity/EntityUtils.java @@ -136,6 +136,11 @@ public class EntityUtils { if(Globals.realmManager != null){ Realm realm = Globals.realmManager.getEntityRealm(e); if(realm != null){ + //get data cell + ServerDataCell dataCell = realm.getEntityDataCellMapper().getEntityDataCell(e); + if(dataCell != null){ + dataCell.getScene().deregisterEntity(e); + } realm.getEntityDataCellMapper().ejectEntity(e); } Globals.realmManager.removeEntity(e); diff --git a/src/main/java/electrosphere/entity/ServerEntityUtils.java b/src/main/java/electrosphere/entity/ServerEntityUtils.java index 63af66cc..0ecf61a1 100644 --- a/src/main/java/electrosphere/entity/ServerEntityUtils.java +++ b/src/main/java/electrosphere/entity/ServerEntityUtils.java @@ -44,9 +44,9 @@ public class ServerEntityUtils { public static void repositionEntity(Entity entity, Vector3d position){ Realm realm = Globals.realmManager.getEntityRealm(entity); //if server, get current server data cell - if(Globals.RUN_SERVER){ - ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity)); - ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position); + ServerDataCell oldDataCell = realm.getDataCellManager().getDataCellAtPoint(EntityUtils.getPosition(entity)); + ServerDataCell newDataCell = realm.getDataCellManager().getDataCellAtPoint(position); + if(oldDataCell != newDataCell){ if(newDataCell != null){ ServerDataCell.moveEntityFromCellToCell(entity, oldDataCell, newDataCell); ServerBehaviorTreeUtils.updateCell(entity, oldDataCell); @@ -58,13 +58,13 @@ public class ServerEntityUtils { ServerBehaviorTreeUtils.updateCell(entity, oldDataCell); } } - // //if the server is also a client, update the drawcell manager to know to pull new chunks - // if(Globals.RUN_CLIENT){ - // Globals.drawCellManager.invalidateAllCells(); - // Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPos().x); - // Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z); - // } } + // //if the server is also a client, update the drawcell manager to know to pull new chunks + // if(Globals.RUN_CLIENT){ + // Globals.drawCellManager.invalidateAllCells(); + // Globals.drawCellManager.setCellX(Globals.clientPlayerData.getWorldPos().x); + // Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z); + // } //reposition entity CollisionObjUtils.positionCharacter(entity, Globals.spawnPoint); } diff --git a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java index 477f1961..267c4060 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java @@ -71,7 +71,7 @@ public class ServerCollidableTree implements BehaviorTree { Vector3d impulseForce = new Vector3d(impulse.getDirection()).mul(impulse.getForce()); if(impulse.type.matches(Collidable.TYPE_TERRAIN)){ hitTerrain = true; -// System.out.println("Impulse force: " + impulseForce); + // System.out.println("Impulse force: " + impulseForce); // System.out.println("Position: " + position); } if(impulse.type.matches(Collidable.TYPE_ITEM)){ diff --git a/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java b/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java index ab93f2ab..5bd33bb5 100644 --- a/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java +++ b/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java @@ -12,11 +12,8 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.BehaviorTree; -import electrosphere.entity.state.collidable.ClientCollidableTree; import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.collidable.ServerCollidableTree; -import electrosphere.entity.state.movement.FallTree; -import electrosphere.entity.state.movement.JumpTree; import electrosphere.entity.state.movement.ServerFallTree; import electrosphere.entity.state.movement.ServerJumpTree; import electrosphere.game.collision.collidable.Collidable; @@ -212,6 +209,7 @@ public class ServerGravityTree implements BehaviorTree { boolean rVal = false; for(Impulse impulse : collidable.getImpulses()){ if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){ + System.out.println(rVal); rVal = true; break; } else if( diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index 323fd8f3..b6d7cd51 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -496,6 +496,7 @@ public class CreatureUtils { */ public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, CreatureTemplate template){ CreatureType rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(type); + System.out.println("Creature"); Entity rVal = EntityCreationUtils.createServerEntity(realm, position); EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath()); diff --git a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java index b6312043..713f0c8d 100644 --- a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java +++ b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java @@ -285,46 +285,49 @@ public class HitboxUtils { Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT); Realm generatorRealm = Globals.realmManager.getEntityRealm(generatorParent); - HitboxManager realmHitboxManager = generatorRealm.getHitboxManager(); + if(generatorRealm != null){ + HitboxManager realmHitboxManager = generatorRealm.getHitboxManager(); - for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){ - - Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT); - - HitboxData generatorData = getHitboxData(generatorHitbox); - HitboxData receiverData = getHitboxData(receiverHitbox); - - //check projectile filters - List generatorFilter = generatorData.getEntityFilter(); - if(generatorFilter != null && generatorFilter.contains(receiverParent)){ - continue; - } - - List receiverFilter = receiverData.getEntityFilter(); - if(receiverFilter != null && receiverFilter.contains(generatorParent)){ - continue; - } - - //if there is a collision - //and the collision isn't against itself - //and both hitboxes are active - if( - receiverParent != generatorParent && - generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) && - generatorData.isActive() && - receiverData.isActive()){ - //if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc) - String generatorType = generatorData.getType(); - String receiverType = receiverData.getType(); + for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){ - if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ - serverDamageHitboxColision(generatorHitbox, receiverHitbox); + Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT); + + HitboxData generatorData = getHitboxData(generatorHitbox); + HitboxData receiverData = getHitboxData(receiverHitbox); + + //check projectile filters + List generatorFilter = generatorData.getEntityFilter(); + if(generatorFilter != null && generatorFilter.contains(receiverParent)){ + continue; + } + + List receiverFilter = receiverData.getEntityFilter(); + if(receiverFilter != null && receiverFilter.contains(generatorParent)){ + continue; } - if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ - serverDamageHitboxColision(receiverHitbox, generatorHitbox); + //if there is a collision + //and the collision isn't against itself + //and both hitboxes are active + if( + receiverParent != generatorParent && + generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) && + generatorData.isActive() && + receiverData.isActive()){ + //if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc) + String generatorType = generatorData.getType(); + String receiverType = receiverData.getType(); + + if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ + serverDamageHitboxColision(generatorHitbox, receiverHitbox); + } + + if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ + serverDamageHitboxColision(receiverHitbox, generatorHitbox); + } } } + } } diff --git a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java index 696ac01c..791c751b 100644 --- a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java +++ b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java @@ -1,171 +1,68 @@ package electrosphere.entity.types.terrain; import org.joml.Vector3d; -import org.joml.Vector3f; import electrosphere.client.terrain.manager.ClientTerrainManager; -import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityDataStrings; -import electrosphere.entity.EntityUtils; import electrosphere.entity.ServerEntityUtils; import electrosphere.game.collision.PhysicsUtils; -import electrosphere.renderer.Model; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration; +import electrosphere.server.datacell.Realm; +/** + * Utilities for creating terrain chunk entities + */ public class TerrainChunk { - public static Entity createTerrainChunkEntity(){ - - float[][][] terrainGrid = new float[][][]{ - //plane 1 - { - //row 1 - {1.0f,1.0f,-1.0f,-1.0f,-1.0f,}, - //row 2 - {-1.0f,1.0f,-1.0f,-1.0f,-1.0f,}, - //row 3 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 4 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 5 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - }, - //plane 2 - { - //row 1 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 2 - {-1.0f,0.3f,0.6f,0.3f,-1.0f,}, - //row 3 - {-1.0f,0.6f,1.0f,0.6f,-1.0f,}, - //row 4 - {-1.0f,0.3f,0.6f,0.3f,-1.0f,}, - //row 5 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - }, - //plane 3 - { - //row 1 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 2 - {-1.0f,0.7f,1.0f,0.7f,-1.0f,}, - //row 3 - {-1.0f,1.0f,1.0f,1.0f,-1.0f,}, - //row 4 - {-1.0f,0.7f,1.0f,0.7f,-1.0f,}, - //row 5 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - }, - //plane 4 - { - //row 1 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 2 - {-1.0f,0.3f,0.6f,0.3f,-1.0f,}, - //row 3 - {-1.0f,0.6f,1.0f,0.6f,-1.0f,}, - //row 4 - {-1.0f,0.3f,0.6f,0.3f,-1.0f,}, - //row 5 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - }, - //plane 5 - { - //row 1 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 2 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 3 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 4 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - //row 5 - {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,}, - }, - }; - - int[][][] textureGrid = new int[][][]{ - //plane 1 - { - //row 1 - {0, 0, 0, 0, 0}, - //row 2 - {0, 0, 0, 0, 0}, - //row 3 - {0, 0, 0, 0, 0}, - //row 4 - {0, 0, 0, 0, 0}, - //row 5 - {0, 0, 0, 0, 0}, - }, - //plane 2 - { - //row 1 - {0, 0, 0, 0, 0}, - //row 2 - {0, 0, 0, 0, 0}, - //row 3 - {0, 0, 0, 0, 0}, - //row 4 - {0, 0, 0, 0, 0}, - //row 5 - {0, 0, 0, 0, 0}, - }, - //plane 3 - { - //row 1 - {0, 0, 0, 0, 0}, - //row 2 - {0, 0, 0, 0, 0}, - //row 3 - {0, 0, 0, 0, 0}, - //row 4 - {0, 0, 0, 0, 0}, - //row 5 - {0, 0, 0, 0, 0}, - }, - //plane 4 - { - //row 1 - {0, 0, 0, 0, 0}, - //row 2 - {0, 0, 0, 0, 0}, - //row 3 - {0, 0, 0, 0, 0}, - //row 4 - {0, 0, 0, 0, 0}, - //row 5 - {0, 0, 0, 0, 0}, - }, - //plane 5 - { - //row 1 - {0, 0, 0, 0, 0}, - //row 2 - {0, 0, 0, 0, 0}, - //row 3 - {0, 0, 0, 0, 0}, - //row 4 - {0, 0, 0, 0, 0}, - //row 5 - {0, 0, 0, 0, 0}, - }, - }; + /** + * Creates a client terrain chunk based on weights and values provided + * @param weights The terrain weights + * @param values The values (block types) + * @return The terrain chunk entity + */ + public static Entity clientCreateTerrainChunkEntity(float[][][] weights, int[][][] values){ - TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(terrainGrid, textureGrid); + TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data); Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(rVal, modelPath); - // Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath); - PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data); + EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); + if(data.vertices.size() > 0){ + PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data); + } + rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); - ServerEntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1)); + return rVal; + } + + /** + * Creates a terrain chunk entity on the server + * @param realm The realm + * @param position The position of the chunk + * @param weights The weights for the terrain chunk + * @param values The values of each voxel in the chunk + * @return The terrain entity + */ + public static Entity serverCreateTerrainChunkEntity(Realm realm, Vector3d position, float[][][] weights, int[][][] values){ + + TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); + + Entity rVal = EntityCreationUtils.createServerEntity(realm, position); + if(data.vertices.size() > 0){ + PhysicsUtils.serverAttachTerrainChunkRigidBody(rVal, data); + rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); + ServerEntityUtils.initiallyPositionEntity(realm, rVal, position); + // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); + // Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); + // realm.getCollisionEngine().registerPhysicsEntity(physicsEntity); + + } + return rVal; } diff --git a/src/main/java/electrosphere/game/collision/CollisionEngine.java b/src/main/java/electrosphere/game/collision/CollisionEngine.java index 35282bf5..033dc190 100644 --- a/src/main/java/electrosphere/game/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/game/collision/CollisionEngine.java @@ -1,6 +1,7 @@ package electrosphere.game.collision; import electrosphere.collision.dispatch.CollisionWorld.ClosestConvexResultCallback; +import electrosphere.collision.dispatch.CollisionWorld.ConvexResultCallback; import electrosphere.collision.dispatch.CollisionWorld.LocalConvexResult; import electrosphere.collision.broadphase.BroadphaseInterface; import electrosphere.collision.broadphase.BroadphasePair; @@ -38,10 +39,13 @@ import org.joml.Vector3f; /** * - * @author amaterasu + * TODO: https://stackoverflow.com/questions/32445679/3d-java-collision-detection-with-jbullet */ public class CollisionEngine { + //world data that the collision engine leverages for position correction and the like + CollisionWorldData collisionWorldData; + DiscreteDynamicsWorld world; SequentialImpulseConstraintSolver solver; BroadphaseInterface broadphase; @@ -211,16 +215,16 @@ public class CollisionEngine { * @param positionToCheck the position that it wants to move to * @return true if it can occupy that position, false otherwise */ - public boolean checkCanOccupyPosition(CommonWorldData w, Entity e, Vector3d positionToCheck){ + public boolean checkCanOccupyPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){ boolean rVal = true; // // check world bounds // if( - positionToCheck.x < w.getWorldBoundMin().x || - positionToCheck.z < w.getWorldBoundMin().z || - positionToCheck.x > w.getWorldBoundMax().x || - positionToCheck.z > w.getWorldBoundMax().z + positionToCheck.x < collisionWorldData.getWorldBoundMin().x || + positionToCheck.z < collisionWorldData.getWorldBoundMin().z || + positionToCheck.x > collisionWorldData.getWorldBoundMax().x || + positionToCheck.z > collisionWorldData.getWorldBoundMax().z ){ return false; } @@ -246,7 +250,7 @@ public class CollisionEngine { * @return the position the engine recommends it move to instead (this is * guaranteed to be a valid position) */ - public Vector3d suggestMovementPosition(CommonWorldData w, Entity e, Vector3d positionToCheck){ + public Vector3d suggestMovementPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){ Vector3d suggestedPosition = new Vector3d(positionToCheck); // // adjust for minimum height (Terrain) @@ -258,17 +262,17 @@ public class CollisionEngine { // // adjust for world bounds // - if(suggestedPosition.x < w.getWorldBoundMin().x){ - suggestedPosition.x = w.getWorldBoundMin().x; + if(suggestedPosition.x < collisionWorldData.getWorldBoundMin().x){ + suggestedPosition.x = collisionWorldData.getWorldBoundMin().x; } - if(suggestedPosition.z < w.getWorldBoundMin().z){ - suggestedPosition.z = w.getWorldBoundMin().z; + if(suggestedPosition.z < collisionWorldData.getWorldBoundMin().z){ + suggestedPosition.z = collisionWorldData.getWorldBoundMin().z; } - if(suggestedPosition.x > w.getWorldBoundMax().x){ - suggestedPosition.x = w.getWorldBoundMax().x; + if(suggestedPosition.x > collisionWorldData.getWorldBoundMax().x){ + suggestedPosition.x = collisionWorldData.getWorldBoundMax().x; } - if(suggestedPosition.z > w.getWorldBoundMax().z){ - suggestedPosition.z = w.getWorldBoundMax().z; + if(suggestedPosition.z > collisionWorldData.getWorldBoundMax().z){ + suggestedPosition.z = collisionWorldData.getWorldBoundMax().z; } return suggestedPosition; } @@ -282,6 +286,13 @@ public class CollisionEngine { return collisionEntities; } + /** + * Sets the collision world data + * @param collisionWorldData The collision world data + */ + public void setCollisionWorldData(CollisionWorldData collisionWorldData){ + this.collisionWorldData = collisionWorldData; + } public boolean collisionSphereCheck(Entity hitbox1, HitboxData hitbox1data, Entity hitbox2, HitboxData hitbox2data){ @@ -384,17 +395,6 @@ public class CollisionEngine { - - -// private static class SpecificConvexResultCallback extends ConvexResultCallback { -// -// @Override -// public float addSingleResult(LocalConvexResult convexResult, boolean bln) { -// } -// -// } - - private static class ClosestConvexResultCallbackImpl extends ClosestConvexResultCallback { CollisionObject me; diff --git a/src/main/java/electrosphere/game/collision/CommonWorldData.java b/src/main/java/electrosphere/game/collision/CollisionWorldData.java similarity index 75% rename from src/main/java/electrosphere/game/collision/CommonWorldData.java rename to src/main/java/electrosphere/game/collision/CollisionWorldData.java index 72421fdd..d28fe978 100644 --- a/src/main/java/electrosphere/game/collision/CommonWorldData.java +++ b/src/main/java/electrosphere/game/collision/CollisionWorldData.java @@ -8,7 +8,7 @@ import electrosphere.server.terrain.manager.ServerTerrainManager; import org.joml.Vector3d; import org.joml.Vector3f; -public class CommonWorldData { +public class CollisionWorldData { @@ -20,17 +20,12 @@ public class CommonWorldData { ServerWorldData serverWorldData; ServerTerrainManager serverTerrainManager; - - - public CommonWorldData(ClientWorldData clientWorldData, ClientTerrainManager clientTerrainManager){ - this.clientWorldData = clientWorldData; - this.clientTerrainManager = clientTerrainManager; - } - - - public CommonWorldData(ServerWorldData serverWorldData, ServerTerrainManager serverTerrainManager){ + public CollisionWorldData(ServerWorldData serverWorldData){ this.serverWorldData = serverWorldData; - this.serverTerrainManager = serverTerrainManager; + } + + public CollisionWorldData(ClientWorldData clientWorldData){ + this.clientWorldData = clientWorldData; } @@ -44,17 +39,17 @@ public class CommonWorldData { * @param position * @return */ - public double getElevationAtPoint(Vector3d position){ - if(clientWorldData != null){ - if(clientTerrainManager.containsHeightmapAtRealPoint(position.x, position.z)){ - return clientTerrainManager.getHeightAtPosition(position.x, position.z); - } else { - return 0; - } - } else { - return serverTerrainManager.getHeightAtPosition(position.x, position.z); - } - } + // public double getElevationAtPoint(Vector3d position){ + // if(clientWorldData != null){ + // if(clientTerrainManager.containsHeightmapAtRealPoint(position.x, position.z)){ + // return clientTerrainManager.getHeightAtPosition(position.x, position.z); + // } else { + // return 0; + // } + // } else { + // return serverTerrainManager.getHeightAtPosition(position.x, position.z); + // } + // } public Vector3f getWorldBoundMin(){ diff --git a/src/main/java/electrosphere/game/collision/PhysicsUtils.java b/src/main/java/electrosphere/game/collision/PhysicsUtils.java index 0f372ab4..06c5df6a 100644 --- a/src/main/java/electrosphere/game/collision/PhysicsUtils.java +++ b/src/main/java/electrosphere/game/collision/PhysicsUtils.java @@ -15,6 +15,7 @@ import electrosphere.server.datacell.Realm; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; +import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.types.terrain.TerrainChunkData; import electrosphere.game.collision.collidable.Collidable; @@ -380,7 +381,6 @@ public class PhysicsUtils { Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain); terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); - // terrainRigidBody.getAabb(aabbMin, aabbMax); // // System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax); @@ -598,6 +598,18 @@ public class PhysicsUtils { return transform; } + + public static electrosphere.linearmath.Transform jomlVecToTransform(Vector3d vector){ + electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform(); + + javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f(); + transformMatrix.setIdentity(); + + transformMatrix.setTranslation(new javax.vecmath.Vector3f((float)vector.x, (float)vector.y, (float)vector.z)); + transform.set(transformMatrix); + + return transform; + } public static void setRigidBodyTransform(Vector3f position, Quaternionf rotation, CollisionObject body){ electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform(); diff --git a/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java b/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java index b2a6afae..1f55dea9 100644 --- a/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java +++ b/src/main/java/electrosphere/game/server/structure/virtual/VirtualStructureUtils.java @@ -20,28 +20,28 @@ import org.joml.Vector3f; public class VirtualStructureUtils { - public static Structure placeStructureAtPoint(float posX, float posY, String type){ + public static Structure placeStructureAtPoint(float posX, float posY, float posZ, String type){ int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX); int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY); Structure rVal = new Structure(worldX,worldY,posX,posY,type); Globals.macroData.addStructure(rVal); - double centerHeight = Globals.serverTerrainManager.getHeightAtPosition(posX, posY); - StructureType currentTypeObject = Globals.gameConfigCurrent.getStructureTypeMap().getType(type); - float radius = currentTypeObject.getRadius(); - for(int x = -(int)radius; x < radius; x++){ - for(int y = -(int)radius; y < radius; y++){ - int newWorldX = Globals.serverWorldData.convertRealToChunkSpace(posX + x); - int newWorldY = Globals.serverWorldData.convertRealToChunkSpace(posY + y); - double newLocationX = Globals.serverWorldData.getRelativeLocation(posX + x, newWorldX); - double newLocationY = Globals.serverWorldData.getRelativeLocation(posY + y, newWorldY); -// System.out.println("Set height: " + centerHeight); -// System.out.println("Deform in chunk: " + newWorldX + "," + newWorldY); - Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight); - } - } +// double centerHeight = Globals.serverTerrainManager.getHeightAtPosition(posX, posY, posZ); +// StructureType currentTypeObject = Globals.gameConfigCurrent.getStructureTypeMap().getType(type); +// float radius = currentTypeObject.getRadius(); +// for(int x = -(int)radius; x < radius; x++){ +// for(int y = -(int)radius; y < radius; y++){ +// int newWorldX = Globals.serverWorldData.convertRealToChunkSpace(posX + x); +// int newWorldY = Globals.serverWorldData.convertRealToChunkSpace(posY + y); +// double newLocationX = Globals.serverWorldData.getRelativeLocation(posX + x, newWorldX); +// double newLocationY = Globals.serverWorldData.getRelativeLocation(posY + y, newWorldY); +// // System.out.println("Set height: " + centerHeight); +// // System.out.println("Deform in chunk: " + newWorldX + "," + newWorldY); +// Globals.serverTerrainManager.deformTerrainAtLocationToValue(newWorldX, newWorldY, (int)(newLocationX), (int)(newLocationY), (float)centerHeight); +// } +// } Realm realm = Globals.realmManager.getRealms().iterator().next(); - StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf()); + // StructureUtils.serverSpawnBasicStructure(type, realm, new Vector3d(posX,(float)centerHeight + 2.4f,posY), new Quaternionf()); return rVal; } diff --git a/src/main/java/electrosphere/game/server/town/Town.java b/src/main/java/electrosphere/game/server/town/Town.java index cb32d82d..4ac87208 100644 --- a/src/main/java/electrosphere/game/server/town/Town.java +++ b/src/main/java/electrosphere/game/server/town/Town.java @@ -36,29 +36,29 @@ public class Town { public static Vector2i findValidTownLocation(){ for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){ for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){ - ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y); - float[][] macroValues = chunk.getMacroValues(); - float sum = 0; - int count = 0; - for(int i = 0; i < 5; i++){ - for(int j = 0; j < 5; j++){ - sum = sum + macroValues[i][j]; - count++; - } - } - float average = sum / (float)count; - if(average > 1000){ - float diffSum = 0; - for(int i = 0; i < 5; i++){ - for(int j = 0; j < 5; j++){ - diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]); - } - } - float averageDiff = diffSum / (float)count; - if(averageDiff < avgDiffThreshold){ - return new Vector2i(x,y); - } - } + // ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(x, y); + // float[][] macroValues = chunk.getMacroValues(); + // float sum = 0; + // int count = 0; + // for(int i = 0; i < 5; i++){ + // for(int j = 0; j < 5; j++){ + // sum = sum + macroValues[i][j]; + // count++; + // } + // } + // float average = sum / (float)count; + // if(average > 1000){ + // float diffSum = 0; + // for(int i = 0; i < 5; i++){ + // for(int j = 0; j < 5; j++){ + // diffSum = diffSum + (float)Math.abs(average - macroValues[i][j]); + // } + // } + // float averageDiff = diffSum / (float)count; + // if(averageDiff < avgDiffThreshold){ + // return new Vector2i(x,y); + // } + // } } } return null; diff --git a/src/main/java/electrosphere/logger/LoggerInterface.java b/src/main/java/electrosphere/logger/LoggerInterface.java index a75e9af0..39ff91b2 100644 --- a/src/main/java/electrosphere/logger/LoggerInterface.java +++ b/src/main/java/electrosphere/logger/LoggerInterface.java @@ -21,7 +21,7 @@ public class LoggerInterface { public static void initLoggers(){ loggerStartup = new Logger(LogLevel.WARNING); - loggerNetworking = new Logger(LogLevel.DEBUG); + loggerNetworking = new Logger(LogLevel.WARNING); loggerFileIO = new Logger(LogLevel.WARNING); loggerGameLogic = new Logger(LogLevel.WARNING); loggerRenderer = new Logger(LogLevel.WARNING); diff --git a/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java index 480744a2..0f480d53 100644 --- a/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java @@ -5,7 +5,11 @@ import javax.vecmath.Vector3d; import org.joml.Vector3f; import electrosphere.client.scene.ClientWorldData; +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.engine.Globals; +import electrosphere.entity.types.terrain.TerrainChunk; +import electrosphere.entity.types.terrain.TerrainChunkData; +import electrosphere.game.collision.CollisionWorldData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; @@ -17,24 +21,18 @@ public class TerrainProtocol { Globals.clientWorldData = new ClientWorldData( //Vector3f worldMinPoint, Vector3f worldMaxPoint, int dynamicInterpolationRatio, float randomDampener, int worldDiscreteSize new Vector3f(message.getworldMinX(),0,message.getworldMinY()), - new Vector3f(message.getworldMaxX(),0,message.getworldMaxY()), - message.getdynamicInterpolationRatio(), + new Vector3f(message.getworldMaxX(),3,message.getworldMaxY()), + ChunkData.CHUNK_SIZE, message.getrandomDampener(), message.getworldSizeDiscrete() ); - Globals.clientTerrainManager.setClientWorldData(Globals.clientWorldData); + Globals.clientSceneWrapper.getCollisionEngine().setCollisionWorldData(new CollisionWorldData(Globals.clientWorldData)); Globals.clientConnection.getClientProtocol().setHasReceivedWorld(true); break; - case MACROVALUE: - Globals.clientTerrainManager.attachTerrainMessage(message); - break; case SPAWNPOSITION: Globals.spawnPoint.set(message.getrealLocationX(),0.25,message.getrealLocationZ()); break; - case CHUNKLOADSTART: - Globals.clientTerrainManager.attachTerrainMessage(message); - break; - case HEIGHTMAPMODIFICATION: + case SENDCHUNKDATA: Globals.clientTerrainManager.attachTerrainMessage(message); break; default: diff --git a/src/main/java/electrosphere/net/parser/net/message/AuthMessage.java b/src/main/java/electrosphere/net/parser/net/message/AuthMessage.java index 0f4d7716..33524c58 100644 --- a/src/main/java/electrosphere/net/parser/net/message/AuthMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/AuthMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -42,29 +43,28 @@ public class AuthMessage extends NetworkMessage { this.pass = pass; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST: - if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST_SIZE){ return true; } else { return false; } case TypeBytes.AUTH_MESSAGE_TYPE_AUTHDETAILS: - return AuthMessage.canParseAuthDetailsMessage(byteStream); + return AuthMessage.canParseAuthDetailsMessage(byteBuffer); case TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS: - if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS_SIZE){ return true; } else { return false; } case TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE: - if(byteStream.size() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE_SIZE){ return true; } else { return false; @@ -73,9 +73,9 @@ public class AuthMessage extends NetworkMessage { return false; } - public static AuthMessage parseAuthRequestMessage(List byteStream){ + public static AuthMessage parseAuthRequestMessage(CircularByteBuffer byteBuffer){ AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHREQUEST); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -85,17 +85,17 @@ public class AuthMessage extends NetworkMessage { return rVal; } - public static boolean canParseAuthDetailsMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseAuthDetailsMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int userSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); userSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + userSize){ @@ -105,10 +105,10 @@ public class AuthMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + userSize + 0)); - temporaryByteQueue.add(byteStream.get(6 + userSize + 1)); - temporaryByteQueue.add(byteStream.get(6 + userSize + 2)); - temporaryByteQueue.add(byteStream.get(6 + userSize + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + userSize + 3)); passSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + userSize + passSize){ @@ -117,11 +117,11 @@ public class AuthMessage extends NetworkMessage { return true; } - public static AuthMessage parseAuthDetailsMessage(List byteStream){ + public static AuthMessage parseAuthDetailsMessage(CircularByteBuffer byteBuffer){ AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHDETAILS); - stripPacketHeader(byteStream); - rVal.setuser(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setpass(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setuser(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setpass(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -133,9 +133,9 @@ public class AuthMessage extends NetworkMessage { return rVal; } - public static AuthMessage parseAuthSuccessMessage(List byteStream){ + public static AuthMessage parseAuthSuccessMessage(CircularByteBuffer byteBuffer){ AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHSUCCESS); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -145,9 +145,9 @@ public class AuthMessage extends NetworkMessage { return rVal; } - public static AuthMessage parseAuthFailureMessage(List byteStream){ + public static AuthMessage parseAuthFailureMessage(CircularByteBuffer byteBuffer){ AuthMessage rVal = new AuthMessage(AuthMessageType.AUTHFAILURE); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/CharacterMessage.java b/src/main/java/electrosphere/net/parser/net/message/CharacterMessage.java index 71c2c161..63865fc3 100644 --- a/src/main/java/electrosphere/net/parser/net/message/CharacterMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/CharacterMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -36,50 +37,49 @@ public class CharacterMessage extends NetworkMessage { this.data = data; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST: - if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST_SIZE){ return true; } else { return false; } case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECHARACTERLIST: - return CharacterMessage.canParseResponseCharacterListMessage(byteStream); + return CharacterMessage.canParseResponseCharacterListMessage(byteBuffer); case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCREATECHARACTER: - return CharacterMessage.canParseRequestCreateCharacterMessage(byteStream); + return CharacterMessage.canParseRequestCreateCharacterMessage(byteBuffer); case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS: - if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS_SIZE){ return true; } else { return false; } case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE: - if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE_SIZE){ return true; } else { return false; } case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER: - if(byteStream.size() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER_SIZE){ return true; } else { return false; } case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSESPAWNCHARACTER: - return CharacterMessage.canParseResponseSpawnCharacterMessage(byteStream); + return CharacterMessage.canParseResponseSpawnCharacterMessage(byteBuffer); } return false; } - public static CharacterMessage parseRequestCharacterListMessage(List byteStream){ + public static CharacterMessage parseRequestCharacterListMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTCHARACTERLIST); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -89,17 +89,17 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static boolean canParseResponseCharacterListMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseResponseCharacterListMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -108,10 +108,10 @@ public class CharacterMessage extends NetworkMessage { return true; } - public static CharacterMessage parseResponseCharacterListMessage(List byteStream){ + public static CharacterMessage parseResponseCharacterListMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECHARACTERLIST); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -122,17 +122,17 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static boolean canParseRequestCreateCharacterMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseRequestCreateCharacterMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -141,10 +141,10 @@ public class CharacterMessage extends NetworkMessage { return true; } - public static CharacterMessage parseRequestCreateCharacterMessage(List byteStream){ + public static CharacterMessage parseRequestCreateCharacterMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTCREATECHARACTER); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -155,9 +155,9 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static CharacterMessage parseResponseCreateCharacterSuccessMessage(List byteStream){ + public static CharacterMessage parseResponseCreateCharacterSuccessMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECREATECHARACTERSUCCESS); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -167,9 +167,9 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static CharacterMessage parseResponseCreateCharacterFailureMessage(List byteStream){ + public static CharacterMessage parseResponseCreateCharacterFailureMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSECREATECHARACTERFAILURE); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -179,9 +179,9 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static CharacterMessage parseRequestSpawnCharacterMessage(List byteStream){ + public static CharacterMessage parseRequestSpawnCharacterMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.REQUESTSPAWNCHARACTER); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -191,17 +191,17 @@ public class CharacterMessage extends NetworkMessage { return rVal; } - public static boolean canParseResponseSpawnCharacterMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseResponseSpawnCharacterMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -210,10 +210,10 @@ public class CharacterMessage extends NetworkMessage { return true; } - public static CharacterMessage parseResponseSpawnCharacterMessage(List byteStream){ + public static CharacterMessage parseResponseSpawnCharacterMessage(CircularByteBuffer byteBuffer){ CharacterMessage rVal = new CharacterMessage(CharacterMessageType.RESPONSESPAWNCHARACTER); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java b/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java index 75cc4bf8..16108270 100644 --- a/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -272,107 +273,106 @@ public class EntityMessage extends NetworkMessage { this.propertyValueString = propertyValueString; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE: - return EntityMessage.canParseCreateMessage(byteStream); + return EntityMessage.canParseCreateMessage(byteBuffer); case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNCREATURE: - return EntityMessage.canParseSpawnCreatureMessage(byteStream); + return EntityMessage.canParseSpawnCreatureMessage(byteBuffer); case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM: - return EntityMessage.canParseSpawnItemMessage(byteStream); + return EntityMessage.canParseSpawnItemMessage(byteBuffer); case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVE_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_KILL: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING: - return EntityMessage.canParsesetBTreePropertyStringMessage(byteStream); + return EntityMessage.canParsesetBTreePropertyStringMessage(byteBuffer); case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM: - if(byteStream.size() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE){ return true; } else { return false; } case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY: - return EntityMessage.canParseattachEntityToEntityMessage(byteStream); + return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer); } return false; } - public static boolean canParseCreateMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseCreateMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -384,10 +384,10 @@ public class EntityMessage extends NetworkMessage { if(currentStreamLength < 14){ return false; } else { - temporaryByteQueue.add(byteStream.get(10 + 0)); - temporaryByteQueue.add(byteStream.get(10 + 1)); - temporaryByteQueue.add(byteStream.get(10 + 2)); - temporaryByteQueue.add(byteStream.get(10 + 3)); + temporaryByteQueue.add(byteBuffer.peek(10 + 0)); + temporaryByteQueue.add(byteBuffer.peek(10 + 1)); + temporaryByteQueue.add(byteBuffer.peek(10 + 2)); + temporaryByteQueue.add(byteBuffer.peek(10 + 3)); entitySubtypeSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 14 + entitySubtypeSize){ @@ -405,15 +405,15 @@ public class EntityMessage extends NetworkMessage { return true; } - public static EntityMessage parseCreateMessage(List byteStream){ + public static EntityMessage parseCreateMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.CREATE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setentitySubtype(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setentityCategory(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setentitySubtype(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -429,8 +429,8 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static boolean canParseSpawnCreatureMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseSpawnCreatureMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -439,10 +439,10 @@ public class EntityMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); creatureTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + creatureTemplateSize){ @@ -460,14 +460,14 @@ public class EntityMessage extends NetworkMessage { return true; } - public static EntityMessage parseSpawnCreatureMessage(List byteStream){ + public static EntityMessage parseSpawnCreatureMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNCREATURE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -482,8 +482,8 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static boolean canParseSpawnItemMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseSpawnItemMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -492,10 +492,10 @@ public class EntityMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); creatureTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + creatureTemplateSize){ @@ -513,14 +513,14 @@ public class EntityMessage extends NetworkMessage { return true; } - public static EntityMessage parseSpawnItemMessage(List byteStream){ + public static EntityMessage parseSpawnItemMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SPAWNITEM); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setcreatureTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -535,14 +535,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseSetPositionMessage(List byteStream){ + public static EntityMessage parseSetPositionMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETPOSITION); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -557,14 +557,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetFacingMessage(List byteStream){ + public static EntityMessage parsesetFacingMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETFACING); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -579,20 +579,20 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsemoveUpdateMessage(List byteStream){ + public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -613,19 +613,19 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseattackUpdateMessage(List byteStream){ + public static EntityMessage parseattackUpdateMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACKUPDATE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -645,14 +645,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseMoveMessage(List byteStream){ + public static EntityMessage parseMoveMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.MOVE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -667,11 +667,11 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseKillMessage(List byteStream){ + public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.KILL); - stripPacketHeader(byteStream); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -683,10 +683,10 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseDestroyMessage(List byteStream){ + public static EntityMessage parseDestroyMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.DESTROY); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -697,13 +697,13 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parseSetBehaviorTreeMessage(List byteStream){ + public static EntityMessage parseSetBehaviorTreeMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBEHAVIORTREE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.settreeType(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settreeStatus(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.settreeType(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settreeStatus(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -717,13 +717,13 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetPropertyMessage(List byteStream){ + public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETPROPERTY); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setpropertyType(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValue(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setpropertyType(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValue(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -737,14 +737,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetBTreePropertyIntMessage(List byteStream){ + public static EntityMessage parsesetBTreePropertyIntMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYINT); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -759,14 +759,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetBTreePropertyFloatMessage(List byteStream){ + public static EntityMessage parsesetBTreePropertyFloatMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYFLOAT); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValueFloat(ByteStreamUtils.popFloatFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValueFloat(ByteStreamUtils.popFloatFromByteQueue(byteBuffer)); return rVal; } @@ -781,14 +781,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetBTreePropertyDoubleMessage(List byteStream){ + public static EntityMessage parsesetBTreePropertyDoubleMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYDOUBLE); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValueDouble(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValueDouble(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -803,8 +803,8 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static boolean canParsesetBTreePropertyStringMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -822,10 +822,10 @@ public class EntityMessage extends NetworkMessage { if(currentStreamLength < 26){ return false; } else { - temporaryByteQueue.add(byteStream.get(22 + 0)); - temporaryByteQueue.add(byteStream.get(22 + 1)); - temporaryByteQueue.add(byteStream.get(22 + 2)); - temporaryByteQueue.add(byteStream.get(22 + 3)); + temporaryByteQueue.add(byteBuffer.peek(22 + 0)); + temporaryByteQueue.add(byteBuffer.peek(22 + 1)); + temporaryByteQueue.add(byteBuffer.peek(22 + 2)); + temporaryByteQueue.add(byteBuffer.peek(22 + 3)); propertyValueStringSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 26 + propertyValueStringSize){ @@ -834,14 +834,14 @@ public class EntityMessage extends NetworkMessage { return true; } - public static EntityMessage parsesetBTreePropertyStringMessage(List byteStream){ + public static EntityMessage parsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYSTRING); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValueString(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValueString(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -856,14 +856,14 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static EntityMessage parsesetBTreePropertyEnumMessage(List byteStream){ + public static EntityMessage parsesetBTreePropertyEnumMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYENUM); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); + rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -878,8 +878,8 @@ public class EntityMessage extends NetworkMessage { return rVal; } - public static boolean canParseattachEntityToEntityMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -888,10 +888,10 @@ public class EntityMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); boneSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + boneSize){ @@ -903,12 +903,12 @@ public class EntityMessage extends NetworkMessage { return true; } - public static EntityMessage parseattachEntityToEntityMessage(List byteStream){ + public static EntityMessage parseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){ EntityMessage rVal = new EntityMessage(EntityMessageType.ATTACHENTITYTOENTITY); - stripPacketHeader(byteStream); - rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.settargetID(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setbone(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.settargetID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/InventoryMessage.java b/src/main/java/electrosphere/net/parser/net/message/InventoryMessage.java index 2ca08e60..9f2e9d69 100644 --- a/src/main/java/electrosphere/net/parser/net/message/InventoryMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/InventoryMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -72,37 +73,36 @@ public class InventoryMessage extends NetworkMessage { this.containerType = containerType; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.INVENTORY_MESSAGE_TYPE_ADDITEMTOINVENTORY: - return InventoryMessage.canParseaddItemToInventoryMessage(byteStream); + return InventoryMessage.canParseaddItemToInventoryMessage(byteBuffer); case TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY: - if(byteStream.size() >= TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE){ return true; } else { return false; } case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTEQUIPITEM: - return InventoryMessage.canParseclientRequestEquipItemMessage(byteStream); + return InventoryMessage.canParseclientRequestEquipItemMessage(byteBuffer); case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDMOVEITEMCONTAINER: - return InventoryMessage.canParseserverCommandMoveItemContainerMessage(byteStream); + return InventoryMessage.canParseserverCommandMoveItemContainerMessage(byteBuffer); case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM: - return InventoryMessage.canParseserverCommandEquipItemMessage(byteStream); + return InventoryMessage.canParseserverCommandEquipItemMessage(byteBuffer); case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM: - return InventoryMessage.canParseserverCommandUnequipItemMessage(byteStream); + return InventoryMessage.canParseserverCommandUnequipItemMessage(byteBuffer); case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM: - return InventoryMessage.canParseclientRequestUnequipItemMessage(byteStream); + return InventoryMessage.canParseclientRequestUnequipItemMessage(byteBuffer); } return false; } - public static boolean canParseaddItemToInventoryMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseaddItemToInventoryMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -111,10 +111,10 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + itemTemplateSize){ @@ -123,11 +123,11 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseaddItemToInventoryMessage(List byteStream){ + public static InventoryMessage parseaddItemToInventoryMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.ADDITEMTOINVENTORY); - stripPacketHeader(byteStream); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -139,10 +139,10 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static InventoryMessage parseremoveItemFromInventoryMessage(List byteStream){ + public static InventoryMessage parseremoveItemFromInventoryMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.REMOVEITEMFROMINVENTORY); - stripPacketHeader(byteStream); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -153,17 +153,17 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static boolean canParseclientRequestEquipItemMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseclientRequestEquipItemMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int equipPointIdSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + equipPointIdSize){ @@ -175,11 +175,11 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseclientRequestEquipItemMessage(List byteStream){ + public static InventoryMessage parseclientRequestEquipItemMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTEQUIPITEM); - stripPacketHeader(byteStream); - rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -191,8 +191,8 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static boolean canParseserverCommandMoveItemContainerMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseserverCommandMoveItemContainerMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -204,10 +204,10 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 14){ return false; } else { - temporaryByteQueue.add(byteStream.get(10 + 0)); - temporaryByteQueue.add(byteStream.get(10 + 1)); - temporaryByteQueue.add(byteStream.get(10 + 2)); - temporaryByteQueue.add(byteStream.get(10 + 3)); + temporaryByteQueue.add(byteBuffer.peek(10 + 0)); + temporaryByteQueue.add(byteBuffer.peek(10 + 1)); + temporaryByteQueue.add(byteBuffer.peek(10 + 2)); + temporaryByteQueue.add(byteBuffer.peek(10 + 3)); equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 14 + equipPointIdSize){ @@ -216,12 +216,12 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseserverCommandMoveItemContainerMessage(List byteStream){ + public static InventoryMessage parseserverCommandMoveItemContainerMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDMOVEITEMCONTAINER); - stripPacketHeader(byteStream); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -234,8 +234,8 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static boolean canParseserverCommandEquipItemMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseserverCommandEquipItemMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -244,10 +244,10 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + equipPointIdSize){ @@ -260,10 +260,10 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 18){ return false; } else { - temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 0)); - temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 1)); - temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 2)); - temporaryByteQueue.add(byteStream.get(14 + equipPointIdSize + 3)); + temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 0)); + temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 1)); + temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 2)); + temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 3)); itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 18 + equipPointIdSize + itemTemplateSize){ @@ -272,13 +272,13 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseserverCommandEquipItemMessage(List byteStream){ + public static InventoryMessage parseserverCommandEquipItemMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDEQUIPITEM); - stripPacketHeader(byteStream); - rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream)); - rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); + rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -292,8 +292,8 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static boolean canParseserverCommandUnequipItemMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseserverCommandUnequipItemMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -302,10 +302,10 @@ public class InventoryMessage extends NetworkMessage { if(currentStreamLength < 10){ return false; } else { - temporaryByteQueue.add(byteStream.get(6 + 0)); - temporaryByteQueue.add(byteStream.get(6 + 1)); - temporaryByteQueue.add(byteStream.get(6 + 2)); - temporaryByteQueue.add(byteStream.get(6 + 3)); + temporaryByteQueue.add(byteBuffer.peek(6 + 0)); + temporaryByteQueue.add(byteBuffer.peek(6 + 1)); + temporaryByteQueue.add(byteBuffer.peek(6 + 2)); + temporaryByteQueue.add(byteBuffer.peek(6 + 3)); equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 10 + equipPointIdSize){ @@ -314,11 +314,11 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseserverCommandUnequipItemMessage(List byteStream){ + public static InventoryMessage parseserverCommandUnequipItemMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDUNEQUIPITEM); - stripPacketHeader(byteStream); - rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -330,17 +330,17 @@ public class InventoryMessage extends NetworkMessage { return rVal; } - public static boolean canParseclientRequestUnequipItemMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseclientRequestUnequipItemMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int equipPointIdSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + equipPointIdSize){ @@ -349,10 +349,10 @@ public class InventoryMessage extends NetworkMessage { return true; } - public static InventoryMessage parseclientRequestUnequipItemMessage(List byteStream){ + public static InventoryMessage parseclientRequestUnequipItemMessage(CircularByteBuffer byteBuffer){ InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTUNEQUIPITEM); - stripPacketHeader(byteStream); - rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/LoreMessage.java b/src/main/java/electrosphere/net/parser/net/message/LoreMessage.java index b8320d90..b8f27efb 100644 --- a/src/main/java/electrosphere/net/parser/net/message/LoreMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/LoreMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -35,40 +36,39 @@ public class LoreMessage extends NetworkMessage { this.data = data; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES: - if(byteStream.size() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES_SIZE){ return true; } else { return false; } case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES: - return LoreMessage.canParseResponseRacesMessage(byteStream); + return LoreMessage.canParseResponseRacesMessage(byteBuffer); case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA: - if(byteStream.size() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA_SIZE){ return true; } else { return false; } case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA: - return LoreMessage.canParseResponseRaceDataMessage(byteStream); + return LoreMessage.canParseResponseRaceDataMessage(byteBuffer); case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA: - return LoreMessage.canParseRequestDataMessage(byteStream); + return LoreMessage.canParseRequestDataMessage(byteBuffer); case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA: - return LoreMessage.canParseResponseDataMessage(byteStream); + return LoreMessage.canParseResponseDataMessage(byteBuffer); } return false; } - public static LoreMessage parseRequestRacesMessage(List byteStream){ + public static LoreMessage parseRequestRacesMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACES); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -78,17 +78,17 @@ public class LoreMessage extends NetworkMessage { return rVal; } - public static boolean canParseResponseRacesMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseResponseRacesMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -97,10 +97,10 @@ public class LoreMessage extends NetworkMessage { return true; } - public static LoreMessage parseResponseRacesMessage(List byteStream){ + public static LoreMessage parseResponseRacesMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACES); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -111,9 +111,9 @@ public class LoreMessage extends NetworkMessage { return rVal; } - public static LoreMessage parseRequestRaceDataMessage(List byteStream){ + public static LoreMessage parseRequestRaceDataMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACEDATA); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -123,17 +123,17 @@ public class LoreMessage extends NetworkMessage { return rVal; } - public static boolean canParseResponseRaceDataMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseResponseRaceDataMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -142,10 +142,10 @@ public class LoreMessage extends NetworkMessage { return true; } - public static LoreMessage parseResponseRaceDataMessage(List byteStream){ + public static LoreMessage parseResponseRaceDataMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACEDATA); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -156,17 +156,17 @@ public class LoreMessage extends NetworkMessage { return rVal; } - public static boolean canParseRequestDataMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseRequestDataMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -175,10 +175,10 @@ public class LoreMessage extends NetworkMessage { return true; } - public static LoreMessage parseRequestDataMessage(List byteStream){ + public static LoreMessage parseRequestDataMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTDATA); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } @@ -189,17 +189,17 @@ public class LoreMessage extends NetworkMessage { return rVal; } - public static boolean canParseResponseDataMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParseResponseDataMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); int dataSize = 0; if(currentStreamLength < 6){ return false; } else { - temporaryByteQueue.add(byteStream.get(2 + 0)); - temporaryByteQueue.add(byteStream.get(2 + 1)); - temporaryByteQueue.add(byteStream.get(2 + 2)); - temporaryByteQueue.add(byteStream.get(2 + 3)); + temporaryByteQueue.add(byteBuffer.peek(2 + 0)); + temporaryByteQueue.add(byteBuffer.peek(2 + 1)); + temporaryByteQueue.add(byteBuffer.peek(2 + 2)); + temporaryByteQueue.add(byteBuffer.peek(2 + 3)); dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 6 + dataSize){ @@ -208,10 +208,10 @@ public class LoreMessage extends NetworkMessage { return true; } - public static LoreMessage parseResponseDataMessage(List byteStream){ + public static LoreMessage parseResponseDataMessage(CircularByteBuffer byteBuffer){ LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSEDATA); - stripPacketHeader(byteStream); - rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer)); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java index 19478b05..7eef63ee 100644 --- a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java @@ -1,6 +1,8 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; + import java.util.List; public abstract class NetworkMessage { @@ -28,329 +30,314 @@ INVENTORY_MESSAGE, return rawBytes; } - public static NetworkMessage parseBytestreamForMessage(List byteStream){ + public static NetworkMessage parseBytestreamForMessage(CircularByteBuffer byteBuffer){ NetworkMessage rVal = null; byte firstByte; byte secondByte; - if(byteStream.size() > 1){ - firstByte = byteStream.get(0); + if(byteBuffer.getRemaining() > 1){ + firstByte = byteBuffer.peek(); switch(firstByte){ case TypeBytes.MESSAGE_TYPE_ENTITY: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.ENTITY_MESSAGE_TYPE_CREATE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseCreateMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseCreateMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNCREATURE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseSpawnCreatureMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseSpawnCreatureMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseSpawnItemMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseSpawnItemMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseSetPositionMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseSetPositionMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetFacingMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetFacingMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsemoveUpdateMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACKUPDATE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseattackUpdateMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseattackUpdateMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseMoveMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseMoveMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_KILL: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseKillMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseKillMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_DESTROY: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseDestroyMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseDestroyMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseSetBehaviorTreeMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseSetBehaviorTreeMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetPropertyMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetPropertyMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetBTreePropertyIntMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetBTreePropertyIntMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetBTreePropertyFloatMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetBTreePropertyFloatMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetBTreePropertyDoubleMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetBTreePropertyDoubleMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetBTreePropertyStringMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetBTreePropertyStringMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parsesetBTreePropertyEnumMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parsesetBTreePropertyEnumMessage(byteBuffer); } break; case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY: - if(EntityMessage.canParseMessage(byteStream,secondByte)){ - rVal = EntityMessage.parseattachEntityToEntityMessage(byteStream); + if(EntityMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_LORE: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACES: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseRequestRacesMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseRequestRacesMessage(byteBuffer); } break; case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseResponseRacesMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseResponseRacesMessage(byteBuffer); } break; case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseRequestRaceDataMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseRequestRaceDataMessage(byteBuffer); } break; case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseResponseRaceDataMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseResponseRaceDataMessage(byteBuffer); } break; case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseRequestDataMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseRequestDataMessage(byteBuffer); } break; case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA: - if(LoreMessage.canParseMessage(byteStream,secondByte)){ - rVal = LoreMessage.parseResponseDataMessage(byteStream); + if(LoreMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = LoreMessage.parseResponseDataMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_PLAYER: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID: - if(PlayerMessage.canParseMessage(byteStream,secondByte)){ - rVal = PlayerMessage.parseSet_IDMessage(byteStream); + if(PlayerMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = PlayerMessage.parseSet_IDMessage(byteBuffer); } break; case TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION: - if(PlayerMessage.canParseMessage(byteStream,secondByte)){ - rVal = PlayerMessage.parseSetInitialDiscretePositionMessage(byteStream); + if(PlayerMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = PlayerMessage.parseSetInitialDiscretePositionMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_TERRAIN: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseRequestMetadataMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseRequestMetadataMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseResponseMetadataMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseRequestChunkMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseRequestChunkMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseUpdateMessage(byteStream); - } - break; - case TypeBytes.TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parsechunkLoadStartMessage(byteStream); - } - break; - case TypeBytes.TERRAIN_MESSAGE_TYPE_MACROVALUE: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseMacroValueMessage(byteStream); - } - break; - case TypeBytes.TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseheightMapModificationMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseUpdateMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseSpawnPositionMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseSpawnPositionMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parseRequestChunkDataMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseRequestChunkDataMessage(byteBuffer); } break; case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA: - if(TerrainMessage.canParseMessage(byteStream,secondByte)){ - rVal = TerrainMessage.parsesendChunkDataMessage(byteStream); + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_SERVER: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.SERVER_MESSAGE_TYPE_PING: - if(ServerMessage.canParseMessage(byteStream,secondByte)){ - rVal = ServerMessage.parsePingMessage(byteStream); + if(ServerMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = ServerMessage.parsePingMessage(byteBuffer); } break; case TypeBytes.SERVER_MESSAGE_TYPE_PONG: - if(ServerMessage.canParseMessage(byteStream,secondByte)){ - rVal = ServerMessage.parsePongMessage(byteStream); + if(ServerMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = ServerMessage.parsePongMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_AUTH: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.AUTH_MESSAGE_TYPE_AUTHREQUEST: - if(AuthMessage.canParseMessage(byteStream,secondByte)){ - rVal = AuthMessage.parseAuthRequestMessage(byteStream); + if(AuthMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = AuthMessage.parseAuthRequestMessage(byteBuffer); } break; case TypeBytes.AUTH_MESSAGE_TYPE_AUTHDETAILS: - if(AuthMessage.canParseMessage(byteStream,secondByte)){ - rVal = AuthMessage.parseAuthDetailsMessage(byteStream); + if(AuthMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = AuthMessage.parseAuthDetailsMessage(byteBuffer); } break; case TypeBytes.AUTH_MESSAGE_TYPE_AUTHSUCCESS: - if(AuthMessage.canParseMessage(byteStream,secondByte)){ - rVal = AuthMessage.parseAuthSuccessMessage(byteStream); + if(AuthMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = AuthMessage.parseAuthSuccessMessage(byteBuffer); } break; case TypeBytes.AUTH_MESSAGE_TYPE_AUTHFAILURE: - if(AuthMessage.canParseMessage(byteStream,secondByte)){ - rVal = AuthMessage.parseAuthFailureMessage(byteStream); + if(AuthMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = AuthMessage.parseAuthFailureMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_CHARACTER: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCHARACTERLIST: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseRequestCharacterListMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseRequestCharacterListMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECHARACTERLIST: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseResponseCharacterListMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseResponseCharacterListMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTCREATECHARACTER: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseRequestCreateCharacterMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseRequestCreateCharacterMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERSUCCESS: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseResponseCreateCharacterSuccessMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseResponseCreateCharacterSuccessMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSECREATECHARACTERFAILURE: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseResponseCreateCharacterFailureMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseResponseCreateCharacterFailureMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_REQUESTSPAWNCHARACTER: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseRequestSpawnCharacterMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseRequestSpawnCharacterMessage(byteBuffer); } break; case TypeBytes.CHARACTER_MESSAGE_TYPE_RESPONSESPAWNCHARACTER: - if(CharacterMessage.canParseMessage(byteStream,secondByte)){ - rVal = CharacterMessage.parseResponseSpawnCharacterMessage(byteStream); + if(CharacterMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = CharacterMessage.parseResponseSpawnCharacterMessage(byteBuffer); } break; } break; case TypeBytes.MESSAGE_TYPE_INVENTORY: - secondByte = byteStream.get(1); + secondByte = byteBuffer.peek(1); switch(secondByte){ case TypeBytes.INVENTORY_MESSAGE_TYPE_ADDITEMTOINVENTORY: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseaddItemToInventoryMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseaddItemToInventoryMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseremoveItemFromInventoryMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseremoveItemFromInventoryMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTEQUIPITEM: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseclientRequestEquipItemMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseclientRequestEquipItemMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDMOVEITEMCONTAINER: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseserverCommandMoveItemContainerMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseserverCommandMoveItemContainerMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseserverCommandEquipItemMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseserverCommandEquipItemMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseserverCommandUnequipItemMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseserverCommandUnequipItemMessage(byteBuffer); } break; case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM: - if(InventoryMessage.canParseMessage(byteStream,secondByte)){ - rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteStream); + if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteBuffer); } break; } diff --git a/src/main/java/electrosphere/net/parser/net/message/PlayerMessage.java b/src/main/java/electrosphere/net/parser/net/message/PlayerMessage.java index 60494bff..f2b9f931 100644 --- a/src/main/java/electrosphere/net/parser/net/message/PlayerMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/PlayerMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -58,21 +59,20 @@ public class PlayerMessage extends NetworkMessage { this.initialDiscretePositionZ = initialDiscretePositionZ; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID: - if(byteStream.size() >= TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SET_ID_SIZE){ return true; } else { return false; } case TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION: - if(byteStream.size() >= TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.PLAYER_MESSAGE_TYPE_SETINITIALDISCRETEPOSITION_SIZE){ return true; } else { return false; @@ -81,10 +81,10 @@ public class PlayerMessage extends NetworkMessage { return false; } - public static PlayerMessage parseSet_IDMessage(List byteStream){ + public static PlayerMessage parseSet_IDMessage(CircularByteBuffer byteBuffer){ PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SET_ID); - stripPacketHeader(byteStream); - rVal.setplayerID(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setplayerID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -95,12 +95,12 @@ public class PlayerMessage extends NetworkMessage { return rVal; } - public static PlayerMessage parseSetInitialDiscretePositionMessage(List byteStream){ + public static PlayerMessage parseSetInitialDiscretePositionMessage(CircularByteBuffer byteBuffer){ PlayerMessage rVal = new PlayerMessage(PlayerMessageType.SETINITIALDISCRETEPOSITION); - stripPacketHeader(byteStream); - rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setinitialDiscretePositionX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setinitialDiscretePositionY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setinitialDiscretePositionZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/ServerMessage.java b/src/main/java/electrosphere/net/parser/net/message/ServerMessage.java index f382cf1a..e5684902 100644 --- a/src/main/java/electrosphere/net/parser/net/message/ServerMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/ServerMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -22,21 +23,20 @@ public class ServerMessage extends NetworkMessage { return this.messageType; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.SERVER_MESSAGE_TYPE_PING: - if(byteStream.size() >= TypeBytes.SERVER_MESSAGE_TYPE_PING_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.SERVER_MESSAGE_TYPE_PING_SIZE){ return true; } else { return false; } case TypeBytes.SERVER_MESSAGE_TYPE_PONG: - if(byteStream.size() >= TypeBytes.SERVER_MESSAGE_TYPE_PONG_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.SERVER_MESSAGE_TYPE_PONG_SIZE){ return true; } else { return false; @@ -45,9 +45,9 @@ public class ServerMessage extends NetworkMessage { return false; } - public static ServerMessage parsePingMessage(List byteStream){ + public static ServerMessage parsePingMessage(CircularByteBuffer byteBuffer){ ServerMessage rVal = new ServerMessage(ServerMessageType.PING); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -57,9 +57,9 @@ public class ServerMessage extends NetworkMessage { return rVal; } - public static ServerMessage parsePongMessage(List byteStream){ + public static ServerMessage parsePongMessage(CircularByteBuffer byteBuffer){ ServerMessage rVal = new ServerMessage(ServerMessageType.PONG); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } diff --git a/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java b/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java index e5e1b67e..2bf20e9c 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java @@ -1,6 +1,7 @@ package electrosphere.net.parser.net.message; import electrosphere.net.parser.util.ByteStreamUtils; +import electrosphere.net.parser.net.raw.CircularByteBuffer; import java.util.LinkedList; import java.util.List; @@ -11,9 +12,6 @@ public class TerrainMessage extends NetworkMessage { RESPONSEMETADATA, REQUESTCHUNK, UPDATE, - CHUNKLOADSTART, - MACROVALUE, - HEIGHTMAPMODIFICATION, SPAWNPOSITION, REQUESTCHUNKDATA, SENDCHUNKDATA, @@ -27,67 +25,16 @@ public class TerrainMessage extends NetworkMessage { int worldMinY; int worldMaxX; int worldMaxY; + float value; int worldX; int worldY; int worldZ; - float value; - int locationX; - int locationY; - int locationZ; double realLocationX; double realLocationY; double realLocationZ; - float macroValue00; - float macroValue01; - float macroValue02; - float macroValue03; - float macroValue04; - float macroValue10; - float macroValue11; - float macroValue12; - float macroValue13; - float macroValue14; - float macroValue20; - float macroValue21; - float macroValue22; - float macroValue23; - float macroValue24; - float macroValue30; - float macroValue31; - float macroValue32; - float macroValue33; - float macroValue34; - float macroValue40; - float macroValue41; - float macroValue42; - float macroValue43; - float macroValue44; - long randomizerValue00; - long randomizerValue01; - long randomizerValue02; - long randomizerValue03; - long randomizerValue04; - long randomizerValue10; - long randomizerValue11; - long randomizerValue12; - long randomizerValue13; - long randomizerValue14; - long randomizerValue20; - long randomizerValue21; - long randomizerValue22; - long randomizerValue23; - long randomizerValue24; - long randomizerValue30; - long randomizerValue31; - long randomizerValue32; - long randomizerValue33; - long randomizerValue34; - long randomizerValue40; - long randomizerValue41; - long randomizerValue42; - long randomizerValue43; - long randomizerValue44; byte[] chunkData; + float terrainWeight; + int terrainValue; TerrainMessage(TerrainMessageType messageType){ this.type = MessageType.TERRAIN_MESSAGE; @@ -154,6 +101,14 @@ public class TerrainMessage extends NetworkMessage { this.worldMaxY = worldMaxY; } + public float getvalue() { + return value; + } + + public void setvalue(float value) { + this.value = value; + } + public int getworldX() { return worldX; } @@ -178,38 +133,6 @@ public class TerrainMessage extends NetworkMessage { this.worldZ = worldZ; } - public float getvalue() { - return value; - } - - public void setvalue(float value) { - this.value = value; - } - - public int getlocationX() { - return locationX; - } - - public void setlocationX(int locationX) { - this.locationX = locationX; - } - - public int getlocationY() { - return locationY; - } - - public void setlocationY(int locationY) { - this.locationY = locationY; - } - - public int getlocationZ() { - return locationZ; - } - - public void setlocationZ(int locationZ) { - this.locationZ = locationZ; - } - public double getrealLocationX() { return realLocationX; } @@ -234,406 +157,6 @@ public class TerrainMessage extends NetworkMessage { this.realLocationZ = realLocationZ; } - public float getmacroValue00() { - return macroValue00; - } - - public void setmacroValue00(float macroValue00) { - this.macroValue00 = macroValue00; - } - - public float getmacroValue01() { - return macroValue01; - } - - public void setmacroValue01(float macroValue01) { - this.macroValue01 = macroValue01; - } - - public float getmacroValue02() { - return macroValue02; - } - - public void setmacroValue02(float macroValue02) { - this.macroValue02 = macroValue02; - } - - public float getmacroValue03() { - return macroValue03; - } - - public void setmacroValue03(float macroValue03) { - this.macroValue03 = macroValue03; - } - - public float getmacroValue04() { - return macroValue04; - } - - public void setmacroValue04(float macroValue04) { - this.macroValue04 = macroValue04; - } - - public float getmacroValue10() { - return macroValue10; - } - - public void setmacroValue10(float macroValue10) { - this.macroValue10 = macroValue10; - } - - public float getmacroValue11() { - return macroValue11; - } - - public void setmacroValue11(float macroValue11) { - this.macroValue11 = macroValue11; - } - - public float getmacroValue12() { - return macroValue12; - } - - public void setmacroValue12(float macroValue12) { - this.macroValue12 = macroValue12; - } - - public float getmacroValue13() { - return macroValue13; - } - - public void setmacroValue13(float macroValue13) { - this.macroValue13 = macroValue13; - } - - public float getmacroValue14() { - return macroValue14; - } - - public void setmacroValue14(float macroValue14) { - this.macroValue14 = macroValue14; - } - - public float getmacroValue20() { - return macroValue20; - } - - public void setmacroValue20(float macroValue20) { - this.macroValue20 = macroValue20; - } - - public float getmacroValue21() { - return macroValue21; - } - - public void setmacroValue21(float macroValue21) { - this.macroValue21 = macroValue21; - } - - public float getmacroValue22() { - return macroValue22; - } - - public void setmacroValue22(float macroValue22) { - this.macroValue22 = macroValue22; - } - - public float getmacroValue23() { - return macroValue23; - } - - public void setmacroValue23(float macroValue23) { - this.macroValue23 = macroValue23; - } - - public float getmacroValue24() { - return macroValue24; - } - - public void setmacroValue24(float macroValue24) { - this.macroValue24 = macroValue24; - } - - public float getmacroValue30() { - return macroValue30; - } - - public void setmacroValue30(float macroValue30) { - this.macroValue30 = macroValue30; - } - - public float getmacroValue31() { - return macroValue31; - } - - public void setmacroValue31(float macroValue31) { - this.macroValue31 = macroValue31; - } - - public float getmacroValue32() { - return macroValue32; - } - - public void setmacroValue32(float macroValue32) { - this.macroValue32 = macroValue32; - } - - public float getmacroValue33() { - return macroValue33; - } - - public void setmacroValue33(float macroValue33) { - this.macroValue33 = macroValue33; - } - - public float getmacroValue34() { - return macroValue34; - } - - public void setmacroValue34(float macroValue34) { - this.macroValue34 = macroValue34; - } - - public float getmacroValue40() { - return macroValue40; - } - - public void setmacroValue40(float macroValue40) { - this.macroValue40 = macroValue40; - } - - public float getmacroValue41() { - return macroValue41; - } - - public void setmacroValue41(float macroValue41) { - this.macroValue41 = macroValue41; - } - - public float getmacroValue42() { - return macroValue42; - } - - public void setmacroValue42(float macroValue42) { - this.macroValue42 = macroValue42; - } - - public float getmacroValue43() { - return macroValue43; - } - - public void setmacroValue43(float macroValue43) { - this.macroValue43 = macroValue43; - } - - public float getmacroValue44() { - return macroValue44; - } - - public void setmacroValue44(float macroValue44) { - this.macroValue44 = macroValue44; - } - - public long getrandomizerValue00() { - return randomizerValue00; - } - - public void setrandomizerValue00(long randomizerValue00) { - this.randomizerValue00 = randomizerValue00; - } - - public long getrandomizerValue01() { - return randomizerValue01; - } - - public void setrandomizerValue01(long randomizerValue01) { - this.randomizerValue01 = randomizerValue01; - } - - public long getrandomizerValue02() { - return randomizerValue02; - } - - public void setrandomizerValue02(long randomizerValue02) { - this.randomizerValue02 = randomizerValue02; - } - - public long getrandomizerValue03() { - return randomizerValue03; - } - - public void setrandomizerValue03(long randomizerValue03) { - this.randomizerValue03 = randomizerValue03; - } - - public long getrandomizerValue04() { - return randomizerValue04; - } - - public void setrandomizerValue04(long randomizerValue04) { - this.randomizerValue04 = randomizerValue04; - } - - public long getrandomizerValue10() { - return randomizerValue10; - } - - public void setrandomizerValue10(long randomizerValue10) { - this.randomizerValue10 = randomizerValue10; - } - - public long getrandomizerValue11() { - return randomizerValue11; - } - - public void setrandomizerValue11(long randomizerValue11) { - this.randomizerValue11 = randomizerValue11; - } - - public long getrandomizerValue12() { - return randomizerValue12; - } - - public void setrandomizerValue12(long randomizerValue12) { - this.randomizerValue12 = randomizerValue12; - } - - public long getrandomizerValue13() { - return randomizerValue13; - } - - public void setrandomizerValue13(long randomizerValue13) { - this.randomizerValue13 = randomizerValue13; - } - - public long getrandomizerValue14() { - return randomizerValue14; - } - - public void setrandomizerValue14(long randomizerValue14) { - this.randomizerValue14 = randomizerValue14; - } - - public long getrandomizerValue20() { - return randomizerValue20; - } - - public void setrandomizerValue20(long randomizerValue20) { - this.randomizerValue20 = randomizerValue20; - } - - public long getrandomizerValue21() { - return randomizerValue21; - } - - public void setrandomizerValue21(long randomizerValue21) { - this.randomizerValue21 = randomizerValue21; - } - - public long getrandomizerValue22() { - return randomizerValue22; - } - - public void setrandomizerValue22(long randomizerValue22) { - this.randomizerValue22 = randomizerValue22; - } - - public long getrandomizerValue23() { - return randomizerValue23; - } - - public void setrandomizerValue23(long randomizerValue23) { - this.randomizerValue23 = randomizerValue23; - } - - public long getrandomizerValue24() { - return randomizerValue24; - } - - public void setrandomizerValue24(long randomizerValue24) { - this.randomizerValue24 = randomizerValue24; - } - - public long getrandomizerValue30() { - return randomizerValue30; - } - - public void setrandomizerValue30(long randomizerValue30) { - this.randomizerValue30 = randomizerValue30; - } - - public long getrandomizerValue31() { - return randomizerValue31; - } - - public void setrandomizerValue31(long randomizerValue31) { - this.randomizerValue31 = randomizerValue31; - } - - public long getrandomizerValue32() { - return randomizerValue32; - } - - public void setrandomizerValue32(long randomizerValue32) { - this.randomizerValue32 = randomizerValue32; - } - - public long getrandomizerValue33() { - return randomizerValue33; - } - - public void setrandomizerValue33(long randomizerValue33) { - this.randomizerValue33 = randomizerValue33; - } - - public long getrandomizerValue34() { - return randomizerValue34; - } - - public void setrandomizerValue34(long randomizerValue34) { - this.randomizerValue34 = randomizerValue34; - } - - public long getrandomizerValue40() { - return randomizerValue40; - } - - public void setrandomizerValue40(long randomizerValue40) { - this.randomizerValue40 = randomizerValue40; - } - - public long getrandomizerValue41() { - return randomizerValue41; - } - - public void setrandomizerValue41(long randomizerValue41) { - this.randomizerValue41 = randomizerValue41; - } - - public long getrandomizerValue42() { - return randomizerValue42; - } - - public void setrandomizerValue42(long randomizerValue42) { - this.randomizerValue42 = randomizerValue42; - } - - public long getrandomizerValue43() { - return randomizerValue43; - } - - public void setrandomizerValue43(long randomizerValue43) { - this.randomizerValue43 = randomizerValue43; - } - - public long getrandomizerValue44() { - return randomizerValue44; - } - - public void setrandomizerValue44(long randomizerValue44) { - this.randomizerValue44 = randomizerValue44; - } - public byte[] getchunkData() { return chunkData; } @@ -642,76 +165,73 @@ public class TerrainMessage extends NetworkMessage { this.chunkData = chunkData; } - static void stripPacketHeader(List byteStream){ - byteStream.remove(0); - byteStream.remove(0); + public float getterrainWeight() { + return terrainWeight; } - public static boolean canParseMessage(List byteStream, byte secondByte){ + public void setterrainWeight(float terrainWeight) { + this.terrainWeight = terrainWeight; + } + + public int getterrainValue() { + return terrainValue; + } + + public void setterrainValue(int terrainValue) { + this.terrainValue = terrainValue; + } + + static void stripPacketHeader(CircularByteBuffer byteBuffer){ + byteBuffer.read(2); + } + + public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){ switch(secondByte){ case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTMETADATA_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE_SIZE){ - return true; - } else { - return false; - } - case TypeBytes.TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART_SIZE){ - return true; - } else { - return false; - } - case TypeBytes.TERRAIN_MESSAGE_TYPE_MACROVALUE: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_MACROVALUE_SIZE){ - return true; - } else { - return false; - } - case TypeBytes.TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA: - if(byteStream.size() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE){ + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE){ return true; } else { return false; } case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA: - return TerrainMessage.canParsesendChunkDataMessage(byteStream); + return TerrainMessage.canParsesendChunkDataMessage(byteBuffer); } return false; } - public static TerrainMessage parseRequestMetadataMessage(List byteStream){ + public static TerrainMessage parseRequestMetadataMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTMETADATA); - stripPacketHeader(byteStream); + stripPacketHeader(byteBuffer); return rVal; } @@ -721,16 +241,16 @@ public class TerrainMessage extends NetworkMessage { return rVal; } - public static TerrainMessage parseResponseMetadataMessage(List byteStream){ + public static TerrainMessage parseResponseMetadataMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.RESPONSEMETADATA); - stripPacketHeader(byteStream); - rVal.setworldSizeDiscrete(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setdynamicInterpolationRatio(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setrandomDampener(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setworldMinX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldMinY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldMaxX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldMaxY(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setworldSizeDiscrete(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setdynamicInterpolationRatio(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setrandomDampener(ByteStreamUtils.popFloatFromByteQueue(byteBuffer)); + rVal.setworldMinX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldMinY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldMaxX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldMaxY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -747,11 +267,11 @@ public class TerrainMessage extends NetworkMessage { return rVal; } - public static TerrainMessage parseRequestChunkMessage(List byteStream){ + public static TerrainMessage parseRequestChunkMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTCHUNK); - stripPacketHeader(byteStream); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -763,190 +283,30 @@ public class TerrainMessage extends NetworkMessage { return rVal; } - public static TerrainMessage parseUpdateMessage(List byteStream){ + public static TerrainMessage parseUpdateMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATE); - stripPacketHeader(byteStream); - rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setlocationZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } - public static TerrainMessage constructUpdateMessage(int locationX,int locationY,int locationZ){ + public static TerrainMessage constructUpdateMessage(int worldX,int worldY,int worldZ){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATE); - rVal.setlocationX(locationX); - rVal.setlocationY(locationY); - rVal.setlocationZ(locationZ); - rVal.serialize(); - return rVal; - } - - public static TerrainMessage parsechunkLoadStartMessage(List byteStream){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.CHUNKLOADSTART); - stripPacketHeader(byteStream); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - return rVal; - } - - public static TerrainMessage constructchunkLoadStartMessage(int worldX,int worldY,float value){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.CHUNKLOADSTART); - rVal.setworldX(worldX); - rVal.setworldY(worldY); - rVal.setvalue(value); - rVal.serialize(); - return rVal; - } - - public static TerrainMessage parseMacroValueMessage(List byteStream){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.MACROVALUE); - stripPacketHeader(byteStream); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setmacroValue00(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue01(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue02(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue03(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue04(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue10(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue11(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue12(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue13(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue14(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue20(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue21(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue22(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue23(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue24(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue30(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue31(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue32(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue33(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue34(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue40(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue41(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue42(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue43(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setmacroValue44(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setrandomizerValue00(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue01(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue02(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue03(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue04(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue10(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue11(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue12(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue13(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue14(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue20(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue21(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue22(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue23(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue24(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue30(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue31(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue32(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue33(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue34(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue40(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue41(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue42(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue43(ByteStreamUtils.popLongFromByteQueue(byteStream)); - rVal.setrandomizerValue44(ByteStreamUtils.popLongFromByteQueue(byteStream)); - return rVal; - } - - public static TerrainMessage constructMacroValueMessage(int worldX,int worldY,float macroValue00,float macroValue01,float macroValue02,float macroValue03,float macroValue04,float macroValue10,float macroValue11,float macroValue12,float macroValue13,float macroValue14,float macroValue20,float macroValue21,float macroValue22,float macroValue23,float macroValue24,float macroValue30,float macroValue31,float macroValue32,float macroValue33,float macroValue34,float macroValue40,float macroValue41,float macroValue42,float macroValue43,float macroValue44,long randomizerValue00,long randomizerValue01,long randomizerValue02,long randomizerValue03,long randomizerValue04,long randomizerValue10,long randomizerValue11,long randomizerValue12,long randomizerValue13,long randomizerValue14,long randomizerValue20,long randomizerValue21,long randomizerValue22,long randomizerValue23,long randomizerValue24,long randomizerValue30,long randomizerValue31,long randomizerValue32,long randomizerValue33,long randomizerValue34,long randomizerValue40,long randomizerValue41,long randomizerValue42,long randomizerValue43,long randomizerValue44){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.MACROVALUE); - rVal.setworldX(worldX); - rVal.setworldY(worldY); - rVal.setmacroValue00(macroValue00); - rVal.setmacroValue01(macroValue01); - rVal.setmacroValue02(macroValue02); - rVal.setmacroValue03(macroValue03); - rVal.setmacroValue04(macroValue04); - rVal.setmacroValue10(macroValue10); - rVal.setmacroValue11(macroValue11); - rVal.setmacroValue12(macroValue12); - rVal.setmacroValue13(macroValue13); - rVal.setmacroValue14(macroValue14); - rVal.setmacroValue20(macroValue20); - rVal.setmacroValue21(macroValue21); - rVal.setmacroValue22(macroValue22); - rVal.setmacroValue23(macroValue23); - rVal.setmacroValue24(macroValue24); - rVal.setmacroValue30(macroValue30); - rVal.setmacroValue31(macroValue31); - rVal.setmacroValue32(macroValue32); - rVal.setmacroValue33(macroValue33); - rVal.setmacroValue34(macroValue34); - rVal.setmacroValue40(macroValue40); - rVal.setmacroValue41(macroValue41); - rVal.setmacroValue42(macroValue42); - rVal.setmacroValue43(macroValue43); - rVal.setmacroValue44(macroValue44); - rVal.setrandomizerValue00(randomizerValue00); - rVal.setrandomizerValue01(randomizerValue01); - rVal.setrandomizerValue02(randomizerValue02); - rVal.setrandomizerValue03(randomizerValue03); - rVal.setrandomizerValue04(randomizerValue04); - rVal.setrandomizerValue10(randomizerValue10); - rVal.setrandomizerValue11(randomizerValue11); - rVal.setrandomizerValue12(randomizerValue12); - rVal.setrandomizerValue13(randomizerValue13); - rVal.setrandomizerValue14(randomizerValue14); - rVal.setrandomizerValue20(randomizerValue20); - rVal.setrandomizerValue21(randomizerValue21); - rVal.setrandomizerValue22(randomizerValue22); - rVal.setrandomizerValue23(randomizerValue23); - rVal.setrandomizerValue24(randomizerValue24); - rVal.setrandomizerValue30(randomizerValue30); - rVal.setrandomizerValue31(randomizerValue31); - rVal.setrandomizerValue32(randomizerValue32); - rVal.setrandomizerValue33(randomizerValue33); - rVal.setrandomizerValue34(randomizerValue34); - rVal.setrandomizerValue40(randomizerValue40); - rVal.setrandomizerValue41(randomizerValue41); - rVal.setrandomizerValue42(randomizerValue42); - rVal.setrandomizerValue43(randomizerValue43); - rVal.setrandomizerValue44(randomizerValue44); - rVal.serialize(); - return rVal; - } - - public static TerrainMessage parseheightMapModificationMessage(List byteStream){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.HEIGHTMAPMODIFICATION); - stripPacketHeader(byteStream); - rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteStream)); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setlocationX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setlocationY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setlocationZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); - return rVal; - } - - public static TerrainMessage constructheightMapModificationMessage(float value,int worldX,int worldY,int worldZ,int locationX,int locationY,int locationZ){ - TerrainMessage rVal = new TerrainMessage(TerrainMessageType.HEIGHTMAPMODIFICATION); - rVal.setvalue(value); rVal.setworldX(worldX); rVal.setworldY(worldY); rVal.setworldZ(worldZ); - rVal.setlocationX(locationX); - rVal.setlocationY(locationY); - rVal.setlocationZ(locationZ); rVal.serialize(); return rVal; } - public static TerrainMessage parseSpawnPositionMessage(List byteStream){ + public static TerrainMessage parseSpawnPositionMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SPAWNPOSITION); - stripPacketHeader(byteStream); - rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); - rVal.setrealLocationZ(ByteStreamUtils.popDoubleFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrealLocationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } @@ -959,12 +319,12 @@ public class TerrainMessage extends NetworkMessage { return rVal; } - public static TerrainMessage parseRequestChunkDataMessage(List byteStream){ + public static TerrainMessage parseRequestChunkDataMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTCHUNKDATA); - stripPacketHeader(byteStream); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); return rVal; } @@ -977,8 +337,8 @@ public class TerrainMessage extends NetworkMessage { return rVal; } - public static boolean canParsesendChunkDataMessage(List byteStream){ - int currentStreamLength = byteStream.size(); + public static boolean canParsesendChunkDataMessage(CircularByteBuffer byteBuffer){ + int currentStreamLength = byteBuffer.getRemaining(); List temporaryByteQueue = new LinkedList(); if(currentStreamLength < 6){ return false; @@ -993,10 +353,10 @@ public class TerrainMessage extends NetworkMessage { if(currentStreamLength < 18){ return false; } else { - temporaryByteQueue.add(byteStream.get(14 + 0)); - temporaryByteQueue.add(byteStream.get(14 + 1)); - temporaryByteQueue.add(byteStream.get(14 + 2)); - temporaryByteQueue.add(byteStream.get(14 + 3)); + temporaryByteQueue.add(byteBuffer.peek(14 + 0)); + temporaryByteQueue.add(byteBuffer.peek(14 + 1)); + temporaryByteQueue.add(byteBuffer.peek(14 + 2)); + temporaryByteQueue.add(byteBuffer.peek(14 + 3)); chunkDataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue); } if(currentStreamLength < 18 + chunkDataSize){ @@ -1005,13 +365,13 @@ public class TerrainMessage extends NetworkMessage { return true; } - public static TerrainMessage parsesendChunkDataMessage(List byteStream){ + public static TerrainMessage parsesendChunkDataMessage(CircularByteBuffer byteBuffer){ TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDCHUNKDATA); - stripPacketHeader(byteStream); - rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteStream)); - rVal.setchunkData(ByteStreamUtils.popByteArrayFromByteQueue(byteStream)); + stripPacketHeader(byteBuffer); + rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setchunkData(ByteStreamUtils.popByteArrayFromByteQueue(byteBuffer)); return rVal; } @@ -1092,25 +452,6 @@ public class TerrainMessage extends NetworkMessage { rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN; //entity messaage header rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATE; - intValues = ByteStreamUtils.serializeIntToBytes(locationX); - for(int i = 0; i < 4; i++){ - rawBytes[2+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(locationY); - for(int i = 0; i < 4; i++){ - rawBytes[6+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(locationZ); - for(int i = 0; i < 4; i++){ - rawBytes[10+i] = intValues[i]; - } - break; - case CHUNKLOADSTART: - rawBytes = new byte[2+4+4+4]; - //message header - rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN; - //entity messaage header - rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART; intValues = ByteStreamUtils.serializeIntToBytes(worldX); for(int i = 0; i < 4; i++){ rawBytes[2+i] = intValues[i]; @@ -1119,232 +460,9 @@ public class TerrainMessage extends NetworkMessage { for(int i = 0; i < 4; i++){ rawBytes[6+i] = intValues[i]; } - intValues = ByteStreamUtils.serializeFloatToBytes(value); - for(int i = 0; i < 4; i++){ - rawBytes[10+i] = intValues[i]; - } break; - case MACROVALUE: - rawBytes = new byte[2+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8]; - //message header - rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN; - //entity messaage header - rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_MACROVALUE; - intValues = ByteStreamUtils.serializeIntToBytes(worldX); - for(int i = 0; i < 4; i++){ - rawBytes[2+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(worldY); - for(int i = 0; i < 4; i++){ - rawBytes[6+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeFloatToBytes(macroValue00); - for(int i = 0; i < 4; i++){ - rawBytes[10+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue01); - for(int i = 0; i < 4; i++){ - rawBytes[14+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue02); - for(int i = 0; i < 4; i++){ - rawBytes[18+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue03); - for(int i = 0; i < 4; i++){ - rawBytes[22+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue04); - for(int i = 0; i < 4; i++){ - rawBytes[26+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue10); - for(int i = 0; i < 4; i++){ - rawBytes[30+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue11); - for(int i = 0; i < 4; i++){ - rawBytes[34+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue12); - for(int i = 0; i < 4; i++){ - rawBytes[38+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue13); - for(int i = 0; i < 4; i++){ - rawBytes[42+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue14); - for(int i = 0; i < 4; i++){ - rawBytes[46+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue20); - for(int i = 0; i < 4; i++){ - rawBytes[50+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue21); - for(int i = 0; i < 4; i++){ - rawBytes[54+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue22); - for(int i = 0; i < 4; i++){ - rawBytes[58+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue23); - for(int i = 0; i < 4; i++){ - rawBytes[62+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue24); - for(int i = 0; i < 4; i++){ - rawBytes[66+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue30); - for(int i = 0; i < 4; i++){ - rawBytes[70+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue31); - for(int i = 0; i < 4; i++){ - rawBytes[74+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue32); - for(int i = 0; i < 4; i++){ - rawBytes[78+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue33); - for(int i = 0; i < 4; i++){ - rawBytes[82+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue34); - for(int i = 0; i < 4; i++){ - rawBytes[86+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue40); - for(int i = 0; i < 4; i++){ - rawBytes[90+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue41); - for(int i = 0; i < 4; i++){ - rawBytes[94+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue42); - for(int i = 0; i < 4; i++){ - rawBytes[98+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue43); - for(int i = 0; i < 4; i++){ - rawBytes[102+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeFloatToBytes(macroValue44); - for(int i = 0; i < 4; i++){ - rawBytes[106+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue00); - for(int i = 0; i < 8; i++){ - rawBytes[110+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue01); - for(int i = 0; i < 8; i++){ - rawBytes[118+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue02); - for(int i = 0; i < 8; i++){ - rawBytes[126+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue03); - for(int i = 0; i < 8; i++){ - rawBytes[134+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue04); - for(int i = 0; i < 8; i++){ - rawBytes[142+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue10); - for(int i = 0; i < 8; i++){ - rawBytes[150+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue11); - for(int i = 0; i < 8; i++){ - rawBytes[158+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue12); - for(int i = 0; i < 8; i++){ - rawBytes[166+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue13); - for(int i = 0; i < 8; i++){ - rawBytes[174+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue14); - for(int i = 0; i < 8; i++){ - rawBytes[182+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue20); - for(int i = 0; i < 8; i++){ - rawBytes[190+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue21); - for(int i = 0; i < 8; i++){ - rawBytes[198+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue22); - for(int i = 0; i < 8; i++){ - rawBytes[206+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue23); - for(int i = 0; i < 8; i++){ - rawBytes[214+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue24); - for(int i = 0; i < 8; i++){ - rawBytes[222+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue30); - for(int i = 0; i < 8; i++){ - rawBytes[230+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue31); - for(int i = 0; i < 8; i++){ - rawBytes[238+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue32); - for(int i = 0; i < 8; i++){ - rawBytes[246+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue33); - for(int i = 0; i < 8; i++){ - rawBytes[254+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue34); - for(int i = 0; i < 8; i++){ - rawBytes[262+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue40); - for(int i = 0; i < 8; i++){ - rawBytes[270+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue41); - for(int i = 0; i < 8; i++){ - rawBytes[278+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue42); - for(int i = 0; i < 8; i++){ - rawBytes[286+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue43); - for(int i = 0; i < 8; i++){ - rawBytes[294+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeLongToBytes(randomizerValue44); - for(int i = 0; i < 8; i++){ - rawBytes[302+i] = intValues[i]; - } - break; - case HEIGHTMAPMODIFICATION: - rawBytes = new byte[2+4+4+4+4+4+4+4]; - //message header - rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN; - //entity messaage header - rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION; - intValues = ByteStreamUtils.serializeFloatToBytes(value); - for(int i = 0; i < 4; i++){ - rawBytes[2+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeIntToBytes(worldX); - for(int i = 0; i < 4; i++){ - rawBytes[6+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(worldY); - for(int i = 0; i < 4; i++){ - rawBytes[10+i] = intValues[i]; - } intValues = ByteStreamUtils.serializeIntToBytes(worldZ); for(int i = 0; i < 4; i++){ - rawBytes[14+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(locationX); - for(int i = 0; i < 4; i++){ - rawBytes[18+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(locationY); - for(int i = 0; i < 4; i++){ - rawBytes[22+i] = intValues[i]; - } - intValues = ByteStreamUtils.serializeIntToBytes(locationZ); - for(int i = 0; i < 4; i++){ - rawBytes[26+i] = intValues[i]; + rawBytes[10+i] = intValues[i]; } break; case SPAWNPOSITION: diff --git a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java index 2ce89e1f..2b7b5baa 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java +++ b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java @@ -81,12 +81,9 @@ Message categories public static final byte TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA = 1; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNK = 2; public static final byte TERRAIN_MESSAGE_TYPE_UPDATE = 3; - public static final byte TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART = 4; - public static final byte TERRAIN_MESSAGE_TYPE_MACROVALUE = 5; - public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION = 6; - public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 7; - public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 8; - public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 9; + public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 4; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 5; + public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 6; /* Terrain packet sizes */ @@ -94,9 +91,6 @@ Message categories public static final byte TERRAIN_MESSAGE_TYPE_RESPONSEMETADATA_SIZE = 30; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNK_SIZE = 10; public static final byte TERRAIN_MESSAGE_TYPE_UPDATE_SIZE = 14; - public static final byte TERRAIN_MESSAGE_TYPE_CHUNKLOADSTART_SIZE = 14; - public static final short TERRAIN_MESSAGE_TYPE_MACROVALUE_SIZE = 310; - public static final byte TERRAIN_MESSAGE_TYPE_HEIGHTMAPMODIFICATION_SIZE = 30; public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14; /* diff --git a/src/main/java/electrosphere/net/parser/net/raw/CircularByteBuffer.java b/src/main/java/electrosphere/net/parser/net/raw/CircularByteBuffer.java new file mode 100644 index 00000000..2aadb3f8 --- /dev/null +++ b/src/main/java/electrosphere/net/parser/net/raw/CircularByteBuffer.java @@ -0,0 +1,120 @@ +package electrosphere.net.parser.net.raw; + + +import java.util.concurrent.Semaphore; + +/** + * A circular byte buffer optimized for high throughput (relative to a list) and peaking at early elements of the current position. + */ +public class CircularByteBuffer { + + //The array backing this circular byte buffer + byte[] backingArray; + //the current read position of the buffer in the backing array + int position; + //the remaining bytes to read before the read position equals the write position + int remaining; + //the capacity of the backing array + int capacity; + //Lock to make the structure threadsafe + Semaphore lock = new Semaphore(1); + + /** + * Constructs a CircularByteBuffer + * @param capacity The capacity of the backing array in bytes + */ + public CircularByteBuffer(int capacity){ + backingArray = new byte[capacity]; + position = 0; + remaining = 0; + this.capacity = capacity; + } + + /** + * Adds an array of bytes to the circular buffer + * @param bytes The bytes + * @param len The number of bytes to pull from the array bytes + */ + public void add(byte[] bytes, int len){ + lock.acquireUninterruptibly(); + // System.out.println("Add start"); + int writePosition = (position + remaining) % capacity; + //amount possible to write before wrapping + int writeBeforeWrap = capacity - writePosition; + //only run wrapping logic if necessary + if(len > writeBeforeWrap){ + System.arraycopy(bytes, 0, backingArray, writePosition, writeBeforeWrap); + System.arraycopy(bytes, writeBeforeWrap, backingArray, 0, len - writeBeforeWrap); + } else { + System.arraycopy(bytes, 0, backingArray, writePosition, len); + } + remaining = remaining + len; + lock.release(); + } + + /** + * Peeks at the next element in the buffer + * @return The value of the byte next in the buffer + */ + public byte peek(){ + byte rVal = peek(0); + return rVal; + } + + /** + * Peeks at an element @param offset elements further along the buffer from the current position + * @param offset The offset, in bytes, to look forward in the buffer + * @return The value of the byte at the current position + @param offset + */ + public byte peek(int offset){ + lock.acquireUninterruptibly(); + byte rVal = backingArray[(position + offset) % capacity]; + lock.release(); + return rVal; + } + + /** + * Gets the remaining number of bytes in the buffer + * @return The remaining number of bytes + */ + public int getRemaining(){ + lock.acquireUninterruptibly(); + int rVal = remaining; + lock.release(); + return rVal; + } + + /** + * Gets the capacity of the buffer + * @return The capacity + */ + public int getCapacity(){ + lock.acquireUninterruptibly(); + int rVal = capacity; + lock.release(); + return rVal; + } + + /** + * Reads a given number of bytes from the buffer + * @param len The number of bytes to read + * @return The bytes in an array + */ + public byte[] read(int len){ + lock.acquireUninterruptibly(); + byte[] rVal = new byte[len]; + //amount possible to read before loop + int toReadBeforeLoop = capacity - position; + if(len > capacity - position){ + System.arraycopy(backingArray, position, rVal, 0, toReadBeforeLoop); + System.arraycopy(backingArray, 0, rVal, toReadBeforeLoop, len - toReadBeforeLoop); + } else { + System.arraycopy(backingArray, position, rVal, 0, len); + } + position = (position + len) % capacity; + remaining = remaining - len; + lock.release(); + return rVal; + } + +} diff --git a/src/main/java/electrosphere/net/parser/net/raw/NetworkParser.java b/src/main/java/electrosphere/net/parser/net/raw/NetworkParser.java index 7cc5a544..325a7302 100644 --- a/src/main/java/electrosphere/net/parser/net/raw/NetworkParser.java +++ b/src/main/java/electrosphere/net/parser/net/raw/NetworkParser.java @@ -15,7 +15,7 @@ public class NetworkParser { CopyOnWriteArrayList incomingMessageQueue = new CopyOnWriteArrayList(); CopyOnWriteArrayList outgoingMessageQueue = new CopyOnWriteArrayList(); - CopyOnWriteArrayList incomingByteQueue = new CopyOnWriteArrayList(); + CircularByteBuffer incomingByteBuffer = new CircularByteBuffer(64 * 1024 * 124); CopyOnWriteArrayList outgoingByteQueue = new CopyOnWriteArrayList(); @@ -29,24 +29,24 @@ public class NetworkParser { } + static final int READ_BUFFER_SIZE = 64 * 1024 * 1024; + byte[] readBuffer = new byte[READ_BUFFER_SIZE]; public void readMessagesIn(){ try { //read in bytes - int nextValue = 0; + int bytesRead = 0; byte currentByte = -1; while(incomingStream.available() > 0){ - nextValue = incomingStream.read(); - if(nextValue != -1){ - currentByte = (byte)nextValue; - incomingByteQueue.add(currentByte); -// System.out.println(currentByte); + // nextValue = incomingStream.read(); + bytesRead = incomingStream.read(readBuffer, 0, READ_BUFFER_SIZE); + if(bytesRead > 0){ + incomingByteBuffer.add(readBuffer, bytesRead); } - //add bytes to some kind of queue } //parse byte queue for messages //for each message, append to clientIncomingMessageQueue NetworkMessage newMessage; - while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteQueue))!=null){ + while((newMessage = NetworkMessage.parseBytestreamForMessage(incomingByteBuffer))!=null){ incomingMessageQueue.add(newMessage); } } catch (IOException ex) { diff --git a/src/main/java/electrosphere/net/parser/util/ByteStreamUtils.java b/src/main/java/electrosphere/net/parser/util/ByteStreamUtils.java index a2336e25..f1c036cc 100644 --- a/src/main/java/electrosphere/net/parser/util/ByteStreamUtils.java +++ b/src/main/java/electrosphere/net/parser/util/ByteStreamUtils.java @@ -1,5 +1,7 @@ package electrosphere.net.parser.util; +import electrosphere.net.parser.net.raw.CircularByteBuffer; + import java.nio.ByteBuffer; import java.util.List; import java.util.concurrent.Semaphore; @@ -107,6 +109,96 @@ public class ByteStreamUtils { bufferLock.release(); return rVal; } + + public static int popIntFromByteQueue(CircularByteBuffer byteBuffer){ + int rVal = -1; + bufferLock.acquireUninterruptibly(); + integerCompactor.clear(); + integerCompactor.position(0); + integerCompactor.limit(4); + integerCompactor.put(0,byteBuffer.peek(0)); + integerCompactor.put(1,byteBuffer.peek(1)); + integerCompactor.put(2,byteBuffer.peek(2)); + integerCompactor.put(3,byteBuffer.peek(3)); + byteBuffer.read(4); + integerCompactor.position(0); + integerCompactor.limit(4); + rVal = integerCompactor.getInt(); + bufferLock.release(); + return rVal; + } + + public static float popFloatFromByteQueue(CircularByteBuffer byteBuffer){ + float rVal = -1; + bufferLock.acquireUninterruptibly(); + integerCompactor.clear(); + integerCompactor.position(0); + integerCompactor.limit(4); + integerCompactor.put(0,byteBuffer.read(1)); + integerCompactor.put(1,byteBuffer.read(1)); + integerCompactor.put(2,byteBuffer.read(1)); + integerCompactor.put(3,byteBuffer.read(1)); + integerCompactor.position(0); + integerCompactor.limit(4); + rVal = integerCompactor.getFloat(); + bufferLock.release(); + return rVal; + } + + public static long popLongFromByteQueue(CircularByteBuffer byteBuffer){ + long rVal = -1; + bufferLock.acquireUninterruptibly(); + integerCompactor.clear(); + integerCompactor.position(0); + integerCompactor.limit(8); + integerCompactor.put(0,byteBuffer.read(1)); + integerCompactor.put(1,byteBuffer.read(1)); + integerCompactor.put(2,byteBuffer.read(1)); + integerCompactor.put(3,byteBuffer.read(1)); + integerCompactor.put(4,byteBuffer.read(1)); + integerCompactor.put(5,byteBuffer.read(1)); + integerCompactor.put(6,byteBuffer.read(1)); + integerCompactor.put(7,byteBuffer.read(1)); + integerCompactor.position(0); + integerCompactor.limit(8); + rVal = integerCompactor.getLong(); + bufferLock.release(); + return rVal; + } + + public static String popStringFromByteQueue(CircularByteBuffer byteBuffer){ + int length = popIntFromByteQueue(byteBuffer); + byte[] stringBytes = byteBuffer.read(length); + String rVal = new String(stringBytes); + return rVal; + } + + public static byte[] popByteArrayFromByteQueue(CircularByteBuffer byteBuffer){ + int length = popIntFromByteQueue(byteBuffer); + byte[] bytes = byteBuffer.read(length); + return bytes; + } + + public static double popDoubleFromByteQueue(CircularByteBuffer byteBuffer){ + double rVal = -1; + bufferLock.acquireUninterruptibly(); + integerCompactor.clear(); + integerCompactor.position(0); + integerCompactor.limit(8); + integerCompactor.put(0,byteBuffer.read(1)); + integerCompactor.put(1,byteBuffer.read(1)); + integerCompactor.put(2,byteBuffer.read(1)); + integerCompactor.put(3,byteBuffer.read(1)); + integerCompactor.put(4,byteBuffer.read(1)); + integerCompactor.put(5,byteBuffer.read(1)); + integerCompactor.put(6,byteBuffer.read(1)); + integerCompactor.put(7,byteBuffer.read(1)); + integerCompactor.position(0); + integerCompactor.limit(8); + rVal = integerCompactor.getDouble(); + bufferLock.release(); + return rVal; + } public static byte[] serializeIntToBytes(int i){ byte[] rVal = new byte[4]; diff --git a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java index 8e56ef11..448251d3 100644 --- a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java @@ -1,5 +1,10 @@ package electrosphere.net.server.protocol; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.engine.Globals; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.net.server.Server; @@ -12,25 +17,27 @@ public class TerrainProtocol { protected static void handleTerrainMessage(ServerConnectionHandler connectionHandler, TerrainMessage message){ switch(message.getMessageSubtype()){ case REQUESTCHUNK: - sendWorldChunk(connectionHandler, message.getworldX(), message.getworldY()); + // sendWorldChunk(connectionHandler, message.getworldX(), message.getworldY()); break; case REQUESTMETADATA: sendWorldMetadata(connectionHandler); break; - + case REQUESTCHUNKDATA: + sendWorldSubChunk(connectionHandler, + message.getworldX(), message.getworldY(), message.getworldZ() + ); + break; //all ignored message types - case CHUNKLOADSTART: - case HEIGHTMAPMODIFICATION: - case MACROVALUE: case RESPONSEMETADATA: case SPAWNPOSITION: case UPDATE: + case SENDCHUNKDATA: //silently ignore break; } } - static void sendWorldChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY){ + static void sendWorldSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){ /* int locationX, int locationY, @@ -56,92 +63,117 @@ public class TerrainProtocol { // System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY()); - ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY); + ServerTerrainChunk chunk = Globals.serverTerrainManager.getChunk(worldX, worldY, worldZ); - float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY()); + // float[][] macroValues = chunk.getMacroValues();//Globals.serverTerrainManager.getRad5MacroValues(message.getworldX(), message.getworldY()); - long[][] randomizer = chunk.getRandomizer();//Globals.serverTerrainManager.getRandomizer(message.getworldX(), message.getworldY()); + // long[][] randomizer = chunk.getRandomizer();//Globals.serverTerrainManager.getRandomizer(message.getworldX(), message.getworldY()); - int numMessages = 2 + chunk.getModifications().size(); + ByteBuffer buffer = ByteBuffer.allocate(ServerTerrainChunk.CHUNK_DIMENSION*ServerTerrainChunk.CHUNK_DIMENSION*ServerTerrainChunk.CHUNK_DIMENSION*(4+4)); + FloatBuffer floatView = buffer.asFloatBuffer(); - connectionHandler.addMessagetoOutgoingQueue( - TerrainMessage.constructchunkLoadStartMessage(worldX, worldY, numMessages) - ); - - connectionHandler.addMessagetoOutgoingQueue( - TerrainMessage.constructMacroValueMessage( - worldX, - worldY, - - - macroValues[0][0], - macroValues[0][1], - macroValues[0][2], - macroValues[0][3], - macroValues[0][4], - macroValues[1][0], - macroValues[1][1], - macroValues[1][2], - macroValues[1][3], - macroValues[1][4], - macroValues[2][0], - macroValues[2][1], - macroValues[2][2], - macroValues[2][3], - macroValues[2][4], - macroValues[3][0], - macroValues[3][1], - macroValues[3][2], - macroValues[3][3], - macroValues[3][4], - macroValues[4][0], - macroValues[4][1], - macroValues[4][2], - macroValues[4][3], - macroValues[4][4], - - - randomizer[0][0], - randomizer[0][1], - randomizer[0][2], - randomizer[0][3], - randomizer[0][4], - randomizer[1][0], - randomizer[1][1], - randomizer[1][2], - randomizer[1][3], - randomizer[1][4], - randomizer[2][0], - randomizer[2][1], - randomizer[2][2], - randomizer[2][3], - randomizer[2][4], - randomizer[3][0], - randomizer[3][1], - randomizer[3][2], - randomizer[3][3], - randomizer[3][4], - randomizer[4][0], - randomizer[4][1], - randomizer[4][2], - randomizer[4][3], - randomizer[4][4] - ) - ); - - for(TerrainModification modification : chunk.getModifications()){ - connectionHandler.addMessagetoOutgoingQueue( - TerrainMessage.constructheightMapModificationMessage( - modification.getValue(), - modification.getWorldX(), - 0, - modification.getWorldY(), - modification.getLocationX(), - 0, - modification.getLocationY() - ) - ); + for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ + for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ + for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ + floatView.put(chunk.getWeights()[x][y][z]); + } + } } + + IntBuffer intView = buffer.asIntBuffer(); + intView.position(floatView.position()); + + for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ + for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ + for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ + intView.put(chunk.getValues()[x][y][z]); + } + } + } + + + connectionHandler.addMessagetoOutgoingQueue(TerrainMessage.constructsendChunkDataMessage(worldX, worldY, worldZ, buffer.array())); + + // int numMessages = 2 + chunk.getModifications().size(); + + // connectionHandler.addMessagetoOutgoingQueue( + // TerrainMessage.constructchunkLoadStartMessage(worldX, worldY, numMessages) + // ); + + // connectionHandler.addMessagetoOutgoingQueue( + // TerrainMessage.constructMacroValueMessage( + // worldX, + // worldY, + + + // macroValues[0][0], + // macroValues[0][1], + // macroValues[0][2], + // macroValues[0][3], + // macroValues[0][4], + // macroValues[1][0], + // macroValues[1][1], + // macroValues[1][2], + // macroValues[1][3], + // macroValues[1][4], + // macroValues[2][0], + // macroValues[2][1], + // macroValues[2][2], + // macroValues[2][3], + // macroValues[2][4], + // macroValues[3][0], + // macroValues[3][1], + // macroValues[3][2], + // macroValues[3][3], + // macroValues[3][4], + // macroValues[4][0], + // macroValues[4][1], + // macroValues[4][2], + // macroValues[4][3], + // macroValues[4][4], + + + // randomizer[0][0], + // randomizer[0][1], + // randomizer[0][2], + // randomizer[0][3], + // randomizer[0][4], + // randomizer[1][0], + // randomizer[1][1], + // randomizer[1][2], + // randomizer[1][3], + // randomizer[1][4], + // randomizer[2][0], + // randomizer[2][1], + // randomizer[2][2], + // randomizer[2][3], + // randomizer[2][4], + // randomizer[3][0], + // randomizer[3][1], + // randomizer[3][2], + // randomizer[3][3], + // randomizer[3][4], + // randomizer[4][0], + // randomizer[4][1], + // randomizer[4][2], + // randomizer[4][3], + // randomizer[4][4] + // ) + // ); + + // for(TerrainModification modification : chunk.getModifications()){ + // connectionHandler.addMessagetoOutgoingQueue( + // TerrainMessage.constructheightMapModificationMessage( + // modification.getValue(), + // modification.getWorldX(), + // 0, + // modification.getWorldY(), + // modification.getLocationX(), + // 0, + // modification.getLocationY() + // ) + // ); + // } } static void sendWorldMetadata(ServerConnectionHandler connectionHandler){ diff --git a/src/main/java/electrosphere/renderer/Material.java b/src/main/java/electrosphere/renderer/Material.java index 5aceeddc..aed16bb6 100644 --- a/src/main/java/electrosphere/renderer/Material.java +++ b/src/main/java/electrosphere/renderer/Material.java @@ -1,15 +1,8 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package electrosphere.renderer; import electrosphere.engine.Globals; import electrosphere.renderer.texture.Texture; -import org.lwjgl.PointerBuffer; import org.lwjgl.assimp.AIMaterial; -import org.lwjgl.assimp.AIMaterialProperty; import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; import static org.lwjgl.opengl.GL11.glBindTexture; import static org.lwjgl.opengl.GL13.GL_TEXTURE0; @@ -27,6 +20,8 @@ public class Material { String specular; boolean hasTransparency = false; + //Sets whether this material should get its texture pointers from the assetManager by looking up diffuse and specular paths + //or whether it should have a manually set texturePointer and not look up while binding boolean usesFetch = true; int texturePointer; @@ -70,8 +65,11 @@ public class Material { usesFetch = false; } + /** + * Applies the material + */ public void apply_material(){ - //basically a switch for the case where we want to manually set texture pointer + //Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material if(usesFetch){ Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); if(diffuseTexture != null){ diff --git a/src/main/java/electrosphere/renderer/actor/instance/InstanceData.java b/src/main/java/electrosphere/renderer/actor/instance/InstanceData.java index 3db7d67c..a2bb736f 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/InstanceData.java +++ b/src/main/java/electrosphere/renderer/actor/instance/InstanceData.java @@ -132,40 +132,41 @@ public class InstanceData { */ protected void fillBuffers(){ int i = 0; - //reset all buffers + //for some reason the limit is not being set correctly. This explicitly forces it for each buffer for(ShaderAttribute attribute : attributeIndices){ switch(attributeGlBufferMap.get(attribute).getType()){ case VEC3F: { FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case VEC3D: { DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case VEC4F: { FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case VEC4D: { DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case MAT4F: { FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); + // System.out.println(buffer.position() + " " + buffer.limit()); } break; case DOUBLE: { DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case FLOAT: { FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; case INT: { IntBuffer buffer = ((IntBuffer)attributeCpuBufferMap.get(attribute)); - buffer.position(0); + buffer.limit(buffer.capacity()); } break; } } @@ -308,6 +309,46 @@ public class InstanceData { } } + protected void flip(){ + //reset all buffers + for(ShaderAttribute attribute : attributeIndices){ + switch(attributeGlBufferMap.get(attribute).getType()){ + case VEC3F: { + FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case VEC3D: { + DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case VEC4F: { + FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case VEC4D: { + DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case MAT4F: { + FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case DOUBLE: { + DoubleBuffer buffer = ((DoubleBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case FLOAT: { + FloatBuffer buffer = ((FloatBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + case INT: { + IntBuffer buffer = ((IntBuffer)attributeCpuBufferMap.get(attribute)); + buffer.flip(); + } break; + } + } + } + /** * Gets a map of all attributes to the buffers of data for that attribute * @return The data buffers diff --git a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java index 108b9289..fb804345 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java +++ b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java @@ -85,6 +85,8 @@ public class InstanceManager { model.draw(renderPipelineState); } + data.flip(); + //clear queue data.clearDrawQueue(); } diff --git a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java index c2625c1e..9a93ba4c 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java @@ -790,6 +790,7 @@ public class TerrainChunkModelGeneration { Material groundMat = new Material(); groundMat.set_diffuse("/Textures/Ground/Dirt1.png"); groundMat.set_specular("/Textures/Ground/Dirt1.png"); + Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); m.setShader(TerrainChunkModelGeneration.terrainChunkShaderProgram); @@ -802,7 +803,7 @@ public class TerrainChunkModelGeneration { //TODO: more optimal key creation private static String getVertKeyFromPoints(float x, float y, float z){ - return x + "-" + y + "-" + z; + return x + "_" + y + "_" + z; } private static int getVertIndex(Vector3f vert, Map vertMap, List verts){ diff --git a/src/main/java/electrosphere/server/ai/creature/MillAbout.java b/src/main/java/electrosphere/server/ai/creature/MillAbout.java index d1783bdb..5e9b08e8 100644 --- a/src/main/java/electrosphere/server/ai/creature/MillAbout.java +++ b/src/main/java/electrosphere/server/ai/creature/MillAbout.java @@ -64,7 +64,7 @@ public class MillAbout extends AI { rand.nextFloat() - 0.5, rand.nextFloat() - 0.5 ).normalize().mul(millTargetMaxDist); - moveVector.y = Globals.commonWorldData.getElevationAtPoint(new Vector3d(position).add(moveVector)); + moveVector.y = position.y; //Globals.commonWorldData.getElevationAtPoint(new Vector3d(position).add(moveVector)); //TODO: search in navmeshmanager to make sure navigable, otherwise generate new pos // } diff --git a/src/main/java/electrosphere/server/ai/creature/adventurer/SeekTown.java b/src/main/java/electrosphere/server/ai/creature/adventurer/SeekTown.java index 666eea0c..dbbcbb46 100644 --- a/src/main/java/electrosphere/server/ai/creature/adventurer/SeekTown.java +++ b/src/main/java/electrosphere/server/ai/creature/adventurer/SeekTown.java @@ -29,18 +29,18 @@ public class SeekTown extends AI { @Override public void simulate() { - if(target == null){ - if(Globals.macroData.getTowns().size() > 0){ - target = Globals.macroData.getTowns().get(0); - targetPos = new Vector3d( - Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).x), - 0, - Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).y) - ); - targetPos.y = Globals.commonWorldData.getElevationAtPoint(targetPos); - System.out.println("Target pos: " + targetPos); - } - } + // if(target == null){ + // if(Globals.macroData.getTowns().size() > 0){ + // target = Globals.macroData.getTowns().get(0); + // targetPos = new Vector3d( + // Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).x), + // 0, + // Globals.commonWorldData.convertWorldToReal(target.getPositions().get(0).y) + // ); + // targetPos.y = Globals.commonWorldData.getElevationAtPoint(targetPos); + // System.out.println("Target pos: " + targetPos); + // } + // } moveToTarget(); } diff --git a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java index 3e47455c..56988ee0 100644 --- a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java +++ b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java @@ -24,14 +24,14 @@ public class EnvironmentGenerator { Random rand = new Random(randomizer); int targetNum = (int)(rand.nextFloat() * 10) + 10; for(int i = 0; i < targetNum; i++){ - Entity newTree = FoliageUtils.spawnBasicFoliage("FallOak1"); - cell.getScene().registerEntity(newTree); - double posX = worldPos.x * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio()); - double posZ = worldPos.z * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio()); - double posY = Globals.serverTerrainManager.getHeightAtPosition(posX, posZ); -// System.out.println("Spawning tree at: " + posX + "," + posY + "," + posZ); -// CollisionObjUtils.positionCharacter(newTree, new Vector3f(posX,posY,posZ)); - EntityUtils.getPosition(newTree).set(posX,posY,posZ); +// Entity newTree = FoliageUtils.spawnBasicFoliage("FallOak1"); +// cell.getScene().registerEntity(newTree); +// double posX = worldPos.x * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio()); +// double posZ = worldPos.z * Globals.serverWorldData.getDynamicInterpolationRatio() + (float)(rand.nextFloat() * Globals.serverWorldData.getDynamicInterpolationRatio()); +// double posY = Globals.serverTerrainManager.getHeightAtPosition(posX, posZ); +// // System.out.println("Spawning tree at: " + posX + "," + posY + "," + posZ); +// // CollisionObjUtils.positionCharacter(newTree, new Vector3f(posX,posY,posZ)); +// EntityUtils.getPosition(newTree).set(posX,posY,posZ); } } } diff --git a/src/main/java/electrosphere/server/content/ServerContentManager.java b/src/main/java/electrosphere/server/content/ServerContentManager.java index f59ab2ef..d0eec60d 100644 --- a/src/main/java/electrosphere/server/content/ServerContentManager.java +++ b/src/main/java/electrosphere/server/content/ServerContentManager.java @@ -15,7 +15,14 @@ public class ServerContentManager { //else create from scratch EnvironmentGenerator.generatePlains(cell, worldPos, Globals.serverTerrainManager.getRandomizerAtPoint(worldPos.x, worldPos.z)); } - cell.setNavMesh(NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.z),Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z))); + cell.setNavMesh( + NavMeshUtils.createMeshFromChunk(Globals.serverTerrainManager.getChunk( + worldPos.x, + worldPos.y, + worldPos.z + ), + Globals.navMeshManager.getBlockerCache().getBlocker(worldPos.x, worldPos.z)) + ); } diff --git a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java index 17e27f64..77bf4da9 100644 --- a/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java +++ b/src/main/java/electrosphere/server/datacell/GriddedDataCellManager.java @@ -1,9 +1,12 @@ package electrosphere.server.datacell; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.Semaphore; import org.joml.Vector3d; import org.joml.Vector3i; @@ -16,29 +19,40 @@ import electrosphere.game.server.world.ServerWorldData; import electrosphere.logger.LoggerInterface; import electrosphere.net.server.player.Player; import electrosphere.server.datacell.interfaces.DataCellManager; +import electrosphere.server.datacell.physics.PhysicsDataCell; +import electrosphere.server.terrain.manager.ServerTerrainManager; +import electrosphere.server.terrain.manager.ServerTerrainChunk; /** * Implementation of DataCellManager that lays out cells in a logical grid (array). Useful for eg 3d terrain gridded world. */ public class GriddedDataCellManager implements DataCellManager { //these are going to be the natural ground grid of data cells, but we're going to have more than this - ServerDataCell[][][] groundDataCells; + Map groundDataCells = new HashMap(); + //loaded cells + Semaphore loadedCellsLock = new Semaphore(1); Set loadedCells; int discreteWorldSize; //parent realm Realm parent; + //Manager for terrain for this particular cell manager + ServerTerrainManager serverTerrainManager; /** * Constructor * @param parent The gridded data cell manager's parent realm */ - public GriddedDataCellManager(Realm parent) { + public GriddedDataCellManager(Realm parent, ServerTerrainManager serverTerrainManager) { this.parent = parent; + this.serverTerrainManager = serverTerrainManager; } + /** + * Initializes the gridded data cell manager + * @param data The server world data to back the manager with + */ public void init(ServerWorldData data){ discreteWorldSize = data.getWorldSizeDiscrete(); - groundDataCells = new ServerDataCell[discreteWorldSize][discreteWorldSize][discreteWorldSize]; loadedCells = new HashSet(); } @@ -57,17 +71,24 @@ public class GriddedDataCellManager implements DataCellManager { y >= 0 && y < discreteWorldSize && z >= 0 && z < discreteWorldSize ){ - LoggerInterface.loggerEngine.DEBUG("TerrainDataCellManager: Add player to " + x + " " + y); - if(groundDataCells[x][y][z] != null){ - groundDataCells[x][y][z].addPlayer(player); + Vector3i targetPos = new Vector3i(x,y,z); + LoggerInterface.loggerEngine.DEBUG("GriddedDataCellManager: Add player to " + x + " " + y + " " + z); + if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){ + groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player); } else { + LoggerInterface.loggerEngine.DEBUG("Creating new cell @ " + x + " " + y + " " + z); //create data cell - groundDataCells[x][y][z] = ServerDataCell.createServerDataCell(new Scene()); - loadedCells.add(groundDataCells[x][y][z]); + createServerDataCell(targetPos); + ///generates physics for the cell in a dedicated thread then finally registers + runPhysicsGenerationThread(targetPos); + //add to loaded cells + loadedCellsLock.acquireUninterruptibly(); + loadedCells.add(groundDataCells.get(getServerDataCellKey(targetPos))); + loadedCellsLock.release(); //generate/handle content for new server data cell //add player - groundDataCells[x][y][z].addPlayer(player); + groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player); } } } @@ -103,10 +124,11 @@ public class GriddedDataCellManager implements DataCellManager { z > newPosition.z + playerSimulationRadius ) ){ - if(groundDataCells[x][y][z] != null){ - if(groundDataCells[x][y][z].containsPlayer(player)){ + Vector3i targetPos = new Vector3i(x,y,z); + if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){ + if(groundDataCells.get(getServerDataCellKey(targetPos)).containsPlayer(player)){ // removals++; - groundDataCells[x][y][z].removePlayer(player); + groundDataCells.get(getServerDataCellKey(targetPos)).removePlayer(player); } } } @@ -129,14 +151,21 @@ public class GriddedDataCellManager implements DataCellManager { z > oldPosition.z + playerSimulationRadius ) ){ + Vector3i targetPos = new Vector3i(x,y,z); // System.out.println("Add player to " + x + " " + y); - if(groundDataCells[x][y][z] != null){ - groundDataCells[x][y][z].addPlayer(player); + if(groundDataCells.get(getServerDataCellKey(targetPos)) != null){ + groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player); } else { //create data cell - groundDataCells[x][y][z] = parent.createNewCell(); + createServerDataCell(targetPos); + //generates physics for the cell in a dedicated thread then finally registers + runPhysicsGenerationThread(targetPos); + //add to loaded cells + loadedCellsLock.acquireUninterruptibly(); + loadedCells.add(groundDataCells.get(getServerDataCellKey(targetPos))); + loadedCellsLock.release(); //add player - groundDataCells[x][y][z].addPlayer(player); + groundDataCells.get(getServerDataCellKey(targetPos)).addPlayer(player); } // additions++; } else { @@ -148,6 +177,15 @@ public class GriddedDataCellManager implements DataCellManager { } // System.out.println("removals: " + removals + "\tadditions: " + additions); } + + /** + * Creates physics entities when new data cell being created + */ + private void createTerrainPhysicsEntities(Vector3i worldPos){ + ServerTerrainChunk subChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z); + PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(parent, worldPos, subChunk); + cell.generatePhysics(); + } /** * For every player, looks at their entity and determines what data cell they should be considered inside of @@ -181,15 +219,16 @@ public class GriddedDataCellManager implements DataCellManager { int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); + Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); if( //in bounds of array - worldX >= 0 && worldX < groundDataCells.length && - worldY >= 0 && worldY < groundDataCells[0].length && - worldZ >= 0 && worldZ < groundDataCells[0][0].length && + worldX >= 0 && worldX < discreteWorldSize && + worldY >= 0 && worldY < discreteWorldSize && + worldZ >= 0 && worldZ < discreteWorldSize && //isn't null - groundDataCells[worldX][worldY][worldZ] != null + groundDataCells.get(getServerDataCellKey(worldPos)) != null ){ - rVal = groundDataCells[worldX][worldY][worldZ]; + rVal = groundDataCells.get(getServerDataCellKey(worldPos)); } return rVal; } @@ -203,18 +242,25 @@ public class GriddedDataCellManager implements DataCellManager { int worldX = Globals.serverWorldData.convertRealToChunkSpace(point.x); int worldY = Globals.serverWorldData.convertRealToChunkSpace(point.y); int worldZ = Globals.serverWorldData.convertRealToChunkSpace(point.z); + Vector3i worldPos = new Vector3i(worldX,worldY,worldZ); if( //in bounds of array - worldX >= 0 && worldX < groundDataCells.length && - worldY >= 0 && worldY < groundDataCells[0].length && - worldZ >= 0 && worldZ < groundDataCells[0][0].length && + worldX >= 0 && worldX < discreteWorldSize && + worldY >= 0 && worldY < discreteWorldSize && + worldZ >= 0 && worldZ < discreteWorldSize && //isn't null - groundDataCells[worldX][worldY][worldZ] == null + groundDataCells.get(getServerDataCellKey(worldPos)) == null ){ - groundDataCells[worldX][worldY][worldZ] = ServerDataCell.createServerDataCell(new Scene()); - loadedCells.add(groundDataCells[worldX][worldY][worldZ]); + //create data cell + createServerDataCell(worldPos); + //generates physics for the cell in a dedicated thread then finally registers + runPhysicsGenerationThread(worldPos); + //add to loaded cells + loadedCellsLock.acquireUninterruptibly(); + loadedCells.add(groundDataCells.get(getServerDataCellKey(worldPos))); + loadedCellsLock.release(); } - return groundDataCells[worldX][worldY][worldZ]; + return groundDataCells.get(getServerDataCellKey(worldPos)); } /** @@ -225,13 +271,13 @@ public class GriddedDataCellManager implements DataCellManager { public ServerDataCell getCellAtWorldPosition(Vector3i position){ if( //in bounds of array - position.x >= 0 && position.x < groundDataCells.length && - position.y >= 0 && position.y < groundDataCells[0].length && - position.z >= 0 && position.z < groundDataCells[0][0].length && + position.x >= 0 && position.x < discreteWorldSize && + position.y >= 0 && position.y < discreteWorldSize && + position.z >= 0 && position.z < discreteWorldSize && //isn't null - groundDataCells[position.x][position.y][position.z] != null + groundDataCells.get(getServerDataCellKey(position)) != null ){ - return groundDataCells[position.x][position.y][position.z]; + return groundDataCells.get(getServerDataCellKey(position)); } return null; } @@ -241,9 +287,59 @@ public class GriddedDataCellManager implements DataCellManager { * Calls the simulate function on all loaded cells */ public void simulate(){ + loadedCellsLock.acquireUninterruptibly(); for(ServerDataCell cell : loadedCells){ Globals.microSimulation.simulate(cell, parent.getHitboxManager()); } + loadedCellsLock.release(); + } + + + /** + * Gets the server terrain manager for this realm if it exists + * @return The server terrain manager if it exists, null otherwise + */ + public ServerTerrainManager getServerTerrainManager(){ + return serverTerrainManager; + } + + /** + * Runs code to generate physics entities and register cell in a dedicated thread. + * Because cell hasn't been registered yet, no simulation is performed until the physics is created. + * @param worldPos + */ + private void runPhysicsGenerationThread(Vector3i worldPos){ + Thread thread = new Thread(new Runnable(){ + @Override + public void run() { + //create physics entities + createTerrainPhysicsEntities(worldPos); + //set ready + groundDataCells.get(getServerDataCellKey(worldPos)).setReady(true); + } + }); + groundDataCells.get(getServerDataCellKey(worldPos)).setReady(false); + thread.start(); + } + + /** + * Gets the key in the groundDataCells map for the data cell at the provided world pos + * @param worldPos The position in world coordinates of the server data cell + * @return The server data cell if it exists, otherwise null + */ + private String getServerDataCellKey(Vector3i worldPos){ + return worldPos.x + "_" + worldPos.y + "_" + worldPos.z; + } + + /** + * Registers a server data cell with the internal datastructure for tracking them + * @param key The key to register the cell at + * @param cell The cell itself + */ + private ServerDataCell createServerDataCell(Vector3i worldPos){ + ServerDataCell rVal = parent.createNewCell(); + groundDataCells.put(getServerDataCellKey(worldPos),rVal); + return rVal; } } diff --git a/src/main/java/electrosphere/server/datacell/Realm.java b/src/main/java/electrosphere/server/datacell/Realm.java index e42b5564..54f71aee 100644 --- a/src/main/java/electrosphere/server/datacell/Realm.java +++ b/src/main/java/electrosphere/server/datacell/Realm.java @@ -7,13 +7,14 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.Scene; import electrosphere.entity.types.hitbox.HitboxManager; import electrosphere.game.collision.CollisionEngine; -import electrosphere.game.collision.CommonWorldData; +import electrosphere.game.collision.CollisionWorldData; import electrosphere.game.server.world.ServerWorldData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.server.Server; import electrosphere.net.server.player.Player; import electrosphere.server.datacell.interfaces.DataCellManager; +import electrosphere.server.terrain.manager.ServerTerrainManager; import java.util.LinkedList; import java.util.List; @@ -30,9 +31,6 @@ public class Realm { //this is the cell that all players loading into the game (via connection startup, death, etc) reside in ServerDataCell loadingCell = new ServerDataCell(new Scene()); - //resolver for location -> data cell within this realm - // DataCellLocationResolver dataCellLocationResolver; - //resolver for entity -> data cell within this realm EntityDataCellMapper entityDataCellMapper; diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index a93e37a3..ad800fe1 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -4,10 +4,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.types.hitbox.HitboxManager; import electrosphere.game.collision.CollisionEngine; +import electrosphere.game.collision.CollisionWorldData; import electrosphere.game.server.world.ServerWorldData; /** @@ -16,9 +20,9 @@ import electrosphere.game.server.world.ServerWorldData; public class RealmManager { //All realms in this manager - Set realms = new HashSet(); + Set realms = new CopyOnWriteArraySet(); //Map of entities to the realm the entity is in - Map entityToRealmMap = new HashMap(); + Map entityToRealmMap = new ConcurrentHashMap(); /** @@ -42,9 +46,13 @@ public class RealmManager { * @return The realm */ public Realm createGriddedRealm(ServerWorldData serverWorldData){ - Realm realm = new Realm(new CollisionEngine(), new HitboxManager()); + //create collision engine + CollisionEngine collisionEngine = new CollisionEngine(); + collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData)); + //create realm + Realm realm = new Realm(collisionEngine, new HitboxManager()); //create function classes - GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm); + GriddedDataCellManager griddedDataCellManager = new GriddedDataCellManager(realm,Globals.serverTerrainManager); EntityDataCellMapper entityDataCellMapper = new EntityDataCellMapper(); //init gridded manager griddedDataCellManager.init(serverWorldData); diff --git a/src/main/java/electrosphere/server/datacell/ServerDataCell.java b/src/main/java/electrosphere/server/datacell/ServerDataCell.java index c4e177a6..32cc33a9 100644 --- a/src/main/java/electrosphere/server/datacell/ServerDataCell.java +++ b/src/main/java/electrosphere/server/datacell/ServerDataCell.java @@ -31,7 +31,8 @@ public class ServerDataCell { List activePlayers = new LinkedList(); NavMesh navMesh; Scene scene; - + //controls whether the server data cell simulates its entities or not + boolean ready = false; /** * Constructs a datacell based on a virtual cell. Should be used when a player @@ -222,5 +223,21 @@ public class ServerDataCell { public void setNavMesh(NavMesh navMesh){ this.navMesh = navMesh; } + + /** + * Gets the simulation ready status of the server data cell + * @return True if ready, false otherwise + */ + public boolean isReady(){ + return ready; + } + + /** + * Sets the simulation ready status of the server data cell + * @param ready True if ready, false otherwise + */ + public void setReady(boolean ready){ + this.ready = ready; + } } diff --git a/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java b/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java index 69c806c0..ca8fdcf6 100644 --- a/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java +++ b/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java @@ -1,44 +1,49 @@ package electrosphere.server.datacell.physics; import electrosphere.client.scene.ClientWorldData; +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; import electrosphere.game.terrain.processing.TerrainInterpolator; -import electrosphere.game.collision.CommonWorldData; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.renderer.ShaderProgram; +import electrosphere.server.datacell.Realm; import electrosphere.server.terrain.manager.ServerTerrainManager; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.joml.Vector2i; import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector3i; /** - * This managed spinning up and tearing down physics on the server side specifically for terrain meshes + * + * @author satellite */ public class DataCellPhysicsManager { - //the center of this cell manager's array in cell space - int cellX; - int cellY; //the dimensions of the world that this cell manager can handles int cellWidth; - int cellHeight; //the width of a minicell in this manager int miniCellWidth; //all currently displaying mini cells - PhysicsDataCell[][] cells; - boolean[][] valid; - boolean[][] updateable; - boolean[][] hasRequested; - boolean[][] needsPhysics; - boolean[][] hasPhysics; + Set cells; + Map keyCellMap = new HashMap(); + Set invalid; + Set updateable; + Set hasRequested; + + + ShaderProgram program; + int drawRadius = 5; @@ -49,10 +54,7 @@ public class DataCellPhysicsManager { int worldBoundDiscreteMin = 0; int worldBoundDiscreteMax = 0; - - //metadata about the game world - CommonWorldData commonWorldData; - + //client terrain manager // ClientTerrainManager clientTerrainManager; @@ -63,34 +65,27 @@ public class DataCellPhysicsManager { //controls whether we try to generate the drawable entities //we want this to be false when in server-only mode boolean generateDrawables = false; + + Realm realm; - - public DataCellPhysicsManager(CommonWorldData commonWorldData, int discreteX, int discreteY){ - this.commonWorldData = commonWorldData; - worldBoundDiscreteMax = (int)(commonWorldData.getWorldBoundMin().x / commonWorldData.getDynamicInterpolationRatio() * 1.0f); - // this.clientTerrainManager = clientTerrainManager; - cells = new PhysicsDataCell[drawRadius * 2 + 1][drawRadius * 2 + 1]; - valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - updateable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - hasRequested = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1]; - needsPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1]; - hasPhysics = new boolean[physicsRadius * 2 + 1][physicsRadius * 2 + 1]; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[x][y] = false; - updateable[x][y] = false; - hasRequested[x][y] = false; - } - } - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = true; - hasPhysics[x][y] = false; - } - } - cellX = discreteX; - cellY = discreteY; + /** + * DrawCellManager constructor + * @param commonWorldData The common world data + * @param clientTerrainManager The client terrain manager + * @param discreteX The initial discrete position X coordinate + * @param discreteY The initial discrete position Y coordinate + */ + public DataCellPhysicsManager(Realm realm, int discreteX, int discreteY, int discreteZ){ + worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f); + cells = new HashSet(); + invalid = new HashSet(); + updateable = new HashSet(); + hasRequested = new HashSet(); + + this.realm = realm; + + program = Globals.terrainShaderProgram; drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius(); drawStepdownInterval = Globals.userSettings.getGameplayPhysicsCellRadius(); @@ -103,538 +98,384 @@ public class DataCellPhysicsManager { } - public int getCellX(){ - return cellX; - } - - public int getCellY(){ - return cellY; - } - - public void setCellX(int x){ - cellX = x; - } - - public void setCellY(int y){ - cellY = y; - } - - public void setCell(Vector2i cellPos){ - cellX = cellPos.x; - cellY = cellPos.y; - } - - void updateInvalidCell(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < drawRadius * 2 + 1; y++){ - targetY = y; - if(!valid[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - - if(found){ - int currentCellX = cellX - drawRadius + targetX; - int currentCellY = cellY - drawRadius + targetY; +// void updateInvalidCell(){ +// if(invalid.size() > 0){ +// String targetKey = invalid.iterator().next(); +// invalid.remove(targetKey); +// Vector3i vector = getVectorFromKey(targetKey); +// int currentCellX = cellX - drawRadius + vector.x; +// int currentCellY = cellY - drawRadius + vector.y; +// int currentCellZ = cellZ - drawRadius + vector.z; - if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ - if(containsHeightmapAtDiscretePoint(currentCellX, currentCellY)){ - cells[targetX][targetY] = PhysicsDataCell.generateTerrainCell( - currentCellX, - currentCellY, - getHeightmapAtPoint(currentCellX, currentCellY), - getTextureMapAtPoint(currentCellX, currentCellY), - commonWorldData.getDynamicInterpolationRatio() - ); - valid[targetX][targetY] = true; - updateable[targetX][targetY] = false; - hasRequested[targetX][targetY] = false; - hasPhysics[targetX][targetY] = false; - needsPhysics[targetX][targetY] = true; -// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } - } else { - if(hasRequested[targetX][targetY] == false){ - //client should request macro values from server - Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkMessage(currentCellX, currentCellY)); - hasRequested[targetX][targetY] = true; - } - } - } else { - valid[targetX][targetY] = true; - updateable[targetX][targetY] = false; - hasRequested[targetX][targetY] = false; - hasPhysics[targetX][targetY] = false; - needsPhysics[targetX][targetY] = true; - } - } - } +// if( +// currentCellX >= 0 && +// currentCellX < Globals.clientWorldData.getWorldDiscreteSize() && +// currentCellY >= 0 && +// currentCellY < Globals.clientWorldData.getWorldDiscreteSize() && +// currentCellZ >= 0 && +// currentCellZ < Globals.clientWorldData.getWorldDiscreteSize() +// ){ +// if(containsChunkDataAtWorldPoint(currentCellX, currentCellY, currentCellZ)){ +// PhysicsDataCell cell = PhysicsDataCell.generateTerrainCell( +// realm, +// currentCellX, +// currentCellY, +// currentCellZ, +// Globals.serverTerrainManager.getChunk(currentCellX, currentCellY, currentCellZ) +// ); +// cell.generatePhysics(); +// cells.add(cell); +// keyCellMap.put(targetKey,cell); +// } else { +// if(!hasRequested.contains(targetKey)){ +// //client should request chunk data from terrain manager +// hasRequested.add(targetKey); +// } +// } +// } +// } +// } + + +// /** +// * Updates a cell that can be updated +// */ +// void updateCellPhysics(){ +// if(updateable.size() > 0){ +// String targetKey = updateable.iterator().next(); +// updateable.remove(targetKey); +// Vector3i vector = getVectorFromKey(targetKey); +// int currentCellX = cellX - drawRadius + vector.x; +// int currentCellY = cellY - drawRadius + vector.y; +// int currentCellZ = cellZ - drawRadius + vector.z; +// if( +// currentCellX >= 0 && +// currentCellX < Globals.clientWorldData.getWorldDiscreteSize() && +// currentCellY >= 0 && +// currentCellY < Globals.clientWorldData.getWorldDiscreteSize() && +// currentCellZ >= 0 && +// currentCellZ < Globals.clientWorldData.getWorldDiscreteSize() +// ){ +// // if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){ +// // needsPhysics[targetX][targetY] = true; +// // } +// // int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); +// // int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); +// // while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){ +// // stride = stride + 1; +// // } +// keyCellMap.get(targetKey).generatePhysics(); +// } +// } +// } + + +// public boolean containsInvalidCell(){ +// return invalid.size() > 0; +// } + +// public boolean containsUpdateableCell(){ +// return updateable.size() > 0; +// } + +// /** +// * If any cells need physics, generates physics for them +// */ +// // public void addPhysicsToCell(){ +// // if(needsPhysics.size() > 0){ +// // String targetKey = updateable.iterator().next(); +// // updateable.remove(targetKey); +// // Vector3i vector = getVectorFromKey(targetKey); +// // int currentCellX = cellX - drawRadius + vector.x; +// // int currentCellY = cellY - drawRadius + vector.y; +// // int currentCellZ = cellZ - drawRadius + vector.z; +// // if( +// // currentCellX >= 0 && +// // currentCellX < Globals.clientWorldData.getWorldDiscreteSize() && +// // currentCellY >= 0 && +// // currentCellY < Globals.clientWorldData.getWorldDiscreteSize() && +// // currentCellZ >= 0 && +// // currentCellZ < Globals.clientWorldData.getWorldDiscreteSize() +// // ){ +// // keyCellMap.get(targetKey).generatePhysics(); +// // } +// // needsPhysics.remove(targetKey); +// // } +// // } + + + +// public void shiftChunksNegX(){ +// //retire old graphics +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + drawRadius * 2, cellY + y, cellZ + z); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); - void updateCellModel(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < drawRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < drawRadius * 2 + 1; y++){ - targetY = y; - if(updateable[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX - drawRadius * 2, cellY + y, cellZ + z); +// invalid.add(cellKey); +// } +// } +// } + +// public void shiftChunksPosX(){ +// //retire old graphics +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX - drawRadius * 2, cellY + y, cellZ + z); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); + +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + drawRadius * 2, cellY + y, cellZ + z); +// invalid.add(cellKey); +// } +// } +// } + +// public void shiftChunksNegY(){ +// //retire old graphics +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + x, cellY + drawRadius * 2, cellZ + z); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); + +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + x, cellY - drawRadius * 2, cellZ + z); +// invalid.add(cellKey); +// } +// } +// } + +// public void shiftChunksPosY(){ +// //retire old graphics +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + x, cellY - drawRadius * 2, cellZ + z); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); + +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// String cellKey = getCellKey(cellX + x, cellY + drawRadius * 2, cellZ + z); +// invalid.add(cellKey); +// } +// } +// } + +// public void shiftChunksNegZ(){ +// //retire old graphics +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// String cellKey = getCellKey(cellX + x, cellY + y, cellZ + drawRadius * 2); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); + +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// String cellKey = getCellKey(cellX + x, cellY + y, cellZ - drawRadius * 2); +// invalid.add(cellKey); +// } +// } +// } + +// public void shiftChunksPosZ(){ +// //retire old graphics +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// String cellKey = getCellKey(cellX + x, cellY + y, cellZ - drawRadius * 2); +// PhysicsDataCell cell = keyCellMap.get(cellKey); +// cell.retireCell(); + +// invalid.remove(cellKey); +// } +// } +// //invalidate edge of draw array +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// String cellKey = getCellKey(cellX + x, cellY + y, cellZ + drawRadius * 2); +// invalid.add(cellKey); +// } +// } +// } + + +// public int transformRealSpaceToCellSpace(double input){ +// return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio()); +// } + +// /** +// * Clears the valid set and adds all keys to invalid set +// */ +// public void invalidateAllCells(){ +// for(int x = 0; x < drawRadius * 2 + 1; x++){ +// for(int y = 0; y < drawRadius * 2 + 1; y++){ +// for(int z = 0; z < drawRadius * 2 + 1; z++){ +// invalid.add(getCellKey(x, y, z)); +// } +// } +// } +// } + +// /** +// * Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly +// * @param oldPosition The position of the player entity on previous frame +// * @param newPosition The position of the player entity on current frame +// */ +// public void calculateDeltas(Vector3d oldPosition, Vector3d newPosition){ +// // if(transformRealSpaceToCellSpace(newPosition.x()) < transformRealSpaceToCellSpace(oldPosition.x())){ +// // shiftChunksNegX(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } else if(transformRealSpaceToCellSpace(newPosition.x()) > transformRealSpaceToCellSpace(oldPosition.x())){ +// // shiftChunksPosX(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } - if(found){ - int currentCellX = cellX - drawRadius + targetX; - int currentCellY = cellY - drawRadius + targetY; - if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ -// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } - int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); - int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); - while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){ - stride = stride + 1; - } - cells[targetX][targetY].generatePhysics(); - } - updateable[targetX][targetY] = false; - } - } - - - public boolean containsInvalidCell(){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - for(int x = 0;x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(!valid[x][y]){ - return true; - } - } - } -// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -// return cells[0][0] == null || cells[1][0] == null || cells[0][1] == null | cells[1][1] == null; -// } - return false; - } - - public boolean containsUpdateableCell(){ - for(int x = 0;x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(updateable[x][y] && this.generateDrawables){ - return true; - } - } - } - return false; - } - - public boolean containsPhysicsNeedingCell(){ - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - if(needsPhysics[x][y]){ - return true; - } - } - } - return false; - } - - public void addPhysicsToCell(){ - int targetX = 0; - int targetY = 0; - boolean found = false; - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - targetX = x; - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - targetY = y; -// System.out.println(x + " <=>w " + y); - if(needsPhysics[x][y]){ - found = true; - break; - } - } - if(found){ - break; - } - } - - if(found){ - int currentCellX = cellX - physicsRadius + targetX; - int currentCellY = cellY - physicsRadius + targetY; - if( - currentCellX >= 0 && - currentCellX < commonWorldData.getWorldDiscreteSize() && - currentCellY >= 0 && - currentCellY < commonWorldData.getWorldDiscreteSize() - ){ -// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){ -// needsPhysics[targetX][targetY] = true; -// } -// int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius); -// int stride = Math.min(clientWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue)); -// while(clientWorldData.getDynamicInterpolationRatio() % stride != 0){ -// stride = stride + 1; -// } -// if(cells[targetX][targetY + drawRadius] != null){ - // System.out.println(targetX + " - " + targetY); - cells[targetX + drawRadius - physicsRadius][targetY + drawRadius - physicsRadius].generatePhysics(); -// } else { -// System.out.println("Current cell is null: " + currentCellX + " - " + currentCellY); -// } - } - needsPhysics[targetX][targetY] = false; - hasPhysics[targetX][targetY] = true; - } - } - - - public void shiftChunksNegX(){ - //retire old graphics - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(cells[drawRadius * 2][y] != null){ - cells[drawRadius * 2][y].retireCell(); - } - } - //shift draw array - for(int x = drawRadius * 2; x > 0; x--){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - cells[x][y] = cells[x-1][y]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x-1][y]; - } - } - //invalidate edge of draw array - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[0][y] = false; - hasRequested[0][y] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = physicsRadius * 2; x > 0; x--){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = needsPhysics[x-1][y]; - hasPhysics[x][y] = hasPhysics[x-1][y]; - } - } - //invalidate edge of physics array - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[0][y] = true; - hasPhysics[0][y] = false; - } - } - - public void shiftChunksPosX(){ - //retire old graphics - for(int y = 0; y < drawRadius * 2 + 1; y++){ - if(cells[0][y] != null){ - cells[0][y].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - cells[x][y] = cells[x+1][y]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x+1][y]; - } - } - //invalidate edge of draw array - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[drawRadius * 2][y] = false; - hasRequested[drawRadius * 2][y] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2; x++){ - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[x][y] = needsPhysics[x+1][y]; - hasPhysics[x][y] = hasPhysics[x+1][y]; - } - } - //invalidate edge of physics array - for(int y = 0; y < physicsRadius * 2 + 1; y++){ - needsPhysics[physicsRadius * 2][y] = true; - hasPhysics[physicsRadius * 2][y] = false; - } - } - - public void shiftChunksNegY(){ - //retire cells - for(int x = 0; x < drawRadius * 2 + 1; x++){ - if(cells[x][drawRadius * 2] != null){ - cells[x][drawRadius * 2].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = drawRadius * 2; y > 0; y--){ - cells[x][y] = cells[x][y-1]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x][y-1]; - } - } - //invalidate edge of draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - valid[x][0] = false; - hasRequested[x][0] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][physicsRadius * 2]){ - if(cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][physicsRadius * 2 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = physicsRadius * 2; y > 0; y--){ - needsPhysics[x][y] = needsPhysics[x][y-1]; - hasPhysics[x][y] = hasPhysics[x][y-1]; - } - } - //invalidate edge of physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - needsPhysics[x][0] = true; - hasPhysics[x][0] = false; - } - } - - public void shiftChunksPosY(){ - //retire old graphics - for(int x = 0; x < drawRadius * 2 + 1; x++){ - if(cells[x][0] != null){ - cells[x][0].retireCell(); - } - } - //shift draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2; y++){ - cells[x][y] = cells[x][y+1]; - updateable[x][y] = true; - hasRequested[x][y] = hasRequested[x][y+1]; - } - } - //invalidate edge of draw array - for(int x = 0; x < drawRadius * 2 + 1; x++){ - valid[x][drawRadius * 2] = false; - hasRequested[x][drawRadius * 2] = false; - } - //retire physics of cells - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - if(hasPhysics[x][0]){ - if(cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius] != null){ - cells[x + drawRadius - physicsRadius][0 + drawRadius - physicsRadius].destroyPhysics(); - } - } - } - //shift physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - for(int y = 0; y < physicsRadius * 2; y++){ - needsPhysics[x][y] = needsPhysics[x][y+1]; - hasPhysics[x][y] = hasPhysics[x][y+1]; - } - } - //invalidate edge of physics array - for(int x = 0; x < physicsRadius * 2 + 1; x++){ - needsPhysics[x][physicsRadius * 2] = true; - hasPhysics[x][physicsRadius * 2] = false; - } - } - - - public int transformRealSpaceToCellSpace(double input){ - return (int)(input / commonWorldData.getDynamicInterpolationRatio()); - } - - - public void invalidateAllCells(){ - for(int x = 0; x < drawRadius * 2 + 1; x++){ - for(int y = 0; y < drawRadius * 2 + 1; y++){ - valid[x][y] = false; - } - } - } - - public void calculateDeltas(Vector3d oldPosition, Vector3d newPosition){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - if(transformRealSpaceToCellSpace(newPosition.x()) < transformRealSpaceToCellSpace(oldPosition.x())){ - shiftChunksNegX(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } else if(transformRealSpaceToCellSpace(newPosition.x()) > transformRealSpaceToCellSpace(oldPosition.x())){ - shiftChunksPosX(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } - - if(transformRealSpaceToCellSpace(newPosition.z()) < transformRealSpaceToCellSpace(oldPosition.z())){ - shiftChunksNegY(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } else if(transformRealSpaceToCellSpace(newPosition.z()) > transformRealSpaceToCellSpace(oldPosition.z())){ - shiftChunksPosY(); - setCellX(transformRealSpaceToCellSpace(newPosition.x())); - setCellY(transformRealSpaceToCellSpace(newPosition.z())); - } -// } - } - - public void update(){ - if(update){ -// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ - if(containsInvalidCell()){ - updateInvalidCell(); - } else if(containsUpdateableCell()){ - updateCellModel(); - } else if(containsPhysicsNeedingCell()){ - addPhysicsToCell(); - } - } -// } else if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -// if(cells[0][0] == null){ -// int arenaChunkWidth = 100; -// cells[0][0] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 0, -// 0, -// arenaChunkWidth, -// program -// ); -// cells[0][0].generateDrawableEntity(1); -// } else if(cells[0][1] == null){ -// int arenaChunkWidth = 100; -// cells[0][1] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 0, -// 1, -// arenaChunkWidth, -// program -// ); -// cells[0][1].generateDrawableEntity(1); -// } else if(cells[1][0] == null){ -// int arenaChunkWidth = 100; -// cells[1][0] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 1, -// 0, -// arenaChunkWidth, -// program -// ); -// cells[1][0].generateDrawableEntity(1); -// } else if(cells[1][1] == null){ -// int arenaChunkWidth = 100; -// cells[1][1] = new DrawCell( -// new float[arenaChunkWidth + 1][arenaChunkWidth + 1], -// arenaChunkWidth + 1, -// 1, -// 1, -// arenaChunkWidth, -// program -// ); -// cells[1][1].generateDrawableEntity(1); -// } -// } - } - -// public float getElevationAtRealPoint(float realPointX, float realPointY){ -//// if(DRAW_CELL_MANAGER_FLAG_UPDATE_DYNAMIC_TERRAIN){ -// return terrainManager.getHeightAtPosition(realPointX, realPointY); -//// } -//// if(DRAW_CELL_MANAGER_FLAG_GENERATE_ARENA){ -//// return 0; -//// } -//// return 0; -// } - - - public boolean canValidateCell(){ - boolean rVal = false; - return rVal; - } - - public boolean coordsInPhysicsSpace(int worldX, int worldY){ - return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius; - } +// // if(transformRealSpaceToCellSpace(newPosition.y()) < transformRealSpaceToCellSpace(oldPosition.y())){ +// // shiftChunksNegY(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } else if(transformRealSpaceToCellSpace(newPosition.y()) > transformRealSpaceToCellSpace(oldPosition.y())){ +// // shiftChunksPosY(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } - public void setGenerateDrawables(boolean generate){ - this.generateDrawables = generate; - } +// // if(transformRealSpaceToCellSpace(newPosition.z()) < transformRealSpaceToCellSpace(oldPosition.z())){ +// // shiftChunksNegZ(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } else if(transformRealSpaceToCellSpace(newPosition.z()) > transformRealSpaceToCellSpace(oldPosition.z())){ +// // shiftChunksPosZ(); +// // setCellX(transformRealSpaceToCellSpace(newPosition.x())); +// // setCellY(transformRealSpaceToCellSpace(newPosition.y())); +// // setCellZ(transformRealSpaceToCellSpace(newPosition.z())); +// // } +// } + +// /** +// * Updates cells that need updating in this manager +// */ +// public void update(){ +// if(update){ +// if(containsInvalidCell()){ +// updateInvalidCell(); +// } else if(containsUpdateableCell()){ +// updateCellPhysics(); +// } +// } +// } + +// public boolean coordsInPhysicsSpace(int worldX, int worldY){ +// return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius; +// } - boolean containsHeightmapAtDiscretePoint(int currentCellX, int currentCellY){ - if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.containsHeightmapAtDiscretePoint(currentCellX, currentCellY); - } - return true; - } +// public void setGenerateDrawables(boolean generate){ +// this.generateDrawables = generate; +// } - float[][] getHeightmapAtPoint(int currentCellX, int currentCellY){ - if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY); - } - return Globals.serverTerrainManager.getChunk(currentCellX, currentCellY).getHeightMap(); - } +// boolean containsChunkDataAtWorldPoint(int currentCellX, int currentCellY, int currentCellZ){ +// if(Globals.clientTerrainManager != null){ +// return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(currentCellX, currentCellY, currentCellZ); +// } +// return true; +// } - float[][] getTextureMapAtPoint(int currentCellX, int currentCellY){ - if(Globals.clientTerrainManager != null){ - return Globals.clientTerrainManager.getTextureMapAtPoint(currentCellX,currentCellY); - } else { - //hacky fix to +2 to this, I think the interpolation ratio was different for server/client data - //now that we're merging/ambiguous within this class, it's out of bounds-ing unless I +2 - //TODO: investigate - float[][] rVal = new float[commonWorldData.getDynamicInterpolationRatio() + 2][commonWorldData.getDynamicInterpolationRatio() + 2]; - rVal[1][1] = 1; - rVal[2][1] = 1; - rVal[3][1] = 1; - rVal[4][1] = 1; - rVal[5][1] = 1; - rVal[5][2] = 1; - rVal[6][1] = 1; - rVal[6][2] = 1; - return rVal; - } - } +// /** +// * Gets the chunk data at a given point +// * @param currentCellX The x coord +// * @param currentCellY The y coord +// * @param currentCellZ The z coord +// * @return The chunk data at the specified points +// */ +// ChunkData getChunkDataAtPoint(int currentCellX, int currentCellY, int currentCellZ){ +// return Globals.clientTerrainManager.getChunkDataAtWorldPoint(currentCellX, currentCellY, currentCellZ); +// } + +// // float[][] getHeightmapAtPoint(int currentCellX, int currentCellY, int currentCellZ){ +// // if(Globals.clientTerrainManager != null){ +// // return Globals.clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY, currentCellZ); +// // } +// // return Globals.serverTerrainManager.getChunk(currentCellX, currentCellY).getHeightMap(); +// // } + +// // float[][] getTextureMapAtPoint(int currentCellX, int currentCellY){ +// // if(Globals.clientTerrainManager != null){ +// // return Globals.clientTerrainManager.getTextureMapAtPoint(currentCellX,currentCellY); +// // } else { +// // //hacky fix to +2 to this, I think the interpolation ratio was different for server/client data +// // //now that we're merging/ambiguous within this class, it's out of bounds-ing unless I +2 +// // //TODO: investigate +// // float[][] rVal = new float[commonWorldData.getDynamicInterpolationRatio() + 2][commonWorldData.getDynamicInterpolationRatio() + 2]; +// // rVal[1][1] = 1; +// // rVal[2][1] = 1; +// // rVal[3][1] = 1; +// // rVal[4][1] = 1; +// // rVal[5][1] = 1; +// // rVal[5][2] = 1; +// // rVal[6][1] = 1; +// // rVal[6][2] = 1; +// // return rVal; +// // } +// // } + +// /** +// * Gets a unique key for the cell +// * @param worldX The world position x component of the cell +// * @param worldY The world position y component of the cell +// * @param worldZ The world position z component of the cell +// * @return The key +// */ +// private String getCellKey(int worldX, int worldY, int worldZ){ +// return worldX + "_" + worldY + "_" + worldZ; +// } + +// /** +// * Parses a vector3i from the cell key +// * @param key The cell key +// * @return The vector3i containing the components of the cell key +// */ +// private Vector3i getVectorFromKey(String key){ +// String[] keyComponents = key.split("_"); +// return new Vector3i(Integer.parseInt(keyComponents[0]),Integer.parseInt(keyComponents[1]),Integer.parseInt(keyComponents[2])); +// } + + + +// public + } diff --git a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java index 1952278c..eb6f41c4 100644 --- a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java +++ b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java @@ -1,5 +1,6 @@ package electrosphere.server.datacell.physics; +import electrosphere.client.terrain.cache.ChunkData; import electrosphere.collision.dispatch.CollisionObject; import electrosphere.dynamics.RigidBody; import electrosphere.engine.Globals; @@ -7,6 +8,8 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; +import electrosphere.entity.ServerEntityUtils; +import electrosphere.entity.types.terrain.TerrainChunk; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.terrain.processing.TerrainInterpolator; @@ -19,30 +22,33 @@ import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.actor.ActorTextureMask; import electrosphere.renderer.texture.Texture; import electrosphere.server.datacell.Realm; +import electrosphere.server.terrain.manager.ServerTerrainManager; +import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.util.Utilities; import java.util.LinkedList; import java.util.List; import org.joml.Quaternionf; +import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector3i; /** * * @author satellite */ public class PhysicsDataCell { - int cellX; - int cellZ; + + Vector3i worldPos; - float[][] heightmap; - float[][] texturemap; - - int dynamicInterpolationRatio; + ServerTerrainChunk chunkData; Entity physicsEntity; CollisionObject physicsObject; + + Realm realm; PhysicsDataCell(){ @@ -50,18 +56,15 @@ public class PhysicsDataCell { } - public static PhysicsDataCell generateTerrainCell( - int cellX, - int cellZ, - float[][] heightmap, - float[][] texturemap, - int dynamicInterpolationRatio + public static PhysicsDataCell createPhysicsCell( + Realm realm, + Vector3i worldPos, + ServerTerrainChunk chunkData ){ PhysicsDataCell rVal = new PhysicsDataCell(); - rVal.cellX = cellX; - rVal.cellZ = cellZ; - rVal.dynamicInterpolationRatio = dynamicInterpolationRatio; - rVal.heightmap = heightmap; + rVal.realm = realm; + rVal.worldPos = worldPos; + rVal.chunkData = chunkData; return rVal; } @@ -72,17 +75,25 @@ public class PhysicsDataCell { EntityUtils.cleanUpEntity(physicsEntity); } + /** + * Generates the physics entity for this chunk + */ public void generatePhysics(){ //if the entity hasn't already been created for some reason, need to create it if(physicsEntity == null){ - physicsEntity = EntityCreationUtils.createClientSpatialEntity(); + Vector3d position = new Vector3d( + worldPos.x * ServerTerrainChunk.CHUNK_DIMENSION, + worldPos.y * ServerTerrainChunk.CHUNK_DIMENSION, + worldPos.z * ServerTerrainChunk.CHUNK_DIMENSION + ); + physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, position, chunkData.getWeights(), chunkData.getValues()); physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); - EntityUtils.getPosition(physicsEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellZ * dynamicInterpolationRatio)); + ServerEntityUtils.repositionEntity(physicsEntity, position); } - //then actually perform the attach - physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); - Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); - realm.getCollisionEngine().registerPhysicsEntity(physicsEntity); + // //then actually perform the attach + // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); + // Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); + // realm.getCollisionEngine().registerPhysicsEntity(physicsEntity); } public void destroyPhysics(){ diff --git a/src/main/java/electrosphere/server/pathfinding/NavMeshUtils.java b/src/main/java/electrosphere/server/pathfinding/NavMeshUtils.java index 6d347fda..427487fb 100644 --- a/src/main/java/electrosphere/server/pathfinding/NavMeshUtils.java +++ b/src/main/java/electrosphere/server/pathfinding/NavMeshUtils.java @@ -23,7 +23,7 @@ public class NavMeshUtils { static float NAVMESH_PHASE_TWO_DISPARITY_TOLERANCE = 0.5f; public static NavMesh createMeshFromChunk(ServerTerrainChunk chunk, NavBlocker navBlocker){ NavMesh rVal = Globals.navMeshManager.createNavMesh(); - float[][] heightMap = chunk.getHeightMap(); + float[][] heightMap = chunk.getWeights()[0]; boolean[][] navMeshGeneratorMask = navBlocker.getHeightfieldBlocker(); List firstPassBoxes = new LinkedList(); int numInCurrent = 0; diff --git a/src/main/java/electrosphere/server/pathfinding/blocker/NavTerrainBlockerCache.java b/src/main/java/electrosphere/server/pathfinding/blocker/NavTerrainBlockerCache.java index a770af36..2f7cc57c 100644 --- a/src/main/java/electrosphere/server/pathfinding/blocker/NavTerrainBlockerCache.java +++ b/src/main/java/electrosphere/server/pathfinding/blocker/NavTerrainBlockerCache.java @@ -22,7 +22,7 @@ public class NavTerrainBlockerCache { public String getKey(int x, int y){ - return x + "-" + y; + return x + "_" + y; } public NavBlocker getBlocker(int x, int y){ diff --git a/src/main/java/electrosphere/server/saves/SaveUtils.java b/src/main/java/electrosphere/server/saves/SaveUtils.java index 4949830c..e35b35cf 100644 --- a/src/main/java/electrosphere/server/saves/SaveUtils.java +++ b/src/main/java/electrosphere/server/saves/SaveUtils.java @@ -106,7 +106,7 @@ public class SaveUtils { } public static boolean loadTerrainAndCreateWorldData(String currentSaveName){ - Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0); + Globals.serverTerrainManager = new ServerTerrainManager(2000,50,ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO,0.0f,0); SaveUtils.loadTerrainAndDB(currentSaveName); Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); Globals.realmManager.createGriddedRealm(Globals.serverWorldData); diff --git a/src/main/java/electrosphere/server/simulation/MacroSimulation.java b/src/main/java/electrosphere/server/simulation/MacroSimulation.java index dfa2b936..3f474fc6 100644 --- a/src/main/java/electrosphere/server/simulation/MacroSimulation.java +++ b/src/main/java/electrosphere/server/simulation/MacroSimulation.java @@ -105,9 +105,9 @@ public class MacroSimulation { } } if(placementPos != null){ - Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); - CharacterUtils.addShelter(chara, placedStructure); - VirtualStructureUtils.addResident(placedStructure, chara); + // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); + // CharacterUtils.addShelter(chara, placedStructure); + // VirtualStructureUtils.addResident(placedStructure, chara); } } } diff --git a/src/main/java/electrosphere/server/simulation/MicroSimulation.java b/src/main/java/electrosphere/server/simulation/MicroSimulation.java index 91496344..f13c6f7d 100644 --- a/src/main/java/electrosphere/server/simulation/MicroSimulation.java +++ b/src/main/java/electrosphere/server/simulation/MicroSimulation.java @@ -47,62 +47,64 @@ public class MicroSimulation { } public void simulate(ServerDataCell dataCell, HitboxManager hitboxManager){ - //update dynamic entity positions calculated by bullet -// Globals.collisionEngine.updateDynamicObjectTransforms(); - //list dynamic object positions -// Globals.collisionEngine.listBodyPositions(); - //simulate ai - Globals.aiManager.simulate(); - //update actor animations - for(Entity currentEntity : dataCell.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //increment animations - if(currentActor.isPlayingAnimation()){ - currentActor.incrementAnimationTime(Main.deltaFrames / Main.targetFrameRate); + if(dataCell.isReady()){ + //update dynamic entity positions calculated by bullet + // Globals.collisionEngine.updateDynamicObjectTransforms(); + //list dynamic object positions + // Globals.collisionEngine.listBodyPositions(); + //simulate ai + Globals.aiManager.simulate(); + //update actor animations + for(Entity currentEntity : dataCell.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //increment animations + if(currentActor.isPlayingAnimation()){ + currentActor.incrementAnimationTime(Main.deltaFrames / Main.targetFrameRate); + } } - } - //make items play idle animation - for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){ - ItemUtils.updateItemActorAnimation(item); - } - //particle state updates - for(Entity particle : dataCell.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){ - // ParticleTree tree = ParticleUtils.getParticleTree(particle); - // tree.simulate(Main.deltaFrames); - ParticleUtils.makeParticleBillboardFaceCamera(particle); - } - //update attached entity positions - AttachUtils.serverUpdateAttachedEntityPositions(dataCell); - //update hitbox positions - for(Entity currentHitbox : hitboxManager.getAllHitboxes()){ - HitboxUtils.serverUpdatePosition(currentHitbox); - } - //collide hitboxes - for(Entity currentHitbox : hitboxManager.getAllHitboxes()){ - if(isReady){ - HitboxUtils.serverCollideEntities(currentHitbox); + //make items play idle animation + for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){ + ItemUtils.updateItemActorAnimation(item); + } + //particle state updates + for(Entity particle : dataCell.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){ + // ParticleTree tree = ParticleUtils.getParticleTree(particle); + // tree.simulate(Main.deltaFrames); + ParticleUtils.makeParticleBillboardFaceCamera(particle); + } + //update attached entity positions + AttachUtils.serverUpdateAttachedEntityPositions(dataCell); + //update hitbox positions + for(Entity currentHitbox : hitboxManager.getAllHitboxes()){ + HitboxUtils.serverUpdatePosition(currentHitbox); + } + //collide hitboxes + for(Entity currentHitbox : hitboxManager.getAllHitboxes()){ + if(isReady){ + HitboxUtils.serverCollideEntities(currentHitbox); + } + } + //tally collidables and offset position accordingly + // for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){ + // CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable); + // tree.simulate(Main.deltaFrames); + // } + //targeting crosshair + if(Globals.RUN_CLIENT){ + Crosshair.checkTargetable(); + Crosshair.updateTargetCrosshairPosition(); + } + //simulate behavior trees + dataCell.getScene().simulateBehaviorTrees(Main.deltaFrames); + //sum collidable impulses + for(Entity collidable : dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){ + ServerCollidableTree.getServerCollidableTree(collidable).simulate(Main.deltaFrames); + } + //delete all client side entities that aren't in visible chunks + if(Globals.clientEntityCullingManager != null){ + Globals.clientEntityCullingManager.clearOutOfBoundsEntities(); } - } - //tally collidables and offset position accordingly - // for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){ - // CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable); - // tree.simulate(Main.deltaFrames); - // } - //targeting crosshair - if(Globals.RUN_CLIENT){ - Crosshair.checkTargetable(); - Crosshair.updateTargetCrosshairPosition(); - } - //simulate behavior trees - dataCell.getScene().simulateBehaviorTrees(Main.deltaFrames); - //sum collidable impulses - for(Entity collidable : dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){ - ServerCollidableTree.getServerCollidableTree(collidable).simulate(Main.deltaFrames); - } - //delete all client side entities that aren't in visible chunks - if(Globals.clientEntityCullingManager != null){ - Globals.clientEntityCullingManager.clearOutOfBoundsEntities(); } } diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java index 0ea3b837..9ce9b163 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java @@ -6,29 +6,58 @@ import java.util.List; import electrosphere.server.terrain.models.TerrainModification; /** - * - * @author amaterasu + * Is a single subchunk of terrain on the server */ public class ServerTerrainChunk { - int worldX, worldY; - List modifications = new LinkedList(); - float[][] heightMap; - float[][] macroValues; - long[][] randomizer; - public ServerTerrainChunk(int worldX, int worldY, float[][] heightMap, float[][] macroValues, long[][] randomizer) { + //all chunks are 16x16x16 + public static final int CHUNK_DIMENSION = 16; + + int worldX, worldY, worldZ; + List modifications = new LinkedList(); + float[][][] weights; + int[][][] values; + + public ServerTerrainChunk(int worldX, int worldY, int worldZ, float[][][] weights, int[][][] values) { this.worldX = worldX; this.worldY = worldY; - this.heightMap = heightMap; - this.macroValues = macroValues; - this.randomizer = randomizer; + this.worldZ = worldZ; + this.weights = weights; + this.values = values; } - public static ServerTerrainChunk getArenaChunk(int width, int x, int y){ - float[][] macroValues = new float[5][5]; - long[][] randomizer = new long[5][5]; - float[][] heightmap = new float[width + 1][width + 1]; - ServerTerrainChunk rVal = new ServerTerrainChunk(x, y, heightmap, macroValues, randomizer); + public static ServerTerrainChunk getArenaChunk(int worldX, int worldY, int worldZ){ + float[][][] weights = new float[CHUNK_DIMENSION][CHUNK_DIMENSION][CHUNK_DIMENSION]; + int[][][] values = new int[CHUNK_DIMENSION][CHUNK_DIMENSION][CHUNK_DIMENSION]; + for(int inc = 0; inc < CHUNK_DIMENSION; inc++){ + for(int weightX = 0; weightX < CHUNK_DIMENSION; weightX++){ + for(int weightZ = 0; weightZ < CHUNK_DIMENSION; weightZ++){ + weights[weightX][inc][weightZ] = -1; + values[weightX][inc][weightZ] = 0; + } + } + } + if(worldY < 1){ + for(int weightX = 0; weightX < CHUNK_DIMENSION; weightX++){ + for(int weightZ = 0; weightZ < CHUNK_DIMENSION; weightZ++){ + weights[weightX][0][weightZ] = 0.1f; + values[weightX][0][weightZ] = 1; + } + } + } + // for(int weightX = 0; weightX < SUB_CHUNK_DIMENSION; weightX++){ + // for(int weightZ = 0; weightZ < SUB_CHUNK_DIMENSION; weightZ++){ + // weights[weightX][SUB_CHUNK_DIMENSION-1][weightZ] = 1; + // values[weightX][SUB_CHUNK_DIMENSION-1][weightZ] = 1; + // } + // } + // for(int weightX = 0; weightX < SUB_CHUNK_DIMENSION; weightX++){ + // for(int weightZ = 0; weightZ < SUB_CHUNK_DIMENSION; weightZ++){ + // weights[SUB_CHUNK_DIMENSION-1][weightX][weightZ] = 1; + // values[SUB_CHUNK_DIMENSION-1][weightX][weightZ] = 1; + // } + // } + ServerTerrainChunk rVal = new ServerTerrainChunk(worldX, worldY, worldZ, weights, values); // rVal.addModification(new TerrainModification(x, y, 3, 3, 5)); return rVal; } @@ -41,24 +70,26 @@ public class ServerTerrainChunk { return worldY; } + public int getWorldZ() { + return worldZ; + } + public List getModifications() { return modifications; } - public float[][] getHeightMap() { - return heightMap; + public float[][][] getWeights() { + return weights; } - public float[][] getMacroValues() { - return macroValues; + public int[][][] getValues() { + return values; } - public long[][] getRandomizer() { - return randomizer; - } - public void addModification(TerrainModification modification){ modifications.add(modification); + values[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getValue(); + weights[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getWeight(); } diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java index c1bde2de..5ca41b3b 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java @@ -14,15 +14,21 @@ import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.joml.Vector3i; /** - * - * @author satellite + * Provides an interface for the server to query information about terrain */ public class ServerTerrainManager { + //the interpolation width of a server terrain manager is hard coded at the moment to make sure it's divisible by the sub chunk calculations + public static final int SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO = 128; //The size of the world in discrete units * must be multiple of 200 int worldSizeDiscrete; @@ -42,9 +48,14 @@ public class ServerTerrainManager { //Basic idea is we associate string that contains chunk x&y with elevation //While we incur a penalty with converting ints -> string, think this will //offset regenerating the array every time we want a new one - int cacheSize = 50; - Map elevationMapCache; - List elevationMapCacheContents; + int cacheSize = 500; + Map chunkCache; + List chunkCacheContents; + + //cache for the bicubic interpolated chunks + //don't need to interpolate each time a new chunk is created + //This should eventually be removed as terrain generation becomes more complicated than a heightmap + Map heightmapCache = new ConcurrentHashMap<>(); @@ -52,8 +63,8 @@ public class ServerTerrainManager { this.worldSizeDiscrete = worldSizeDiscrete; this.verticalInterpolationRatio = verticalInterpolationRatio; this.dynamicInterpolationRatio = dynamicInterpolationRatio; - this.elevationMapCache = new HashMap(); - this.elevationMapCacheContents = new ArrayList(); + this.chunkCache = new ConcurrentHashMap(); + this.chunkCacheContents = new CopyOnWriteArrayList(); this.interpolationRandomDampener = interpolationRandomDampener; this.seed = seed; } @@ -66,9 +77,9 @@ public class ServerTerrainManager { ServerTerrainManager rVal = new ServerTerrainManager(); rVal.worldSizeDiscrete = 2; rVal.verticalInterpolationRatio = 0; - rVal.dynamicInterpolationRatio = 100; - rVal.elevationMapCache = new HashMap(); - rVal.elevationMapCacheContents = new ArrayList(); + rVal.dynamicInterpolationRatio = SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO; + rVal.chunkCache = new ConcurrentHashMap(); + rVal.chunkCacheContents = new CopyOnWriteArrayList(); rVal.interpolationRandomDampener = 0.0f; return rVal; } @@ -139,41 +150,44 @@ public class ServerTerrainManager { // } // } - public double getHeightAtPosition(double x, double y){ + public double getHeightAtPosition(double x, double y, double z){ //get chunk coordinate space of input x,y - int chunkX = (int)Math.floor(x / dynamicInterpolationRatio); - int chunkY = (int)Math.floor(y / dynamicInterpolationRatio); - //get local coordinate space of input x,y - double localX = x - chunkX * dynamicInterpolationRatio; - double localY = y - chunkY * dynamicInterpolationRatio; - //get chunk elevation map - float[][] chunkElevationMap = getChunk(chunkX,chunkY).heightMap; - //floored variants of local values - int localXf = (int)Math.floor(localX); - int localYf = (int)Math.floor(localY); + // int chunkX = (int)Math.floor(x / dynamicInterpolationRatio); + // int chunkY = (int)Math.floor(y / dynamicInterpolationRatio); + // int chunkZ = (int)Math.floor(z / dynamicInterpolationRatio); + // //get local coordinate space of input x,y + // double localX = x - chunkX * dynamicInterpolationRatio; + // double localY = y - chunkY * dynamicInterpolationRatio; + // double localZ = z - chunkZ * dynamicInterpolationRatio; + // //get chunk elevation map + // float[][] chunkElevationMap = getChunk(chunkX,chunkY,chunkZ).heightMap; + // //floored variants of local values + // int localXf = (int)Math.floor(localX); + // int localYf = (int)Math.floor(localY); + // int localZf = (int)Math.floor(localZ); - /* - Average some inner value. + // /* + // Average some inner value. - 01 11 - 0.3 0.4 0.5 - 0.1 0.2 0.3 - 00 10 - */ - //interp elevation from map - float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0]; - float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0]; - float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1]; - float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1]; + // 01 11 + // 0.3 0.4 0.5 + // 0.1 0.2 0.3 + // 00 10 + // */ + // //interp elevation from map + // float elevation00 = chunkElevationMap[(int)localX+0][(int)localY+0]; + // float elevation10 = chunkElevationMap[(int)localX+1][(int)localY+0]; + // float elevation01 = chunkElevationMap[(int)localX+0][(int)localY+1]; + // float elevation11 = chunkElevationMap[(int)localX+1][(int)localY+1]; - double rVal = - (1-(localX-localXf))*(1-(localY-localYf)) * elevation00 + - ( (localX-localXf))*(1-(localY-localYf)) * elevation10 + - (1-(localX-localXf))*( (localY-localYf)) * elevation01 + - ( (localX-localXf))*( (localY-localYf)) * elevation11 - ; + // double rVal = + // (1-(localX-localXf))*(1-(localY-localYf)) * elevation00 + + // ( (localX-localXf))*(1-(localY-localYf)) * elevation10 + + // (1-(localX-localXf))*( (localY-localYf)) * elevation01 + + // ( (localX-localXf))*( (localY-localYf)) * elevation11 + // ; - return rVal; + return y; } public int getChunkWidth(){ @@ -250,82 +264,100 @@ public class ServerTerrainManager { return model; } - public String getKey(int x, int y){ - return x + "-" + y; + public String getKey(int worldX, int worldY, int worldZ){ + return worldX + "_" + worldY + "_" + worldZ; } - public ServerTerrainChunk getChunk(int x, int y){ + public ServerTerrainChunk getChunk(int worldX, int worldY, int worldZ){ if(model != null){ //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING - String key = getKey(x,y); + String key = getKey(worldX,worldY,worldZ); ServerTerrainChunk returnedChunk; - if(elevationMapCache.containsKey(key)){ - elevationMapCacheContents.remove(key); - elevationMapCacheContents.add(0, key); - returnedChunk = elevationMapCache.get(key); + if(chunkCache.containsKey(key)){ + chunkCacheContents.remove(key); + chunkCacheContents.add(0, key); + returnedChunk = chunkCache.get(key); return returnedChunk; } else { - float[][] macroValues = model.getRad5MacroValuesAtPosition(x, y); - long[][] randomizer = model.getRad5RandomizerValuesAtPosition(x, y); - float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk( - macroValues, - randomizer, - model.getDynamicInterpolationRatio(), - model.getRandomDampener() - ); - ModificationList modificationList = model.getModifications(x, y); - if(modificationList != null){ - for(TerrainModification modification : modificationList.getModifications()){ - heightmap = modification.applyToHeightfield(heightmap); + float[][] heightmap = getHeightmap(worldX, worldZ); + float[][][] weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + int[][][] values = new int[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + for(int weightX = 0; weightX < ServerTerrainChunk.CHUNK_DIMENSION; weightX++){ + for(int weightY = 0; weightY < ServerTerrainChunk.CHUNK_DIMENSION; weightY++){ + for(int weightZ = 0; weightZ < ServerTerrainChunk.CHUNK_DIMENSION; weightZ++){ + if(weightY < heightmap[ServerTerrainChunk.CHUNK_DIMENSION * worldX + weightX][ServerTerrainChunk.CHUNK_DIMENSION * worldZ + weightZ]){ + weights[weightX][weightY][weightZ] = 1; + values[weightX][weightY][weightZ] = 1; + } else { + weights[weightX][weightY][weightZ] = -1; + values[weightX][weightY][weightZ] = 0; + } + } } } - if(elevationMapCacheContents.size() > cacheSize){ - String oldChunk = elevationMapCacheContents.remove(elevationMapCacheContents.size() - 1); - elevationMapCache.remove(oldChunk); + // ModificationList modificationList = model.getModifications(x, y); + // if(modificationList != null){ + // for(TerrainModification modification : modificationList.getModifications()){ + // heightmap = modification.applyToHeightfield(heightmap); + // } + // } + if(chunkCacheContents.size() > cacheSize){ + String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1); + chunkCache.remove(oldChunk); } - returnedChunk = new ServerTerrainChunk(x, y, heightmap, macroValues, randomizer); - elevationMapCache.put(key, returnedChunk); - elevationMapCacheContents.add(key); + returnedChunk = new ServerTerrainChunk(worldX, worldY, worldZ, weights, values); + chunkCache.put(key, returnedChunk); + chunkCacheContents.add(key); return returnedChunk; } } else { //THIS FIRES IF THERE IS AN ARENA WORLD RUNNING - String key = getKey(x,y); + String key = getKey(worldX, worldY, worldZ); ServerTerrainChunk returnedChunk; - if(elevationMapCache.containsKey(key)){ - elevationMapCacheContents.remove(key); - elevationMapCacheContents.add(0, key); - returnedChunk = elevationMapCache.get(key); + if(chunkCache.containsKey(key)){ + chunkCacheContents.remove("" + key); + chunkCacheContents.add(0, key); + returnedChunk = chunkCache.get(key); return returnedChunk; } else { - returnedChunk = ServerTerrainChunk.getArenaChunk(dynamicInterpolationRatio + 1, x, y); - elevationMapCache.put(key, returnedChunk); - elevationMapCacheContents.add(key); + returnedChunk = ServerTerrainChunk.getArenaChunk(worldX, worldY, worldZ); + chunkCache.put(key, returnedChunk); + chunkCacheContents.add(key); return returnedChunk; } } } - - public void deformTerrainAtLocationToValue(int worldX, int worldY, int locationX, int locationY, float value){ - System.out.println("Add modification at " + worldX + "," + worldY + " subloc " + locationX + "," + locationY); - TerrainModification modification = new TerrainModification(worldX,worldY,locationX,locationY,value); - model.addModification(modification); - String key = getKey(worldX,worldY); - if(elevationMapCache.containsKey(key)){ - ServerTerrainChunk chunk = elevationMapCache.get(key); - chunk.addModification(modification); - chunk.heightMap = modification.applyToHeightfield(chunk.heightMap); + + private float[][] getHeightmap(int worldX, int worldZ){ + String key = worldX + "_" + worldZ; + if(heightmapCache.containsKey(key)){ + return heightmapCache.get(key); + } else { + float[][] macroValues = model.getRad5MacroValuesAtPosition(worldX, worldZ); + long[][] randomizer = model.getRad5RandomizerValuesAtPosition(worldX, worldZ); + float[][] heightmap = TerrainInterpolator.getBicubicInterpolatedChunk( + macroValues, + randomizer, + model.getDynamicInterpolationRatio(), + model.getRandomDampener() + ); + heightmapCache.put(key,heightmap); + return heightmap; } - if(locationX == 0){ - if(locationY == 0){ - deformTerrainAtLocationToValue(worldX - 1, worldY - 1, Globals.serverTerrainManager.dynamicInterpolationRatio, Globals.serverTerrainManager.dynamicInterpolationRatio, value); - deformTerrainAtLocationToValue(worldX - 1, worldY, Globals.serverTerrainManager.dynamicInterpolationRatio, locationY, value); - deformTerrainAtLocationToValue(worldX, worldY - 1, locationX, Globals.serverTerrainManager.dynamicInterpolationRatio, value); - } else { - deformTerrainAtLocationToValue(worldX - 1, worldY, Globals.serverTerrainManager.dynamicInterpolationRatio, locationY, value); - } - } else if(locationY == 0){ - deformTerrainAtLocationToValue(worldX, worldY - 1, locationX, Globals.serverTerrainManager.dynamicInterpolationRatio, value); + } + + public void deformTerrainAtLocationToValue( + Vector3i worldPos, + Vector3i subChunkPos, + Vector3i voxelPos, + float weight, int value){ + System.out.println("Add modification at " + worldPos.x + "," + worldPos.z + " subloc " + voxelPos.x + "," + voxelPos.z); + TerrainModification modification = new TerrainModification(worldPos,subChunkPos,voxelPos,weight,value); + model.addModification(modification); + String key = getKey(worldPos.x,worldPos.y,worldPos.z); + if(chunkCache.containsKey(key)){ + ServerTerrainChunk chunk = chunkCache.get(key); + chunk.addModification(modification); } } diff --git a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java index ee1b2cd2..fad22b2c 100644 --- a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java +++ b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java @@ -372,12 +372,12 @@ public class TerrainModel { return realOceanThreshold; } - public String getModificationKey(int x, int y){ - return x + "-" + y; + public String getModificationKey(int x, int y, int z){ + return x + "_" + y + "_" + z; } public void addModification(TerrainModification modification){ - String key = getModificationKey(modification.worldX,modification.worldY); + String key = getModificationKey(modification.getWorldPos().x,modification.getWorldPos().y,modification.getWorldPos().z); ModificationList list; if(!modifications.containsKey(key)){ list = new ModificationList(); @@ -388,13 +388,13 @@ public class TerrainModel { list.addModification(modification); } - public boolean containsModificationsAtCoord(int worldX, int worldY){ - return modifications.containsKey(getModificationKey(worldX, worldY)); + public boolean containsModificationsAtCoord(int worldX, int worldY, int worldZ){ + return modifications.containsKey(getModificationKey(worldX, worldY, worldZ)); } - public ModificationList getModifications(int worldX, int worldY){ + public ModificationList getModifications(int worldX, int worldY, int worldZ){ // System.out.println("Got modifications at " + worldX + " " + worldY); - return modifications.get(getModificationKey(worldX, worldY)); + return modifications.get(getModificationKey(worldX, worldY, worldZ)); } } diff --git a/src/main/java/electrosphere/server/terrain/models/TerrainModification.java b/src/main/java/electrosphere/server/terrain/models/TerrainModification.java index 51841a92..dea89e0e 100644 --- a/src/main/java/electrosphere/server/terrain/models/TerrainModification.java +++ b/src/main/java/electrosphere/server/terrain/models/TerrainModification.java @@ -1,48 +1,47 @@ package electrosphere.server.terrain.models; +import org.joml.Vector3i; + +import electrosphere.server.terrain.manager.ServerTerrainChunk; + /** * * @author amaterasu */ public class TerrainModification { - int worldX; - int worldY; - int locationX; - int locationY; - float value; + Vector3i worldPos; + Vector3i subChunkPos; + Vector3i voxelPos; + float weight; + int value; - public TerrainModification(int worldX, int worldY, int locationX, int locationY, float value) { - this.worldX = worldX; - this.worldY = worldY; - this.locationX = locationX; - this.locationY = locationY; + public TerrainModification(Vector3i worldPos, Vector3i subChunkPos, Vector3i voxelPos, float weight, int value) { + this.worldPos = worldPos; + this.subChunkPos = subChunkPos; + this.voxelPos = voxelPos; + this.weight = weight; this.value = value; } - public int getWorldX() { - return worldX; + public Vector3i getWorldPos() { + return worldPos; } - public int getWorldY() { - return worldY; + public Vector3i getSubChunkPos() { + return subChunkPos; } - public int getLocationX() { - return locationX; + public Vector3i getVoxelPos() { + return voxelPos; } - public int getLocationY() { - return locationY; + public float getWeight(){ + return weight; } - public float getValue() { + public int getValue() { return value; } - public float[][] applyToHeightfield(float[][] heightfield){ - heightfield[locationX][locationY] = value; - return heightfield; - } - }