Fix server physics and terrain generation

This commit is contained in:
austin 2023-07-15 20:16:17 -04:00
parent c71f4fecad
commit e362a6af75
23 changed files with 889 additions and 456 deletions

View File

@ -1 +0,0 @@
{}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"type":"GAME_WORLD","worldMinPoint":{"x":0.0,"y":0.0,"z":0.0},"worldMaxPoint":{"x":200000.0,"y":0.0,"z":200000.0},"worldSizeDiscrete":2000,"dynamicInterpolationRatio":100,"randomDampener":0.0,"isArena":false}

View File

@ -71,10 +71,6 @@ public class FluidDrawCell {
Globals.clientScene.deregisterEntity(modelEntity);
}
modelEntity = FluidChunk.clientCreateFluidChunkEntity(data.getVoxelWeight(), data.getVoxelType());
for(Vector3i position : data.getModifiedPositions()){
Globals.clientFoliageManager.invalidateCell(worldPos, position);
}
data.resetModifiedPositions();
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos());
}

View File

@ -143,6 +143,8 @@ public class ClientFoliageManager {
locationEvaluationCooldownMap.put(key, cooldownTime);
}
}
//invalidate foliage cells that have had their voxel changed
invalidateModifiedPositions();
}
}
@ -325,7 +327,10 @@ public class ClientFoliageManager {
* @return
*/
private boolean typeSupportsFoliage(int type){
return Globals.gameConfigCurrent.getVoxelData().getTypeFromId(type).getAmbientFoliage() != null;
if(Globals.gameConfigCurrent.getVoxelData().getTypeFromId(type) != null){
return Globals.gameConfigCurrent.getVoxelData().getTypeFromId(type).getAmbientFoliage() != null;
}
return false;
}
/**
@ -334,7 +339,7 @@ public class ClientFoliageManager {
* @param worldPosition The world position of the cell
* @param voxelPosition The voxel position of the cell
*/
public void invalidateCell(Vector3i worldPosition, Vector3i voxelPosition){
private void invalidateCell(Vector3i worldPosition, Vector3i voxelPosition){
String key = getFoliageCellKey(worldPosition, voxelPosition);
if(!locationEvaluationCooldownMap.containsKey(key)){
locationEvaluationCooldownMap.put(key,EVALUATION_COOLDOWN);
@ -349,6 +354,20 @@ public class ClientFoliageManager {
}
}
/**
* Invalidates the foliage cells for all modified chunks
*/
private void invalidateModifiedPositions(){
for(ChunkData chunk : Globals.clientTerrainManager.getAllChunks()){
if(chunk.getModifiedPositions().size() > 0){
for(Vector3i position : chunk.getModifiedPositions()){
Globals.clientFoliageManager.invalidateCell(Globals.clientTerrainManager.getPositionOfChunk(chunk), position);
}
chunk.resetModifiedPositions();
}
}
}
}

View File

@ -115,7 +115,18 @@ public class ChunkData {
* @return The weight of the specified voxel
*/
public float getWeight(Vector3i localPosition){
return voxelWeight[localPosition.x][localPosition.y][localPosition.z];
return getWeight(localPosition.x,localPosition.y,localPosition.z);
}
/**
* Gets the weight of a voxel at a poisiton
* @param localX The x coordinate
* @param localY The y coordinate
* @param localZ The z coordinate
* @return The weight of the specified voxel
*/
public float getWeight(int localX, int localY, int localZ){
return voxelWeight[localX][localY][localZ];
}
/**
@ -124,7 +135,18 @@ public class ChunkData {
* @return The type of the specified voxel
*/
public int getType(Vector3i localPosition){
return voxelType[localPosition.x][localPosition.y][localPosition.z];
return getType(localPosition.x,localPosition.y,localPosition.z);
}
/**
* Gets the type of a voxel at a position
* @param localX The x coordinate
* @param localY The y coordinate
* @param localZ The z coordinate
* @return The type of the specified voxel
*/
public int getType(int localX, int localY, int localZ){
return voxelType[localX][localY][localZ];
}
/**

View File

@ -1,10 +1,13 @@
package electrosphere.client.terrain.cache;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector3i;
/**
* Acts as a cache in front of terrain model to streamline receiving chunks
@ -17,6 +20,8 @@ public class ClientTerrainCache {
Map<String,ChunkData> cacheMap = new ConcurrentHashMap<String,ChunkData>();
//the list of keys in the cache
List<String> cacheList = new CopyOnWriteArrayList<String>();
//A map of chunk to its world position
Map<ChunkData,Vector3i> chunkPositionMap = new ConcurrentHashMap<ChunkData,Vector3i>();
/**
* Constructor
@ -35,6 +40,7 @@ public class ClientTerrainCache {
*/
public void addChunkDataToCache(int worldX, int worldY, int worldZ, ChunkData chunkData){
cacheMap.put(getKey(worldX,worldY,worldZ),chunkData);
chunkPositionMap.put(chunkData,new Vector3i(worldX,worldY,worldZ));
while(cacheList.size() > cacheSize){
String currentChunk = cacheList.remove(0);
cacheMap.remove(currentChunk);
@ -79,4 +85,21 @@ public class ClientTerrainCache {
return cacheMap.get(getKey(worldX,worldY,worldZ));
}
/**
* Gets the list of all chunks in the cache
* @return The list of all chunks in the cache
*/
public Collection<ChunkData> getAllChunks(){
return this.cacheMap.values();
}
/**
* Gets the world position of a chunk
* @param chunk The chunk
* @return The world position of the chunk
*/
public Vector3i getChunkPosition(ChunkData chunk){
return chunkPositionMap.get(chunk);
}
}

View File

@ -23,14 +23,14 @@ public class DrawCell {
//the position of the draw cell in world coordinates
Vector3i worldPos;
ChunkData data;
Entity modelEntity;
ShaderProgram program;
DBody physicsObject;
//Allocated once instead of continuously, used to generate the visual/physics models
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
static Texture groundTextureOne = new Texture("/Textures/Ground/Dirt1.png");
static Texture groundTextureTwo = new Texture("/Textures/Ground/Dirt1.png");
static Texture groundTextureThree = new Texture("/Textures/Ground/Dirt1.png");
@ -53,14 +53,10 @@ public class DrawCell {
* Constructs a drawcell object
*/
public static DrawCell generateTerrainCell(
Vector3i worldPos,
ChunkData data,
ShaderProgram program
Vector3i worldPos
){
DrawCell rVal = new DrawCell();
rVal.worldPos = worldPos;
rVal.program = program;
rVal.data = data;
return rVal;
}
@ -71,32 +67,10 @@ public class DrawCell {
if(modelEntity != null){
Globals.clientScene.deregisterEntity(modelEntity);
}
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(data.getVoxelWeight(), data.getVoxelType(), 0);
// TerrainChunk.createTerrainChunkEntity();
// Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride);
// Mesh terrainMesh = terrainModel.meshes.get(0);
// List<Texture> textureList = new LinkedList<Texture>();
// textureList.add(groundTextureOne);
// textureList.add(groundTextureTwo);
// textureList.add(groundTextureThree);
// textureList.add(groundTextureFour);
// List<String> uniformList = new LinkedList<String>();
// 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());
for(Vector3i position : data.getModifiedPositions()){
Globals.clientFoliageManager.invalidateCell(worldPos, position);
}
data.resetModifiedPositions();
fillInData();
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(weights, types, 0);
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos());
}
@ -118,12 +92,135 @@ public class DrawCell {
EntityUtils.cleanUpEntity(modelEntity);
}
/**
* Gets the current chunk data for this draw cell
* @return The chunk data
* Fills in the internal arrays of data for generate terrain models
*/
public ChunkData getData(){
return data;
private void fillInData(){
//
//fill in data
//
//main chunk
ChunkData currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos);
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] = currentChunk.getWeight(x,y,z);
types[x][y][z] = currentChunk.getType(x,y,z);
}
}
}
//face X
if(worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = 0;
types[ChunkData.CHUNK_SIZE][i][j] = 0;
}
}
}
//face Y
if(worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j);
types[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getType(i, 0, j);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = 0;
types[i][ChunkData.CHUNK_SIZE][j] = 0;
}
}
}
//face Z
if(worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0);
types[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, j, 0);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = 0;
types[i][j][ChunkData.CHUNK_SIZE] = 0;
}
}
}
//edge X-Y
if(
worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize()
){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i);
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
}
}
//edge X-Z
if(
worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()
){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0);
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
}
}
//edge Y-Z
if(
worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()
){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y + 1, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0);
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
}
}
if(
worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.clientWorldData.getWorldDiscreteSize()
){
currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0);
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0);
} else {
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
}
}
}

View File

@ -121,25 +121,32 @@ public class DrawCellManager {
// int currentCellX = cellX - drawRadius + vector.x;
// int currentCellY = cellY - drawRadius + vector.y;
// int currentCellZ = cellZ - drawRadius + vector.z;
if(
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);
// }
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
for(int k = 0; k < 2; k++){
Vector3i posToCheck = new Vector3i(worldPos).add(i,j,k);
if(
posToCheck.x >= 0 &&
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.y >= 0 &&
posToCheck.y < Globals.clientWorldData.getWorldDiscreteSize() &&
posToCheck.z >= 0 &&
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z)
){
// if(!hasRequested.contains(targetKey)){
//client should request chunk data from server for each chunk necessary to create the model
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage(
posToCheck.x,
posToCheck.y,
posToCheck.z
));
// }
}
undrawable.add(targetKey);
hasRequested.add(targetKey);
}
}
}
}
}
@ -152,31 +159,40 @@ public class DrawCellManager {
if(undrawable.size() > 0){
String targetKey = undrawable.iterator().next();
Vector3i worldPos = getVectorFromKey(targetKey);
if(
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();
//evaluate for foliage
Globals.clientFoliageManager.evaluateChunk(worldPos);
boolean containsNecessaryChunks = true;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
for(int k = 0; k < 2; k++){
Vector3i posToCheck = new Vector3i(worldPos).add(i,j,k);
if(worldPos.x >= 0 &&
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.y >= 0 &&
worldPos.y < Globals.clientWorldData.getWorldDiscreteSize() &&
worldPos.z >= 0 &&
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize() &&
!containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z)
){
containsNecessaryChunks = false;
}
}
}
}
//if contains all chunks necessary to generate visuals
if(containsNecessaryChunks){
//build float array
DrawCell cell = DrawCell.generateTerrainCell(
worldPos
);
cells.add(cell);
keyCellMap.put(targetKey,cell);
// undrawable.add(targetKey);
undrawable.remove(targetKey);
drawable.add(targetKey);
//make drawable entity
keyCellMap.get(targetKey).generateDrawableEntity();
//evaluate for foliage
Globals.clientFoliageManager.evaluateChunk(worldPos);
}
}
}

View File

@ -3,8 +3,10 @@ package electrosphere.client.terrain.manager;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
@ -58,22 +60,22 @@ public class ClientTerrainManager {
messageQueue.remove(message);
switch(message.getMessageSubtype()){
case SENDCHUNKDATA: {
int[][][] values = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
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_DATA_GENERATOR_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_DATA_GENERATOR_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_DATA_GENERATOR_SIZE; z++){
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();
}
}
}
IntBuffer intView = buffer.asIntBuffer();
intView.position(floatBuffer.position());
for(int x = 0; x < ChunkData.CHUNK_DATA_GENERATOR_SIZE; x++){
for(int y = 0; y < ChunkData.CHUNK_DATA_GENERATOR_SIZE; y++){
for(int z = 0; z < ChunkData.CHUNK_DATA_GENERATOR_SIZE; z++){
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();
}
}
@ -160,4 +162,21 @@ public class ClientTerrainManager {
terrainChunkGenerationQueue.clear();
}
/**
* Gets all chunks in the terrain cache
* @return The collection of all chunk data objects
*/
public Collection<ChunkData> getAllChunks(){
return terrainCache.getAllChunks();
}
/**
* Gets the world position of a given chunk
* @param chunk The chunk
* @return The world position of the chunk
*/
public Vector3i getPositionOfChunk(ChunkData chunk){
return terrainCache.getChunkPosition(chunk);
}
}

View File

@ -97,6 +97,7 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.MenuGenerators;
import electrosphere.menu.MenuGeneratorsDebug;
import electrosphere.menu.MenuGeneratorsInGame;
import electrosphere.menu.MenuGeneratorsInventory;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
@ -871,7 +872,7 @@ public class ControlHandler {
// Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
// Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
Window mainMenuInGame = MenuGenerators.createInGameMainMenu();
Window mainMenuInGame = MenuGeneratorsInGame.createInGameMainMenu();
// mainMenuWindow.addChild(mainMenuInGame);
Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, mainMenuInGame);
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), true);

View File

@ -33,6 +33,7 @@ public class DebugSPWorldLoading {
loadingWindow.setVisible(true);
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,0.0f,0, new OverworldChunkGenerator());
Globals.currentSaveName = "random_sp_world";
if(!SaveUtils.getSaves().contains("random_sp_world")){
//
//the juicy server GENERATION part

View File

@ -413,331 +413,4 @@ public class MenuGenerators {
public static Window createInGameMainMenu(){
// int screenTop = Globals.WINDOW_HEIGHT - 150;
int width = 500;
int height = 500;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
Div div = new Div();
rVal.addChild(div);
div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
Globals.controlHandler.hideMouse();
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
div.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(100,50,1.0f);
backLabel.setText("Back");
backButton.addChild(backLabel);
div.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
Globals.controlHandler.hideMouse();
return false;
}});
//label 2 (quit)
Button quitButton = new Button();
Label quitLabel = new Label(100,150,1.0f);
quitLabel.setText("Quit");
quitButton.addChild(quitLabel);
div.addChild(quitButton);
quitButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Main.running = false;
return false;
}});
//checking macro data is a poor man's check for whether we're arena or full gamemode
// if(Globals.server != null && Globals.macroData == null){
//label 3 (debug)
Button debugButton = new Button();
Label debugLabel = new Label(100,250,1.0f);
debugLabel.setText("Debug");
debugButton.addChild(debugLabel);
div.addChild(debugButton);
debugButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
// }
return rVal;
}
public static Window createInGameDebugMainMenu(){
// int screenTop = Globals.WINDOW_HEIGHT - 150;
int width = 500;
int height = 500;
float fontSize = 0.4f;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
// Div div = new Div();
// div.setPositionX(0);
// div.setPositionY(0);
// div.setWidth(500);
// div.setHeight(500);
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
rVal.addChild(scrollable);
// scrollable.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameMainMenu());
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
scrollable.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(100,50,fontSize);
backLabel.setText("Back");
backButton.addChild(backLabel);
scrollable.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameMainMenu());
return false;
}});
//text entry (port)
TextInput modelDebugInput = new TextInput(100,150,fontSize);
scrollable.addChild(modelDebugInput);
modelDebugInput.setText("Model path goes here");
//label 3 (load model and debug)
Button debugModelButton = new Button();
Label debugModelLabel = new Label(100,250,fontSize);
debugModelLabel.setText("Print Model Debug Info");
debugModelButton.addChild(debugModelLabel);
scrollable.addChild(debugModelButton);
debugModelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Model targetModel = null;
if((targetModel = Globals.assetManager.fetchModel(modelDebugInput.getText())) != null){
targetModel.describeHighLevel();
} else {
Globals.assetManager.addModelPathToQueue(modelDebugInput.getText());
Globals.assetManager.loadAssetsInQueue();
if((targetModel = Globals.assetManager.fetchModel(modelDebugInput.getText())) != null){
targetModel.describeHighLevel();
}
}
return false;
}});
//label 4 (reload all shaders)
Button reloadShaderButton = new Button();
Label reloadShaderLabel = new Label(100,350,fontSize);
reloadShaderLabel.setText("Reload all shaders");
reloadShaderButton.addChild(reloadShaderLabel);
scrollable.addChild(reloadShaderButton);
reloadShaderButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.assetManager.forceReloadAllShaders();
return false;
}});
//reload all models
Button reloadModelButton = new Button();
Label reloadModelLabel = new Label(100,450,fontSize);
reloadModelLabel.setText("Reload all models");
reloadModelButton.addChild(reloadModelLabel);
scrollable.addChild(reloadModelButton);
reloadModelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.assetManager.forceReloadAllModels();
return false;
}});
//disable drawing player character
Button toggleDrawPlayerButton = new Button();
Label toggleDrawPlayerLabel = new Label(100,550,fontSize);
toggleDrawPlayerLabel.setText("Toggle draw character");
toggleDrawPlayerButton.addChild(toggleDrawPlayerLabel);
scrollable.addChild(toggleDrawPlayerButton);
toggleDrawPlayerButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
if(Globals.playerEntity != null){
if(Globals.playerEntity.containsKey(EntityDataStrings.DATA_STRING_DRAW)){
boolean draw = (boolean)Globals.playerEntity.getData(EntityDataStrings.DATA_STRING_DRAW);
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, !draw);
}
if(Globals.playerEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW)){
boolean drawShadow = (boolean)Globals.playerEntity.getData(EntityDataStrings.DRAW_CAST_SHADOW);
Globals.playerEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, !drawShadow);
}
}
return false;
}});
//pull up character editor
Button characterSliderMenuButton = new Button();
Label characterSliderMenuLabel = new Label(100,650,fontSize);
characterSliderMenuLabel.setText("Character slider menu");
characterSliderMenuButton.addChild(characterSliderMenuLabel);
scrollable.addChild(characterSliderMenuButton);
characterSliderMenuButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameCharacterSliderMenu());
return false;
}});
for(int i = 0; i < 5; i++){
Button someButton = new Button();
Label someLabel = new Label(100,750 + i * 100,fontSize);
someLabel.setText("aaaaaa" + i);
someButton.addChild(someLabel);
scrollable.addChild(someButton);
someButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
return false;
}});
}
//label (switch framebuffer)
Button switchFramebufferButton = new Button();
Label switchFramebufferLabel = new Label(100,1250,fontSize);
switchFramebufferLabel.setText("Switch Active Framebuffer");
switchFramebufferButton.addChild(switchFramebufferLabel);
scrollable.addChild(switchFramebufferButton);
switchFramebufferButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
RenderingEngine.incrementOutputFramebuffer();
return false;
}});
//label (toggle draw collision spheres)
Button toggleCollisionSpheresButton = new Button();
Label toggleCollisionSpheresLabel = new Label(100,1350,fontSize);
toggleCollisionSpheresLabel.setText("Toggle draw collision spheres");
toggleCollisionSpheresButton.addChild(toggleCollisionSpheresLabel);
scrollable.addChild(toggleCollisionSpheresButton);
toggleCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawCollisionSpheres(!Globals.userSettings.graphicsDebugDrawCollisionSpheres());
return false;
}});
//label (toggle draw physics objects)
Button togglePhysicsObjectsButton = new Button();
Label togglePhysicsObjectsLabel = new Label(100,1450,fontSize);
togglePhysicsObjectsLabel.setText("Toggle draw physics objects");
togglePhysicsObjectsButton.addChild(togglePhysicsObjectsLabel);
scrollable.addChild(togglePhysicsObjectsButton);
togglePhysicsObjectsButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawPhysicsObjects(!Globals.userSettings.graphicsDebugDrawPhysicsObjects());
return false;
}});
//label (toggle draw movement vectors)
Button toggleMovementVectorsButton = new Button();
Label toggleMovementVectorsLabel = new Label(100,1550,fontSize);
toggleMovementVectorsLabel.setText("Toggle draw movement vectors");
toggleMovementVectorsButton.addChild(toggleMovementVectorsLabel);
scrollable.addChild(toggleMovementVectorsButton);
toggleMovementVectorsButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawMovementVectors(!Globals.userSettings.graphicsDebugDrawMovementVectors());
return false;
}});
//label (toggle draw navmesh)
Button toggleNavmeshButton = new Button();
Label toggleNavmeshLabel = new Label(100,1650,fontSize);
toggleNavmeshLabel.setText("Toggle draw navmesh");
toggleNavmeshButton.addChild(toggleNavmeshLabel);
scrollable.addChild(toggleNavmeshButton);
toggleNavmeshButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawNavmesh(!Globals.userSettings.graphicsDebugDrawNavmesh());
return false;
}});
return rVal;
}
public static Window createInGameCharacterSliderMenu(){
int width = 500;
int height = 500;
float fontSize = 0.4f;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
// Div div = new Div();
// div.setPositionX(0);
// div.setPositionY(0);
// div.setWidth(500);
// div.setHeight(500);
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
rVal.addChild(scrollable);
// scrollable.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
scrollable.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(200,50,fontSize);
backLabel.setText("Back");
backButton.addChild(backLabel);
scrollable.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
Entity playerEntity = Globals.playerEntity;
Actor playerActor = EntityUtils.getActor(playerEntity);
ActorStaticMorph staticMorph = playerActor.getStaticMorph();
CreatureType playeCreatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(playerEntity));
int offset = 0;
for(VisualAttribute attribute : playeCreatureType.getVisualAttributes()){
int posY = offset * 350 + 100;
if(attribute.getType().equals("bone")){
Slider attributeSlider = new Slider(50,posY,400,100,new Vector3f(0.1f,0.1f,0.1f),new Vector3f(1.0f,0,0));
attributeSlider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
float value = event.getAsFloat();
float minVal = attribute.getMinValue();
float range = attribute.getMaxValue() - minVal;
float actualValue = minVal + range * value;
staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat());
if(attribute.getMirrorBone() != null){
staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat());
}
}});
scrollable.addChild(attributeSlider);
}
}
return rVal;
}
}

View File

@ -0,0 +1,383 @@
package electrosphere.menu;
import org.joml.Vector3f;
import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.renderer.Model;
import electrosphere.renderer.RenderingEngine;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorStaticMorph;
import electrosphere.renderer.ui.ClickableElement;
import electrosphere.renderer.ui.Window;
import electrosphere.renderer.ui.NavigableElement.NavigationEventCallback;
import electrosphere.renderer.ui.ValueElement.ValueChangeEventCallback;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.ImagePanel;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.ScrollableContainer;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.TextInput;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.NavigationEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
public class MenuGeneratorsInGame {
/**
* Creates the main in game menu that shows up when you (typically) hit the escape key
* @return The window for the menu
*/
public static Window createInGameMainMenu(){
// int screenTop = Globals.WINDOW_HEIGHT - 150;
int width = 500;
int height = 500;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
Div div = new Div();
rVal.addChild(div);
div.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
Globals.controlHandler.hideMouse();
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
div.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(100,50,1.0f);
backLabel.setText("Back");
backButton.addChild(backLabel);
div.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
Globals.controlHandler.hideMouse();
return false;
}});
//label 2 (quit)
Button saveButton = new Button();
Label saveLabel = new Label(100,150,1.0f);
saveLabel.setText("Save");
saveButton.addChild(saveLabel);
div.addChild(saveButton);
saveButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Main.running = false;
//save terrain
saveWorld();
return false;
}});
//label 3 (quit)
Button quitButton = new Button();
Label quitLabel = new Label(100,250,1.0f);
quitLabel.setText("Quit");
quitButton.addChild(quitLabel);
div.addChild(quitButton);
quitButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Main.running = false;
return false;
}});
//checking macro data is a poor man's check for whether we're arena or full gamemode
// if(Globals.server != null && Globals.macroData == null){
//label 4 (debug)
Button debugButton = new Button();
Label debugLabel = new Label(100,350,1.0f);
debugLabel.setText("Debug");
debugButton.addChild(debugLabel);
div.addChild(debugButton);
debugButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
// }
return rVal;
}
static void saveWorld(){
if(Globals.serverTerrainManager != null){
Globals.serverTerrainManager.save(Globals.currentSaveName);
}
}
public static Window createInGameDebugMainMenu(){
// int screenTop = Globals.WINDOW_HEIGHT - 150;
int width = 500;
int height = 500;
float fontSize = 0.4f;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
// Div div = new Div();
// div.setPositionX(0);
// div.setPositionY(0);
// div.setWidth(500);
// div.setHeight(500);
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
rVal.addChild(scrollable);
// scrollable.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameMainMenu());
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
scrollable.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(100,50,fontSize);
backLabel.setText("Back");
backButton.addChild(backLabel);
scrollable.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameMainMenu());
return false;
}});
//text entry (port)
TextInput modelDebugInput = new TextInput(100,150,fontSize);
scrollable.addChild(modelDebugInput);
modelDebugInput.setText("Model path goes here");
//label 3 (load model and debug)
Button debugModelButton = new Button();
Label debugModelLabel = new Label(100,250,fontSize);
debugModelLabel.setText("Print Model Debug Info");
debugModelButton.addChild(debugModelLabel);
scrollable.addChild(debugModelButton);
debugModelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Model targetModel = null;
if((targetModel = Globals.assetManager.fetchModel(modelDebugInput.getText())) != null){
targetModel.describeHighLevel();
} else {
Globals.assetManager.addModelPathToQueue(modelDebugInput.getText());
Globals.assetManager.loadAssetsInQueue();
if((targetModel = Globals.assetManager.fetchModel(modelDebugInput.getText())) != null){
targetModel.describeHighLevel();
}
}
return false;
}});
//label 4 (reload all shaders)
Button reloadShaderButton = new Button();
Label reloadShaderLabel = new Label(100,350,fontSize);
reloadShaderLabel.setText("Reload all shaders");
reloadShaderButton.addChild(reloadShaderLabel);
scrollable.addChild(reloadShaderButton);
reloadShaderButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.assetManager.forceReloadAllShaders();
return false;
}});
//reload all models
Button reloadModelButton = new Button();
Label reloadModelLabel = new Label(100,450,fontSize);
reloadModelLabel.setText("Reload all models");
reloadModelButton.addChild(reloadModelLabel);
scrollable.addChild(reloadModelButton);
reloadModelButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.assetManager.forceReloadAllModels();
return false;
}});
//disable drawing player character
Button toggleDrawPlayerButton = new Button();
Label toggleDrawPlayerLabel = new Label(100,550,fontSize);
toggleDrawPlayerLabel.setText("Toggle draw character");
toggleDrawPlayerButton.addChild(toggleDrawPlayerLabel);
scrollable.addChild(toggleDrawPlayerButton);
toggleDrawPlayerButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
if(Globals.playerEntity != null){
if(Globals.playerEntity.containsKey(EntityDataStrings.DATA_STRING_DRAW)){
boolean draw = (boolean)Globals.playerEntity.getData(EntityDataStrings.DATA_STRING_DRAW);
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, !draw);
}
if(Globals.playerEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW)){
boolean drawShadow = (boolean)Globals.playerEntity.getData(EntityDataStrings.DRAW_CAST_SHADOW);
Globals.playerEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, !drawShadow);
}
}
return false;
}});
//pull up character editor
Button characterSliderMenuButton = new Button();
Label characterSliderMenuLabel = new Label(100,650,fontSize);
characterSliderMenuLabel.setText("Character slider menu");
characterSliderMenuButton.addChild(characterSliderMenuLabel);
scrollable.addChild(characterSliderMenuButton);
characterSliderMenuButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameCharacterSliderMenu());
return false;
}});
for(int i = 0; i < 5; i++){
Button someButton = new Button();
Label someLabel = new Label(100,750 + i * 100,fontSize);
someLabel.setText("aaaaaa" + i);
someButton.addChild(someLabel);
scrollable.addChild(someButton);
someButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
return false;
}});
}
//label (switch framebuffer)
Button switchFramebufferButton = new Button();
Label switchFramebufferLabel = new Label(100,1250,fontSize);
switchFramebufferLabel.setText("Switch Active Framebuffer");
switchFramebufferButton.addChild(switchFramebufferLabel);
scrollable.addChild(switchFramebufferButton);
switchFramebufferButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
RenderingEngine.incrementOutputFramebuffer();
return false;
}});
//label (toggle draw collision spheres)
Button toggleCollisionSpheresButton = new Button();
Label toggleCollisionSpheresLabel = new Label(100,1350,fontSize);
toggleCollisionSpheresLabel.setText("Toggle draw collision spheres");
toggleCollisionSpheresButton.addChild(toggleCollisionSpheresLabel);
scrollable.addChild(toggleCollisionSpheresButton);
toggleCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawCollisionSpheres(!Globals.userSettings.graphicsDebugDrawCollisionSpheres());
return false;
}});
//label (toggle draw physics objects)
Button togglePhysicsObjectsButton = new Button();
Label togglePhysicsObjectsLabel = new Label(100,1450,fontSize);
togglePhysicsObjectsLabel.setText("Toggle draw physics objects");
togglePhysicsObjectsButton.addChild(togglePhysicsObjectsLabel);
scrollable.addChild(togglePhysicsObjectsButton);
togglePhysicsObjectsButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawPhysicsObjects(!Globals.userSettings.graphicsDebugDrawPhysicsObjects());
return false;
}});
//label (toggle draw movement vectors)
Button toggleMovementVectorsButton = new Button();
Label toggleMovementVectorsLabel = new Label(100,1550,fontSize);
toggleMovementVectorsLabel.setText("Toggle draw movement vectors");
toggleMovementVectorsButton.addChild(toggleMovementVectorsLabel);
scrollable.addChild(toggleMovementVectorsButton);
toggleMovementVectorsButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawMovementVectors(!Globals.userSettings.graphicsDebugDrawMovementVectors());
return false;
}});
//label (toggle draw navmesh)
Button toggleNavmeshButton = new Button();
Label toggleNavmeshLabel = new Label(100,1650,fontSize);
toggleNavmeshLabel.setText("Toggle draw navmesh");
toggleNavmeshButton.addChild(toggleNavmeshLabel);
scrollable.addChild(toggleNavmeshButton);
toggleNavmeshButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
// Main.running = false;
Globals.userSettings.setGraphicsDebugDrawNavmesh(!Globals.userSettings.graphicsDebugDrawNavmesh());
return false;
}});
return rVal;
}
public static Window createInGameCharacterSliderMenu(){
int width = 500;
int height = 500;
float fontSize = 0.4f;
Window rVal = new Window(0,0,width,height);
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
// Div div = new Div();
// div.setPositionX(0);
// div.setPositionY(0);
// div.setWidth(500);
// div.setHeight(500);
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
rVal.addChild(scrollable);
// scrollable.addChild(div);
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
//black texture background
ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture);
// imagePanel.setWidth(width);
// imagePanel.setHeight(height);
// imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture));
scrollable.addChild(imagePanel);
//label 1 (back)
Button backButton = new Button();
Label backLabel = new Label(200,50,fontSize);
backLabel.setText("Back");
backButton.addChild(backLabel);
scrollable.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, createInGameDebugMainMenu());
return false;
}});
Entity playerEntity = Globals.playerEntity;
Actor playerActor = EntityUtils.getActor(playerEntity);
ActorStaticMorph staticMorph = playerActor.getStaticMorph();
CreatureType playeCreatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(playerEntity));
int offset = 0;
for(VisualAttribute attribute : playeCreatureType.getVisualAttributes()){
int posY = offset * 350 + 100;
if(attribute.getType().equals("bone")){
Slider attributeSlider = new Slider(50,posY,400,100,new Vector3f(0.1f,0.1f,0.1f),new Vector3f(1.0f,0,0));
attributeSlider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
float value = event.getAsFloat();
float minVal = attribute.getMinValue();
float range = attribute.getMaxValue() - minVal;
float actualValue = minVal + range * value;
staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat());
if(attribute.getMirrorBone() != null){
staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat());
}
}});
scrollable.addChild(attributeSlider);
}
}
return rVal;
}
}

View File

@ -2,6 +2,7 @@ package electrosphere.renderer;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.texture.Texture;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@ -194,7 +195,7 @@ public class ModelUtils {
maxZ = currentMesh.vertexMaxZ;
}
}
System.out.println("dimensions: " + (maxX - minX) + "," + (maxY - minY) + "," + (maxZ-minZ));
LoggerInterface.loggerRenderer.INFO("dimensions: " + (maxX - minX) + "," + (maxY - minY) + "," + (maxZ-minZ));
}

View File

@ -192,8 +192,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
* 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);
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(parent, worldPos);
cell.generatePhysics();
}
@ -231,7 +230,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
int frameCount = cellPlayerlessFrameMap.get(cell) + 1;
cellPlayerlessFrameMap.put(cell,frameCount);
if(frameCount > UNLOAD_FRAME_THRESHOLD){
System.out.println("Unload cell " + getCellWorldPosition(cell));
toCleanQueue.add(cell);
}
} else {
@ -243,8 +241,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
for(ServerDataCell cell : toCleanQueue){
parent.deregisterCell(cell);
loadedCells.remove(cell);
String key = getServerDataCellKey(getCellWorldPosition(cell));
Vector3i worldPos = getCellWorldPosition(cell);
String key = getServerDataCellKey(worldPos);
groundDataCells.remove(key);
//clear all entities in cell
for(Entity entity : cell.getScene().getEntityList()){
EntityUtils.cleanUpEntity(entity);
}
//save terrain to disk
serverTerrainManager.savePositionToDisk(worldPos);
}
toCleanQueue.clear();
}

View File

@ -33,36 +33,39 @@ import org.joml.Vector3i;
import org.ode4j.ode.DBody;
/**
*
* @author satellite
* An entity containing physics for a given chunk on the server
*/
public class PhysicsDataCell {
Vector3i worldPos;
ServerTerrainChunk chunkData;
Entity physicsEntity;
DBody physicsObject;
Realm realm;
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
PhysicsDataCell(){
}
/**
* Creates a physics cell
* @param realm The realm to create it in
* @param worldPos The world position of the cell
* @return The cell
*/
public static PhysicsDataCell createPhysicsCell(
Realm realm,
Vector3i worldPos,
ServerTerrainChunk chunkData
Vector3i worldPos
){
PhysicsDataCell rVal = new PhysicsDataCell();
rVal.realm = realm;
rVal.worldPos = worldPos;
rVal.chunkData = chunkData;
return rVal;
}
@ -79,14 +82,19 @@ public class PhysicsDataCell {
public void generatePhysics(){
//if the entity hasn't already been created for some reason, need to create it
if(physicsEntity == null){
Vector3d position = new Vector3d(
//
//fill in weights and types maps
//
fillInData();
Vector3d realPos = 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 = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types);
physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
ServerEntityUtils.repositionEntity(physicsEntity, position);
}
// //then actually perform the attach
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
@ -100,4 +108,134 @@ public class PhysicsDataCell {
realm.getCollisionEngine().deregisterRigidBody((DBody)physicsObject);
}
/**
* Fills in the internal arrays of data for generate terrain models
*/
private void fillInData(){
//
//fill in data
//
//main chunk
ServerTerrainChunk currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
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] = currentChunk.getWeight(x,y,z);
types[x][y][z] = currentChunk.getType(x,y,z);
}
}
}
//face X
if(worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[ChunkData.CHUNK_SIZE][i][j] = 0;
types[ChunkData.CHUNK_SIZE][i][j] = 0;
}
}
}
//face Y
if(worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j);
types[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getType(i, 0, j);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][ChunkData.CHUNK_SIZE][j] = 0;
types[i][ChunkData.CHUNK_SIZE][j] = 0;
}
}
}
//face Z
if(worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0);
types[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, j, 0);
}
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
weights[i][j][ChunkData.CHUNK_SIZE] = 0;
types[i][j][ChunkData.CHUNK_SIZE] = 0;
}
}
}
//edge X-Y
if(
worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i);
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
}
}
//edge X-Z
if(
worldPos.x + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0);
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
}
}
//edge Y-Z
if(
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1);
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0);
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0);
}
} else {
for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
}
}
if(
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.y + 1 < Globals.serverTerrainManager.getWorldDiscreteSize() &&
worldPos.z + 1 < Globals.serverTerrainManager.getWorldDiscreteSize()
){
currentChunk = Globals.serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0);
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0);
} else {
weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
}
}
}

View File

@ -59,8 +59,10 @@ public class ChunkDiskMap {
* @param saveName The save name
*/
public void init(String saveName){
System.out.println("INIT CHUNK MAP " + saveName);
if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){
worldPosFileMap = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", Map.class);
System.out.println("POS FILE MAP: " + worldPosFileMap.keySet());
} else {
worldPosFileMap = new HashMap<String,String>();
}
@ -70,7 +72,7 @@ public class ChunkDiskMap {
* Saves the disk map to disk
*/
public void save(){
FileUtils.serializeObjectToSavePath(Globals.currentSaveName, "chunk.map", this);
FileUtils.serializeObjectToSavePath(Globals.currentSaveName, "chunk.map", worldPosFileMap);
}
/**
@ -103,6 +105,7 @@ public class ChunkDiskMap {
* @return The server terrain chunk if it exists, null otherwise
*/
public ServerTerrainChunk getTerrainChunk(int worldX, int worldY, int worldZ){
System.out.println("Load chunk " + worldX + " " + worldY + " " + worldZ);
ServerTerrainChunk rVal = null;
if(containsTerrainAtPosition(worldX, worldY, worldZ)){
//read file
@ -113,7 +116,7 @@ public class ChunkDiskMap {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InflaterOutputStream inflaterInputStream = new InflaterOutputStream(out);
try {
inflaterInputStream.write(rawData);
inflaterInputStream.write(rawDataCompressed);
inflaterInputStream.flush();
inflaterInputStream.close();
rawData = out.toByteArray();
@ -136,7 +139,7 @@ public class ChunkDiskMap {
}
}
IntBuffer intView = buffer.asIntBuffer();
intView.position(DIM * DIM * DIM * 4);
intView.position(DIM * DIM * DIM);
for(int x = 0; x < DIM; x++){
for(int y = 0; y < DIM; y++){
for(int z = 0; z < DIM; z++){
@ -155,6 +158,7 @@ public class ChunkDiskMap {
* @param terrainChunk The terrain chunk
*/
public void saveToDisk(ServerTerrainChunk terrainChunk){
System.out.println("Save to disk: " + terrainChunk.getWorldX() + " " + terrainChunk.getWorldY() + " " + terrainChunk.getWorldZ());
//get the file name for this chunk
String fileName = null;
String chunkKey = getTerrainChunkKey(terrainChunk.getWorldX(),terrainChunk.getWorldY(),terrainChunk.getWorldZ());

View File

@ -33,12 +33,12 @@ public class OverworldChunkGenerator implements ChunkGenerator {
//Each chunk also needs custody of the next chunk's first values so that they can perfectly overlap.
//Hence, width should actually be chunk dimension + 1
float[][] heightmap = getHeightmap(worldX, worldZ);
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
int[][][] values = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
for(int weightX = 0; weightX < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightX++){
for(int weightY = 0; weightY < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightY++){
for(int weightZ = 0; weightZ < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; weightZ++){
float height = heightmap[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldX + weightX][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE * worldZ + weightZ];
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++){
float height = heightmap[ServerTerrainChunk.CHUNK_DIMENSION * worldX + weightX][ServerTerrainChunk.CHUNK_DIMENSION * worldZ + weightZ];
if(weightY < height){
weights[weightX][weightY][weightZ] = 1;
values[weightX][weightY][weightZ] = 1;

View File

@ -13,6 +13,7 @@ import java.util.Random;
import javax.swing.JFrame;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.terrain.models.TerrainModel;
/**
@ -1262,7 +1263,7 @@ public class TerrainGenerator {
}
//Because of how exponentials work, this check should never pass
if(Math.exp(-(1.0 - percentageAboveLand)) > 1.0){
System.out.println("WARNING!!");
LoggerInterface.loggerEngine.WARNING("WARNING!!");
}
} else {
rVal[x][y] = data[x][y];

View File

@ -74,7 +74,18 @@ public class ServerTerrainChunk {
* @return The weight of the specified voxel
*/
public float getWeight(Vector3i localPosition){
return weights[localPosition.x][localPosition.y][localPosition.z];
return getWeight(localPosition.x,localPosition.y,localPosition.z);
}
/**
* Gets the weight of a voxel at a poisiton
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @return The weight of the specified voxel
*/
public float getWeight(int x, int y, int z){
return weights[x][y][z];
}
/**
@ -83,7 +94,18 @@ public class ServerTerrainChunk {
* @return The type of the specified voxel
*/
public int getType(Vector3i localPosition){
return values[localPosition.x][localPosition.y][localPosition.z];
return getType(localPosition.x,localPosition.y,localPosition.z);
}
/**
* Gets the type of a voxel at a position
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @return The type of the specified voxel
*/
public int getType(int x, int y, int z){
return values[x][y][z];
}

View File

@ -125,6 +125,12 @@ public class ServerTerrainManager {
floatView.flip();
FileUtils.saveBinaryToSavePath(saveName, "./terrain.dat", buffer.array());
FileUtils.serializeObjectToSavePath(saveName, "./terrain.json", model);
//for each chunk, save via disk map
for(String chunkKey : chunkCacheContents){
ServerTerrainChunk chunk = chunkCache.get(chunkKey);
chunkDiskMap.saveToDisk(chunk);
}
//save disk map itself
if(chunkDiskMap != null){
chunkDiskMap.save();
}
@ -249,6 +255,15 @@ public class ServerTerrainManager {
}
}
/**
* Saves a given position's chunk to disk.
* Uses the current global save name
* @param position The position to save
*/
public void savePositionToDisk(Vector3i position){
chunkDiskMap.saveToDisk(getChunk(position.x, position.y, position.z));
}
/**
* Applies a deform to terrain at a given location
* @param worldPos The world coordinates of the chunk to modify