server side terrain management refactoring
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
1b1876643d
commit
3777a9a37c
@ -1144,6 +1144,8 @@ Fix script entity spawn utils not spawning on max cursor distance
|
||||
Block mesh generation
|
||||
Add asset manager support for queueing models asynchronously w/ promised path
|
||||
Add promised path support to queued textures
|
||||
Code formatting on queued asset classes
|
||||
Refactoring server side of terrain management
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -22,6 +22,11 @@ public class BlockChunkData {
|
||||
*/
|
||||
public static final float BLOCK_SIZE_MULTIPLIER = 1.0f / BLOCKS_PER_UNIT_DISTANCE;
|
||||
|
||||
/**
|
||||
* Set if this chunk is not homogenous
|
||||
*/
|
||||
public static final short NOT_HOMOGENOUS = -1;
|
||||
|
||||
|
||||
/**
|
||||
* The type of block at a given position
|
||||
@ -34,6 +39,11 @@ public class BlockChunkData {
|
||||
*/
|
||||
short[] metadata;
|
||||
|
||||
/**
|
||||
* If this block chunk is homogenously a single value, it will be the value of this short. Otherwise is
|
||||
*/
|
||||
short homogenousValue = NOT_HOMOGENOUS;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@ -41,7 +51,7 @@ public class BlockChunkData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Allocates a BlockChunkData with empty values
|
||||
*/
|
||||
public static BlockChunkData allocate(){
|
||||
BlockChunkData rVal = new BlockChunkData();
|
||||
@ -50,6 +60,15 @@ public class BlockChunkData {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a BlockChunkData with a homogenous value
|
||||
*/
|
||||
public static BlockChunkData allocate(short homogenousValue){
|
||||
BlockChunkData rVal = new BlockChunkData();
|
||||
rVal.homogenousValue = homogenousValue;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type data for the chunk
|
||||
* @return The type data
|
||||
@ -147,5 +166,12 @@ public class BlockChunkData {
|
||||
return empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this block chunk is homogenous or not
|
||||
* @return true if it is homogenous, false otherwise
|
||||
*/
|
||||
public boolean isHomogenous(){
|
||||
return this.homogenousValue != NOT_HOMOGENOUS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,7 +10,9 @@ import electrosphere.renderer.model.Model;
|
||||
*/
|
||||
public class QueuedModel implements QueuedAsset<Model> {
|
||||
|
||||
//true if loaded
|
||||
/**
|
||||
* true if loaded
|
||||
*/
|
||||
boolean hasLoaded = false;
|
||||
|
||||
/**
|
||||
|
||||
@ -11,13 +11,19 @@ import electrosphere.renderer.texture.Texture;
|
||||
*/
|
||||
public class QueuedTexture implements QueuedAsset<Texture> {
|
||||
|
||||
//true if loaded
|
||||
/**
|
||||
* True if loaded
|
||||
*/
|
||||
boolean hasLoaded = false;
|
||||
|
||||
//the resulting texture object
|
||||
/**
|
||||
* The resuling texture object
|
||||
*/
|
||||
Texture texture = null;
|
||||
|
||||
//data to be loaded
|
||||
/**
|
||||
* The data to be loaded
|
||||
*/
|
||||
BufferedImage data;
|
||||
|
||||
/**
|
||||
|
||||
@ -278,21 +278,21 @@ public class ClientLoading {
|
||||
EntityUtils.getScale(Globals.playerCursor).set(0.2f);
|
||||
|
||||
//block test
|
||||
// Entity blockEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
// BlockChunkData blockChunkData = BlockChunkData.allocate();
|
||||
// blockChunkData.setType(0, 0, 0, 1);
|
||||
// blockChunkData.setType(1, 0, 0, 1);
|
||||
// blockChunkData.setType(0, 1, 0, 1);
|
||||
// blockChunkData.setType(1, 1, 0, 1);
|
||||
// blockChunkData.setType(0, 0, 1, 1);
|
||||
// blockChunkData.setType(1, 0, 1, 1);
|
||||
// blockChunkData.setType(0, 1, 1, 1);
|
||||
// blockChunkData.setType(1, 1, 1, 1);
|
||||
// BlockMeshData meshData = BlockMeshgen.rasterize(blockChunkData);
|
||||
// String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> {
|
||||
// return BlockMeshgen.generateBlockModel(meshData);
|
||||
// }));
|
||||
// EntityCreationUtils.makeEntityDrawablePreexistingModel(blockEntity, modelPath);
|
||||
Entity blockEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
BlockChunkData blockChunkData = BlockChunkData.allocate();
|
||||
blockChunkData.setType(0, 0, 0, 1);
|
||||
blockChunkData.setType(1, 0, 0, 1);
|
||||
blockChunkData.setType(0, 1, 0, 1);
|
||||
blockChunkData.setType(1, 1, 0, 1);
|
||||
blockChunkData.setType(0, 0, 1, 1);
|
||||
blockChunkData.setType(1, 0, 1, 1);
|
||||
blockChunkData.setType(0, 1, 1, 1);
|
||||
blockChunkData.setType(1, 1, 1, 1);
|
||||
BlockMeshData meshData = BlockMeshgen.rasterize(blockChunkData);
|
||||
String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> {
|
||||
return BlockMeshgen.generateBlockModel(meshData);
|
||||
}));
|
||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(blockEntity, modelPath);
|
||||
}
|
||||
|
||||
static final int MAX_DRAW_CELL_WAIT = 1000;
|
||||
|
||||
@ -23,8 +23,10 @@ import electrosphere.util.annotation.Exclude;
|
||||
*/
|
||||
public class ChunkDiskMap {
|
||||
|
||||
//The map of world position+chunk type to the file that actually houses that information
|
||||
Map<String,String> worldPosFileMap = new HashMap<String,String>();
|
||||
/**
|
||||
* The map of world position+chunk type to the file that actually houses that information
|
||||
*/
|
||||
Map<String,String> worldPosFileMap;
|
||||
|
||||
/**
|
||||
* Locks the chunk disk map for thread safety
|
||||
@ -35,8 +37,8 @@ public class ChunkDiskMap {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ChunkDiskMap(){
|
||||
|
||||
private ChunkDiskMap(){
|
||||
worldPosFileMap = new HashMap<String,String>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,14 +67,24 @@ public class ChunkDiskMap {
|
||||
* Initializes a diskmap based on a given save name
|
||||
* @param saveName The save name
|
||||
*/
|
||||
public void init(String saveName){
|
||||
public static ChunkDiskMap init(String saveName){
|
||||
ChunkDiskMap rVal = null;
|
||||
LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName);
|
||||
if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){
|
||||
worldPosFileMap = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", Map.class);
|
||||
LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + worldPosFileMap.keySet());
|
||||
rVal = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", ChunkDiskMap.class);
|
||||
LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet());
|
||||
} else {
|
||||
worldPosFileMap = new HashMap<String,String>();
|
||||
rVal = new ChunkDiskMap();
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a diskmap based on a given save name
|
||||
* @param saveName The save name
|
||||
*/
|
||||
public static ChunkDiskMap init(){
|
||||
return new ChunkDiskMap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -106,7 +106,7 @@ public class ServerTerrainManager {
|
||||
model = terrainGen.generateModel();
|
||||
this.chunkGenerator.setModel(model);
|
||||
model.setInterpolationRandomDampener(SERVER_TERRAIN_MANAGER_DAMPENER);
|
||||
this.chunkDiskMap = new ChunkDiskMap();
|
||||
this.chunkDiskMap = ChunkDiskMap.init();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,8 +157,7 @@ public class ServerTerrainManager {
|
||||
model.setElevationArray(elevation);
|
||||
}
|
||||
//load chunk disk map
|
||||
chunkDiskMap = new ChunkDiskMap();
|
||||
chunkDiskMap.init(saveName);
|
||||
chunkDiskMap = ChunkDiskMap.init(saveName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,10 +295,6 @@ public class ServerTerrainManager {
|
||||
*/
|
||||
public void deformTerrainAtLocationToValue(Vector3i worldPos, Vector3i voxelPos, float weight, int value){
|
||||
TerrainModification modification = new TerrainModification(worldPos,voxelPos,weight,value);
|
||||
//could be null if, for instance, arena mode
|
||||
if(model != null){
|
||||
model.addModification(modification);
|
||||
}
|
||||
if(chunkCache.containsChunk(worldPos.x,worldPos.y,worldPos.z,ChunkData.NO_STRIDE)){
|
||||
ServerTerrainChunk chunk = chunkCache.get(worldPos.x,worldPos.y,worldPos.z, ChunkData.NO_STRIDE);
|
||||
chunk.addModification(modification);
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
package electrosphere.server.terrain.models;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Modifications made to terrain
|
||||
*/
|
||||
public class ModificationList {
|
||||
|
||||
List<TerrainModification> modifications = new ArrayList<TerrainModification>();
|
||||
|
||||
public List<TerrainModification> getModifications() {
|
||||
return modifications;
|
||||
}
|
||||
|
||||
public void addModification(TerrainModification modification){
|
||||
modifications.add(modification);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,8 +1,5 @@
|
||||
package electrosphere.server.terrain.models;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.server.terrain.generation.TestGenerationChunkGenerator;
|
||||
@ -61,11 +58,6 @@ public class TerrainModel {
|
||||
* The real coordinate ocean threshold
|
||||
*/
|
||||
float realOceanThreshold;
|
||||
|
||||
/**
|
||||
* The map of modifications applied to the model
|
||||
*/
|
||||
Map<String,ModificationList> modifications;
|
||||
|
||||
/**
|
||||
* The seed of the terrain
|
||||
@ -84,7 +76,6 @@ public class TerrainModel {
|
||||
* Private constructor
|
||||
*/
|
||||
TerrainModel() {
|
||||
this.modifications = new HashMap<String,ModificationList>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +99,6 @@ public class TerrainModel {
|
||||
this.elevation = elevation;
|
||||
this.realMountainThreshold = realMountainThreshold;
|
||||
this.realOceanThreshold = realOceanThreshold;
|
||||
this.modifications = new HashMap<String,ModificationList>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,55 +448,6 @@ public class TerrainModel {
|
||||
public float getRealOceanThreshold() {
|
||||
return realOceanThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a modification key
|
||||
* @param x The world x position
|
||||
* @param y The world y position
|
||||
* @param z The world z position
|
||||
* @return The key
|
||||
*/
|
||||
public String getModificationKey(int x, int y, int z){
|
||||
return x + "_" + y + "_" + z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a terrain modification to the model
|
||||
* @param modification The modification
|
||||
*/
|
||||
public void addModification(TerrainModification modification){
|
||||
String key = getModificationKey(modification.getWorldPos().x,modification.getWorldPos().y,modification.getWorldPos().z);
|
||||
ModificationList list;
|
||||
if(!modifications.containsKey(key)){
|
||||
list = new ModificationList();
|
||||
modifications.put(key, list);
|
||||
} else {
|
||||
list = modifications.get(key);
|
||||
}
|
||||
list.addModification(modification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a modification has been applied at a world position
|
||||
* @param worldX The x coordinate of the world position
|
||||
* @param worldY The y coordinate of the world position
|
||||
* @param worldZ The z coordinate of the world position
|
||||
* @return true if there is a modification, false otherwise
|
||||
*/
|
||||
public boolean containsModificationsAtCoord(int worldX, int worldY, int worldZ){
|
||||
return modifications.containsKey(getModificationKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the terrain modification at the world position
|
||||
* @param worldX The x coordinate of the world position
|
||||
* @param worldY The y coordinate of the world position
|
||||
* @param worldZ The z coordinate of the world position
|
||||
* @return The modification if there is one at the position, null otherwise
|
||||
*/
|
||||
public ModificationList getModifications(int worldX, int worldY, int worldZ){
|
||||
return modifications.get(getModificationKey(worldX, worldY, worldZ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the elevation array (For instance when read from save file on loading a save)
|
||||
|
||||
@ -3,14 +3,37 @@ package electrosphere.server.terrain.models;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
/**
|
||||
* A modification made to terrain
|
||||
* A modification made to a terrain chunk
|
||||
*/
|
||||
public class TerrainModification {
|
||||
|
||||
/**
|
||||
* The world position of the modification
|
||||
*/
|
||||
Vector3i worldPos;
|
||||
|
||||
/**
|
||||
* The voxel position within the chunk that was modified
|
||||
*/
|
||||
Vector3i voxelPos;
|
||||
|
||||
/**
|
||||
* The new weight
|
||||
*/
|
||||
float weight;
|
||||
|
||||
/**
|
||||
* The new type of voxel
|
||||
*/
|
||||
int value;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param worldPos The world position of the modification
|
||||
* @param voxelPos The voxel position within the chunk that was modified
|
||||
* @param weight The new weight
|
||||
* @param value The new type of voxel
|
||||
*/
|
||||
public TerrainModification(Vector3i worldPos, Vector3i voxelPos, float weight, int value) {
|
||||
this.worldPos = worldPos;
|
||||
this.voxelPos = voxelPos;
|
||||
@ -18,18 +41,34 @@ public class TerrainModification {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world position of the modification
|
||||
* @return The world position
|
||||
*/
|
||||
public Vector3i getWorldPos() {
|
||||
return worldPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new relative voxel position of the modification
|
||||
* @return The relative voxel position
|
||||
*/
|
||||
public Vector3i getVoxelPos() {
|
||||
return voxelPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new weight
|
||||
* @return The new weight
|
||||
*/
|
||||
public float getWeight(){
|
||||
return weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new type of voxel
|
||||
* @return The new type of voxel
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user