diff --git a/.gitignore b/.gitignore index 2dc2c924..9f2c3a17 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ #saves /saves/random_sp_world /saves/defaultLevel* +/saves/generation_testing #screenshots /assets/Screenshots diff --git a/assets/Data/entity/objects/game_objects.json b/assets/Data/entity/objects/game_objects.json index 851b71a8..a26dc0a8 100644 --- a/assets/Data/entity/objects/game_objects.json +++ b/assets/Data/entity/objects/game_objects.json @@ -12,6 +12,17 @@ "SPAWNPOINT" ] }, + { + "id" : "marker", + "graphicsTemplate": { + "model": { + "path" : "Models/gameobj/token.glb" + } + }, + "tokens": [ + "MARKER" + ] + }, { "id" : "flameEmitterTest", "particleEmitter": { diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index 158885a2..44c780cd 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -13,8 +13,6 @@ - Old sword item - Switch that requires being hit - Door that can be locked -+ Lock third room behind climbing - - Climbing + Portal to tutorial hub area - Portals - Switching realms @@ -23,7 +21,6 @@ + rearchitecture + fix the vibes - Tooltips for items, hover over with cursor, etc Ticketed randomizer node for BTs to more heavily weight attacking and waiting + non-feedback requirements diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index a49c821a..d2685c0c 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -897,6 +897,7 @@ Initial implementation of tooltips (10/23/2024) Tooltip improvements +Terrain generation testing realm @@ -961,6 +962,16 @@ Startup Performance - Proactively send chunks on player loading in (ie, send all chunks that are all air before its even requested) - Also send all 'dirt' or 'stone' chunks +Scripting enhancements + - setTimeout + - Get marker by entity name/id + - Play/Stop animations on actors + - Apply cameras + - Show/Hide UI + - Enable/disable controls states + - Spawn/Destroy entities + - Ability to define regions in space (ie with entities) + Code Generation - Generate static "hasXComponent", "getXComponent" functions on sync'd components @@ -977,7 +988,6 @@ Code cleanup - Rename "ShaderProgram" to "VisualShader" - Have ComputeShader and VisualShader use same static method for uploading uniforms -Goof off today requirements: Transvoxel implementation - Fix draw cell manager requesting far-out chunks - Properly update to higher LOD meshes as you get closer diff --git a/src/main/java/electrosphere/client/ui/menu/mainmenu/MenuGeneratorsTitleMenu.java b/src/main/java/electrosphere/client/ui/menu/mainmenu/MenuGeneratorsTitleMenu.java index 62389523..8fbbb0e0 100644 --- a/src/main/java/electrosphere/client/ui/menu/mainmenu/MenuGeneratorsTitleMenu.java +++ b/src/main/java/electrosphere/client/ui/menu/mainmenu/MenuGeneratorsTitleMenu.java @@ -63,6 +63,14 @@ public class MenuGeneratorsTitleMenu { Globals.threadManager.start(loadingThread); }).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE)); + //button (sp debug) + rVal.addChild(Button.createButtonCentered("Load Test Generation Realm", () -> { + LoadingThread loadingThread = new LoadingThread(LoadingThreadType.CHUNK_GENERATION_REALM); + Globals.RUN_CLIENT = true; + Globals.RUN_SERVER = true; + Globals.threadManager.start(loadingThread); + }).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE)); + //button (ui testing) rVal.addChild(Button.createButtonCentered("UI Testing", () -> { WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu()); diff --git a/src/main/java/electrosphere/engine/loadingthreads/ChunkGenerationTestLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ChunkGenerationTestLoading.java new file mode 100644 index 00000000..14495156 --- /dev/null +++ b/src/main/java/electrosphere/engine/loadingthreads/ChunkGenerationTestLoading.java @@ -0,0 +1,104 @@ +package electrosphere.engine.loadingthreads; + +import java.util.concurrent.TimeUnit; + +import electrosphere.auth.AuthenticationManager; +import electrosphere.client.ui.menu.MenuGenerators; +import electrosphere.client.ui.menu.WindowStrings; +import electrosphere.client.ui.menu.WindowUtils; +import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; +import electrosphere.entity.scene.SceneGenerator; +import electrosphere.logger.LoggerInterface; +import electrosphere.net.parser.net.message.TerrainMessage; +import electrosphere.net.server.ServerConnectionHandler; +import electrosphere.renderer.ui.elements.Window; +import electrosphere.server.saves.SaveUtils; + +/** + * Loads the chunk generation testing realm + */ +public class ChunkGenerationTestLoading { + + /** + * Loads the level editor + */ + protected static void loadChunkGenerationTesting(Object[] params){ + + // + //Set params we would expect to run with this thread + // + Globals.RUN_CLIENT = true; + Globals.RUN_SERVER = true; + Globals.RUN_PHYSICS = false; + Globals.aiManager.setActive(false); + + + Globals.signalSystem.post(SignalType.UI_MODIFICATION, ()->{ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + //show loading + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + }); + + + + String saveName = "generation_testing"; + if(!SaveUtils.getSaves().contains(saveName)){ + // + //the juicy server GENERATION part + // + //init save structure + SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createGenerationTestingSceneFile(saveName)); + } + //load just-created save + SaveUtils.loadSave(saveName, false); + + + + + //initialize the "virtual" objects simulation + LoadingUtils.initMacroSimulation(); + LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); + //init authentication + LoadingUtils.initAuthenticationManager(false); + //initialize the local connection + Globals.clientUsername = "leveleditor"; + Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor"); + ServerConnectionHandler serverPlayerConnection = LoadingUtils.initLocalConnection(true); + //wait for player object creation + while(Globals.playerManager.getPlayers().size() < 1 || !Globals.clientConnection.isInitialized()){ + try { + TimeUnit.MILLISECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + //initialize the "real" objects simulation + LoadingUtils.initMicroSimulation(); + //init game specific stuff (ie different skybox colors) + LoadingUtils.initGameGraphicalEntities(); + //set simulations to ready if they exist + LoadingUtils.setSimulationsToReady(); + //log + LoggerInterface.loggerEngine.INFO("[Server]Finished loading level editor"); + + //the less juicy client setup part + while(Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().size() == 0){ + try { + TimeUnit.MILLISECONDS.sleep(1); + } catch (InterruptedException ex) {} + } + + //spawn player character + LoadingUtils.spawnLocalPlayerTestEntity(serverPlayerConnection, true); + + //request terrain data + Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestMetadataMessage()); + + //Run client startup process + ClientLoading.loadClientWorld(params); + } + +} diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java index 5dae7f1d..9602c1ff 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java @@ -40,6 +40,11 @@ public class LoadingThread extends Thread { */ DEBUG_RANDOM_SP_WORLD, + /** + * Loads a chunk generation testing realm + */ + CHUNK_GENERATION_REALM, + /** * Loads the level editor */ @@ -133,6 +138,11 @@ public class LoadingThread extends Thread { DebugSPWorldLoading.loadDebugSPWorld(params); } break; + //Loads a realm used for chunk generation testing + case CHUNK_GENERATION_REALM: { + ChunkGenerationTestLoading.loadChunkGenerationTesting(params); + } break; + //loads the level editor case LEVEL_EDITOR: { LevelEditorLoading.loadLevelEditor(params); diff --git a/src/main/java/electrosphere/entity/scene/RealmDescriptor.java b/src/main/java/electrosphere/entity/scene/RealmDescriptor.java index d2648ed9..7547a8b5 100644 --- a/src/main/java/electrosphere/entity/scene/RealmDescriptor.java +++ b/src/main/java/electrosphere/entity/scene/RealmDescriptor.java @@ -10,6 +10,7 @@ public class RealmDescriptor { */ public static final String REALM_DESCRIPTOR_GRIDDED = "gridded"; public static final String REALM_DESCRIPTOR_PROCEDURAL = "procedural"; + public static final String REALM_DESCRIPTOR_GENERATION_TESTING = "generationTesting"; /** * The dirt voxel type's id diff --git a/src/main/java/electrosphere/entity/scene/SceneGenerator.java b/src/main/java/electrosphere/entity/scene/SceneGenerator.java index ccaa1cc5..2c6cadeb 100644 --- a/src/main/java/electrosphere/entity/scene/SceneGenerator.java +++ b/src/main/java/electrosphere/entity/scene/SceneGenerator.java @@ -1,6 +1,7 @@ package electrosphere.entity.scene; import electrosphere.server.datacell.GriddedDataCellManager; +import electrosphere.server.terrain.generation.TestGenerationChunkGenerator; /** * Generates scene files where appropriate (ie, if playing the procedurally generated level) @@ -24,4 +25,21 @@ public class SceneGenerator { return file; } + /** + * Creates a scene file for the generation testing realm + * @param gridSize The size of the terrain grid of the scene + * @return The scene file + */ + public static SceneFile createGenerationTestingSceneFile(String saveName){ + //base file stuff + SceneFile file = SceneFile.createSceneFile(); + //realm descriptor stuff + file.realmDescriptor.type = RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING; + file.realmDescriptor.griddedRealmSize = TestGenerationChunkGenerator.GENERATOR_REALM_SIZE; + file.createSaveInstance = true; //won't have a predefined scene to load, so must create one in the save + file.loadAllCells = false; // do not load all cells on init + + return file; + } + } diff --git a/src/main/java/electrosphere/entity/scene/SceneLoader.java b/src/main/java/electrosphere/entity/scene/SceneLoader.java index 1ea2b682..0b12cc9f 100644 --- a/src/main/java/electrosphere/entity/scene/SceneLoader.java +++ b/src/main/java/electrosphere/entity/scene/SceneLoader.java @@ -22,7 +22,9 @@ public class SceneLoader { /** * Loads a scene file on the server - * @param path The name of the save to look for a scene file within + * @param saveName The name of the save + * @param serverWorldData the server world data + * @param isLevelEditor true if this is a level editor, false otherwise */ public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData, boolean isLevelEditor){ //load scene file @@ -33,7 +35,9 @@ public class SceneLoader { /** * Loads a scene file on the server - * @param path The name of the scene in the assets/scenes folder + * @param sceneName The name of the scene + * @param serverWorldData the server world data + * @param isLevelEditor true if this is a level editor, false otherwise */ public static void serverInstantiateAssetSceneFile(String sceneName, ServerWorldData serverWorldData, boolean isLevelEditor){ //load scene file @@ -80,6 +84,10 @@ public class SceneLoader { case RealmDescriptor.REALM_DESCRIPTOR_PROCEDURAL: { realm = Globals.realmManager.createGriddedRealm(serverWorldData,serverContentManager); } break; + case RealmDescriptor.REALM_DESCRIPTOR_GENERATION_TESTING: { + ServerWorldData newWorldData = ServerWorldData.createGenerationTestWorldData(); + realm = Globals.realmManager.createGriddedRealm(newWorldData, serverContentManager); + } break; default: { throw new Error("Unhandled case! " + file.realmDescriptor.getType()); } diff --git a/src/main/java/electrosphere/game/server/world/ServerWorldData.java b/src/main/java/electrosphere/game/server/world/ServerWorldData.java index f4bc03f3..7b60192a 100644 --- a/src/main/java/electrosphere/game/server/world/ServerWorldData.java +++ b/src/main/java/electrosphere/game/server/world/ServerWorldData.java @@ -3,6 +3,7 @@ package electrosphere.game.server.world; import electrosphere.server.fluid.generation.DefaultFluidGenerator; import electrosphere.server.fluid.manager.ServerFluidManager; import electrosphere.server.terrain.generation.DefaultChunkGenerator; +import electrosphere.server.terrain.generation.TestGenerationChunkGenerator; import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.util.FileUtils; @@ -133,6 +134,27 @@ public class ServerWorldData { serverWorldData.setManagers(serverTerrainManager, serverFluidManager); return serverWorldData; } + + /** + * Creates world data for testing generation + * @return The server world data + */ + public static ServerWorldData createGenerationTestWorldData(){ + // + //Read world data if it exists + // + ServerWorldData serverWorldData = null; + ServerTerrainManager serverTerrainManager = null; + ServerFluidManager serverFluidManager = null; + //TODO: Allow loading procedurally generated terrain from disk (the chunk generator is always default currently) + serverWorldData = ServerWorldData.createFixedWorldData(new Vector3d(0),new Vector3d(16 * 4 * 4)); + serverWorldData.worldSizeDiscrete = TestGenerationChunkGenerator.GENERATOR_REALM_SIZE; + serverWorldData.worldSizeDiscreteVertical = TestGenerationChunkGenerator.GENERATOR_REALM_SIZE; + serverTerrainManager = new ServerTerrainManager(serverWorldData, 0, new TestGenerationChunkGenerator()); + serverFluidManager = new ServerFluidManager(serverWorldData, serverTerrainManager, 0, new DefaultFluidGenerator()); + serverWorldData.setManagers(serverTerrainManager, serverFluidManager); + return serverWorldData; + } public Vector3f getWorldBoundMin(){ diff --git a/src/main/java/electrosphere/server/db/DatabaseController.java b/src/main/java/electrosphere/server/db/DatabaseController.java index 8b44e295..5dd4cea2 100644 --- a/src/main/java/electrosphere/server/db/DatabaseController.java +++ b/src/main/java/electrosphere/server/db/DatabaseController.java @@ -13,12 +13,20 @@ import java.util.Properties; */ public class DatabaseController { + /** + * The database connection + */ Connection conn; - public DatabaseController(){ - - } + /** + * Constructor + */ + public DatabaseController(){ } + /** + * Connects to a database + * @param path The path to the database + */ public void connect(String path){ String dbms = "sqlite"; Properties connectionProps = new Properties(); @@ -107,6 +115,10 @@ public class DatabaseController { return rVal; } + /** + * Checks of the connection is actually connected + * @return true if connected, false otherwise + */ public boolean isConnected(){ boolean rVal = false; if(conn == null){ @@ -120,6 +132,9 @@ public class DatabaseController { return rVal; } + /** + * Disconnects from the database + */ public void disconnect(){ try { conn.close(); diff --git a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java new file mode 100644 index 00000000..767eda01 --- /dev/null +++ b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java @@ -0,0 +1,104 @@ +package electrosphere.server.terrain.generation; + +import java.util.Arrays; + +import electrosphere.server.terrain.generation.interfaces.ChunkGenerator; +import electrosphere.server.terrain.manager.ServerTerrainChunk; +import electrosphere.server.terrain.models.TerrainModel; + +/** + * A generator for testing terrain generation + */ +public class TestGenerationChunkGenerator implements ChunkGenerator { + + /** + * The size of the realm for testing generation + */ + public static final int GENERATOR_REALM_SIZE = 10; + + /** + * The terreain model for the generator + */ + TerrainModel terrainModel; + + @Override + public ServerTerrainChunk generateChunk(int worldX, int worldY, int worldZ) { + ServerTerrainChunk rVal = null; + float[][][] weights; + int[][][] values; + + if(worldX == 0 || worldZ == 0){ + //generate flat ground for the player to spawn on + weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + values = new int[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ + for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){ + Arrays.fill(weights[x][y],-1f); + } + } + if(worldY == 0){ + for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){ + for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){ + values[x][0][z] = 1; + weights[x][0][z] = 0.1f; + } + } + } + + + + } else { + //actual generation algo + weights = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + values = new int[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; + 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++){ + weights[x][y][z] = this.getChunkWeight(worldX, worldY, worldZ, x, y, z, this.terrainModel); + values[x][y][z] = this.getChunkValue(worldX, worldY, worldZ, x, y, z, this.terrainModel); + } + } + } + } + + rVal = new ServerTerrainChunk(worldX, worldY, worldZ, weights, values); + return rVal; + } + + @Override + public void setModel(TerrainModel model) { + this.terrainModel = model; + } + + + /** + * Gets the value for a chunk + * @param worldX The world x pos + * @param worldY The world y pos + * @param worldZ The world z pos + * @param chunkX The chunk x pos + * @param chunkY The chunk y pos + * @param chunkZ The chunk z pos + * @param terrainModel The terrain model + * @return The value of the chunk + */ + private int getChunkValue(int worldX, int worldY, int worldZ, int chunkX, int chunkY, int chunkZ, TerrainModel terrainModel){ + return 1; + } + + /** + * Gets the weight for a chunk + * @param worldX The world x pos + * @param worldY The world y pos + * @param worldZ The world z pos + * @param chunkX The chunk x pos + * @param chunkY The chunk y pos + * @param chunkZ The chunk z pos + * @param terrainModel The terrain model + * @return The weight of the chunk + */ + private float getChunkWeight(int worldX, int worldY, int worldZ, int chunkX, int chunkY, int chunkZ, TerrainModel terrainModel){ + return 0.1f; + } + +} diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java index cfef1213..0c59f5ba 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainChunk.java @@ -12,16 +12,54 @@ import electrosphere.server.terrain.models.TerrainModification; */ public class ServerTerrainChunk { - //all chunks are 16x16x16 + /** + * All chunks are 16x16x16 + */ public static final int CHUNK_DIMENSION = 16; - //The size of the data passed into marching cubes/transvoxel to generate a fully connected and seamless chunk + + /** + * The size of the data passed into marching cubes/transvoxel to generate a fully connected and seamless chunk + */ public static final int CHUNK_DATA_GENERATOR_SIZE = CHUNK_DIMENSION + 1; - int worldX, worldY, worldZ; + /** + * Gets the x coordinate of the world position of the chunk + */ + int worldX; + + /** + * Gets the y coordinate of the world position of the chunk + */ + int worldY; + + /** + * Gets the z coordinate of the world position of the chunk + */ + int worldZ; + + /** + * The list of modifications applied to the chunk + */ List modifications = new LinkedList(); + + /** + * The weights of the chunk + */ float[][][] weights; + + /** + * The values of the chunk + */ int[][][] values; + /** + * Constructor + * @param worldX The world position x coordinate + * @param worldY The world position y coordinate + * @param worldZ The world position z coordinate + * @param weights The weights of the chunk + * @param values The values of the chunk + */ public ServerTerrainChunk(int worldX, int worldY, int worldZ, float[][][] weights, int[][][] values) { this.worldX = worldX; this.worldY = worldY; @@ -30,18 +68,38 @@ public class ServerTerrainChunk { this.values = values; } + /** + * Gets the world position x coordinate + * @return The x coordinate + */ public int getWorldX() { return worldX; } + /** + * Gets the world position y coordinate + * @return The y coordinate + */ public int getWorldY() { return worldY; } + /** + * Gets the world position z coordinate + * @return The z coordinate + */ public int getWorldZ() { return worldZ; } + /** + * Gets the world position of the chunk + * @return The world position + */ + public Vector3i getWorldPos(){ + return new Vector3i(worldX,worldY,worldZ); + } + /** * Gets the world position of this terrain chunk as a joml Vector * @return The vector @@ -50,18 +108,34 @@ public class ServerTerrainChunk { return new Vector3i(worldX,worldY,worldZ); } + /** + * Gets the list of all modifications applied to the chunk + * @return THe list of all modifications + */ public List getModifications() { return modifications; } + /** + * Gets the weights of the chunk + * @return The weights of the chunk + */ public float[][][] getWeights() { return weights; } + /** + * Gets the values of the chunk + * @return The values of the chunk + */ public int[][][] getValues() { return values; } + /** + * Adds a modification to the chunk + * @param modification The modification + */ public void addModification(TerrainModification modification){ modifications.add(modification); values[modification.getVoxelPos().x][modification.getVoxelPos().y][modification.getVoxelPos().z] = modification.getValue(); diff --git a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java index ae5ce340..fc2889a8 100644 --- a/src/main/java/electrosphere/server/terrain/models/TerrainModel.java +++ b/src/main/java/electrosphere/server/terrain/models/TerrainModel.java @@ -5,25 +5,63 @@ import java.util.Map; import electrosphere.util.annotation.Exclude; +/** + * The model of the terrain + */ public class TerrainModel { + + /** + * The dynamic interpolation ratio + */ int dynamicInterpolationRatio; + + /** + * The interpolation dampener + */ float interpolationRandomDampener = 0.4f; + /** + * The discrete array dimension of the model + */ int discreteArrayDimension; + + /** + * The macro level elevation data + */ @Exclude private float[][] elevation; + /** + * The real coordinate mountain threshold + */ float realMountainThreshold; + + /** + * The real coordinate ocean threshold + */ float realOceanThreshold; + /** + * The map of modifications applied to the model + */ Map modifications; - + /** + * Private constructor + */ TerrainModel() { this.modifications = new HashMap(); } + /** + * Constructor + * @param dimension The dimension of the model + * @param elevation The macro elevation data + * @param realOceanThreshold The real coordinate ocean threshold + * @param realMountainThreshold The real coordinate mountain threshold + * @param dynamicInterpolationRatio The dynamic interpolation ratio + */ public TerrainModel( int dimension, float[][] elevation, @@ -40,6 +78,12 @@ public class TerrainModel { this.modifications = new HashMap(); } + /** + * Constructs a terrain model + * @param dimension The dimension of the terrain model + * @param dynamicInterpolationRatio The dynamic interpolation ratio + * @return The terrain model + */ public static TerrainModel constructTerrainModel(int dimension, int dynamicInterpolationRatio){ TerrainModel rVal = new TerrainModel(); rVal.discreteArrayDimension = dimension; @@ -47,10 +91,18 @@ public class TerrainModel { return rVal; } + /** + * Gets the macro elevation data for the terrain model + * @return The macro elevation data + */ public float[][] getElevation(){ return elevation; } + /** + * Gets the interpolation random dampener + * @param f The interpolation random dampener + */ public void setInterpolationRandomDampener(float f){ interpolationRandomDampener = f; } @@ -205,6 +257,12 @@ public class TerrainModel { */ + /** + * Gets the macro values at a position + * @param x The world x position + * @param y The world y position + * @return The macro values + */ public float[][] getMacroValuesAtPosition(int x, int y){ float[][] rVal = new float[3][3]; @@ -260,7 +318,12 @@ public class TerrainModel { - + /** + * Gets the 5-radius macro values at a position + * @param x The x position + * @param y The y position + * @return The macro values + */ public float[][] getRad5MacroValuesAtPosition(int x, int y){ float[][] rVal = new float[5][5]; @@ -305,26 +368,53 @@ public class TerrainModel { */ + /** + * Gets the random dampener for the model + * @return The random dampener + */ public float getRandomDampener(){ return interpolationRandomDampener; } + /** + * Gets the dynamic interpolation ratio + * @return The ratio + */ public int getDynamicInterpolationRatio(){ return dynamicInterpolationRatio; } + /** + * Gets the real coordinate mountain threshold + * @return The threshold + */ public float getRealMountainThreshold() { return realMountainThreshold; } + /** + * Gets the real coordinate ocean threshold + * @return The threshold + */ 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; @@ -337,12 +427,25 @@ public class TerrainModel { 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){ -// System.out.println("Got modifications at " + worldX + " " + worldY); return modifications.get(getModificationKey(worldX, worldY, worldZ)); }