diff --git a/src/main/java/com/halotroop/litecraft/Litecraft.java b/src/main/java/com/halotroop/litecraft/Litecraft.java deleted file mode 100644 index 4eb3ae5..0000000 --- a/src/main/java/com/halotroop/litecraft/Litecraft.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.halotroop.litecraft; - -import org.joml.*; - -import com.github.hydos.ginger.engine.common.Constants; -import com.github.hydos.ginger.engine.common.api.*; -import com.github.hydos.ginger.engine.common.api.game.*; -import com.github.hydos.ginger.engine.common.cameras.*; -import com.github.hydos.ginger.engine.common.elements.objects.Light; -import com.github.hydos.ginger.engine.common.font.FontType; -import com.github.hydos.ginger.engine.common.info.RenderAPI; -import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.common.obj.ModelLoader; -import com.github.hydos.ginger.engine.opengl.api.GingerGL; -import com.github.hydos.ginger.engine.opengl.postprocessing.PostProcessing; -import com.github.hydos.ginger.engine.opengl.render.*; -import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; -import com.github.hydos.ginger.engine.opengl.utils.*; -import com.halotroop.litecraft.render.BlockRenderer; -import com.halotroop.litecraft.save.LitecraftSave; -import com.halotroop.litecraft.screens.*; -import com.halotroop.litecraft.types.block.Blocks; -import com.halotroop.litecraft.types.entity.PlayerEntity; -import com.halotroop.litecraft.util.RelativeDirection; -import com.halotroop.litecraft.world.World; - -import tk.valoeghese.gateways.client.io.*; - -public class Litecraft extends Game -{ - // FIXME: search for ((GingerGL)engine) and properly implement both render APIs when Vulkan is complete. - private static Litecraft INSTANCE; - private World world; - private LitecraftSave save; - private GingerEngine engine; - public int fps, ups, tps; - public Vector4i dbgStats = new Vector4i(); - private long frameTimer; - private BlockRenderer blockRenderer; - - public Litecraft(int windowWidth, int windowHeight, float frameLimit) - { - Litecraft.INSTANCE = this; - // set constants - this.setupConstants(); - this.setupGinger(windowWidth, windowHeight, frameLimit); - // make sure blocks are initialised ??? (Currently does nothing) - Blocks.init(); - this.frameTimer = System.currentTimeMillis(); - // setup keybinds - setupKeybinds(); - // Open the title screen if nothing is already open. - if (GingerRegister.getInstance().currentScreen == null && world == null) ((GingerGL) engine).openScreen(new TitleScreen()); - // start the game loop - this.engine.startGameLoop(); - } - - @Override - public void exit() - { - engine.openScreen(new ExitGameScreen()); - render(); // Render the exit game screen - if (this.world != null) - { - System.out.println("Saving chunks..."); - long time = System.currentTimeMillis(); - this.world.unloadAllChunks(); - this.getSave().saveGlobalData(this.world.getSeed(), ((PlayerEntity) this.player)); - System.out.println("Saved world in " + (System.currentTimeMillis() - time) + " milliseconds"); - } - engine.cleanup(); - System.exit(0); - } - - /** Things that ARE rendering: Anything that results in something being drawn to the frame buffer - * Things that are NOT rendering: Things that happen to update between frames but do not result in things being drawn to the screen */ - @Override - public void render() - { - fps += 1; - if (System.currentTimeMillis() > frameTimer + 1000) updateDebugStats(); - // Render shadows - GingerRegister.getInstance().masterRenderer.renderShadowMap(data.entities, data.lights.get(0)); - // If there's a world, render it! - if (this.world != null) renderWorld(); - // Render any overlays (GUIs, HUDs) - this.engine.renderOverlays(); - // Put what's stored in the inactive framebuffer on the screen - Window.swapBuffers(); - } - - // Updates the debug stats once per real-time second, regardless of how many frames have been rendered - private void updateDebugStats() - { - this.dbgStats.set(fps, ups, tps, 0); - this.fps = 0; - this.ups = 0; - this.tps = 0; - this.frameTimer += 1000; - } - - public void renderWorld() - { - GameData data = GingerRegister.getInstance().game.data; - if (Window.renderAPI == RenderAPI.OpenGL) - { - GLUtils.preRenderScene(((GingerGL) engine).getRegistry().masterRenderer); - ((GingerGL) engine).contrastFbo.bindFBO(); - ((GingerGL) engine).getRegistry().masterRenderer.renderScene(data.entities, data.normalMapEntities, data.lights, data.camera, data.clippingPlane); - ((GingerGL) engine).contrastFbo.unbindFBO(); - PostProcessing.doPostProcessing(((GingerGL) engine).contrastFbo.colorTexture); - } - } - - @Override - public void update() - { ups += 1; } - - private void setupConstants() - { - Constants.movementSpeed = 0.5f; // movement speed - Constants.turnSpeed = 0.00006f; // turn speed - Constants.gravity = new Vector3f(0, -0.0000000005f, 0); // compute gravity as a vec3f - Constants.jumpPower = 0.00005f; // jump power - } - - // set up Ginger3D engine stuff - private void setupGinger(int windowWidth, int windowHeight, float frameCap) - { - if (engine == null) // Prevents this from being run more than once on accident. - { - Window.create(windowWidth, windowHeight, "Litecraft", frameCap, RenderAPI.OpenGL); // create window - // set up the gateways keybind key tracking - KeyCallbackHandler.trackWindow(Window.getWindow()); - MouseCallbackHandler.trackWindow(Window.getWindow()); - // set up ginger utilities - GLUtils.init(); - switch (Window.renderAPI) - { - case OpenGL: - { - this.engine = new GingerGL(); - //Set the player model - GLTexturedModel playerModel = ModelLoader.loadGenericCube("block/cubes/stone/brick/stonebrick.png"); - FontType font = new FontType(GLLoader.loadFontAtlas("candara.png"), "candara.fnt"); - this.blockRenderer = new BlockRenderer(GingerRegister.getInstance().masterRenderer.getEntityShader(), GingerRegister.getInstance().masterRenderer.getProjectionMatrix()); - this.player = new PlayerEntity(playerModel, new Vector3f(0, 0, -3), 0, 180f, 0, new Vector3f(0.2f, 0.2f, 0.2f)); - this.camera = new FirstPersonCamera(player); - this.data = new GameData(this.player, this.camera, 20); - this.data.handleGuis = false; - ((GingerGL) engine).setup(new GLRenderManager(this.camera), INSTANCE); - ((GingerGL) engine).setGlobalFont(font); - this.data.entities.add(this.player); - break; - } - case Vulkan: - { - // TODO: Setup Vulkan - exit(); - break; - } - } - Light sun = new Light(new Vector3f(0, 105, 0), new Vector3f(0.9765625f, 0.98828125f, 0.05859375f), new Vector3f(0.002f, 0.002f, 0.002f)); - this.data.lights.add(sun); - } - } - - private void setupKeybinds() - { - Input.addPressCallback(Keybind.EXIT, this::exit); - Input.addInitialPressCallback(Keybind.FULLSCREEN, Window::fullscreen); - Input.addInitialPressCallback(Keybind.WIREFRAME, GingerRegister.getInstance()::toggleWireframe); - Input.addPressCallback(Keybind.MOVE_FORWARD, () -> ((PlayerEntity) this.player).move(RelativeDirection.FORWARD)); - Input.addPressCallback(Keybind.MOVE_BACKWARD, () -> ((PlayerEntity) this.player).move(RelativeDirection.BACKWARD)); - Input.addPressCallback(Keybind.STRAFE_LEFT, () -> ((PlayerEntity) this.player).move(RelativeDirection.LEFT)); - Input.addPressCallback(Keybind.STRAFE_RIGHT, () -> ((PlayerEntity) this.player).move(RelativeDirection.RIGHT)); - Input.addPressCallback(Keybind.FLY_UP, () -> ((PlayerEntity) this.player).move(RelativeDirection.UP)); - Input.addPressCallback(Keybind.FLY_DOWN, () -> ((PlayerEntity) this.player).move(RelativeDirection.DOWN)); - } - - /** Things that should be ticked: Entities when deciding an action, in-game timers (such as smelting), the in-game time - * Things that should not be ticked: Rendering, input, player movement */ - @Override - public void tick() - { - tps += 1; - if (this.player instanceof PlayerEntity && camera != null) - { - Input.invokeAllListeners(); - ((PlayerEntity) this.player).updateMovement(); - camera.updateMovement(); - } - } - - // @formatter=off - public static Litecraft getInstance() - { return INSTANCE; } - - public Camera getCamera() - { return this.camera; } - - public LitecraftSave getSave() - { return save; } - - public World getWorld() - { return this.world; } - - public void changeWorld(World world) - { this.world = world; } - - public void setSave(LitecraftSave save) - { this.save = save; } - - @Override - public void renderScene() - { world.render(this.blockRenderer); } -} \ No newline at end of file diff --git a/src/main/java/com/halotroop/litecraft/StarterGL.java b/src/main/java/com/halotroop/litecraft/StarterGL.java deleted file mode 100644 index 103b325..0000000 --- a/src/main/java/com/halotroop/litecraft/StarterGL.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.halotroop.litecraft; - -import org.lwjgl.Version; -import org.lwjgl.glfw.GLFW; - -public class StarterGL -{ - // private static final boolean usingEclipse = false; - public static void main(String[] args) - { - System.out.println("GLFW version: " + GLFW.glfwGetVersionString()); - System.out.println("LWJGL version: " + Version.getVersion()); - // Put SoundSystem version here - // TODO: Put a commandline reader here to check for desired width, height, and frame limit! - new Litecraft(1280, 720, 60); - } -} diff --git a/src/main/java/com/halotroop/litecraft/logic/Gamemode.java b/src/main/java/com/halotroop/litecraft/logic/Gamemode.java deleted file mode 100644 index 7f0ab4d..0000000 --- a/src/main/java/com/halotroop/litecraft/logic/Gamemode.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.halotroop.litecraft.logic; - -public enum Gamemode -{ - GRAVITY, FREECAM, -} diff --git a/src/main/java/com/halotroop/litecraft/logic/SODSerializable.java b/src/main/java/com/halotroop/litecraft/logic/SODSerializable.java deleted file mode 100644 index d803081..0000000 --- a/src/main/java/com/halotroop/litecraft/logic/SODSerializable.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.halotroop.litecraft.logic; - -import tk.valoeghese.sod.BinaryData; - -public interface SODSerializable -{ - void read(BinaryData data); - - void write(BinaryData data); -} diff --git a/src/main/java/com/halotroop/litecraft/render/BlockRenderer.java b/src/main/java/com/halotroop/litecraft/render/BlockRenderer.java deleted file mode 100644 index cccc222..0000000 --- a/src/main/java/com/halotroop/litecraft/render/BlockRenderer.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.halotroop.litecraft.render; - -import org.joml.Matrix4f; -import org.lwjgl.opengl.*; - -import com.github.hydos.ginger.engine.common.api.GingerRegister; -import com.github.hydos.ginger.engine.common.elements.objects.RenderObject; -import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.common.math.Maths; -import com.github.hydos.ginger.engine.opengl.render.Renderer; -import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; -import com.github.hydos.ginger.engine.opengl.render.shaders.StaticShader; -import com.halotroop.litecraft.types.block.BlockInstance; -import com.halotroop.litecraft.world.gen.WorldGenConstants; - -public class BlockRenderer extends Renderer implements WorldGenConstants -{ - public StaticShader shader; - public int atlasID; - - public BlockRenderer(StaticShader shader, Matrix4f projectionMatrix) - { - this.shader = shader; - shader.start(); - shader.loadProjectionMatrix(projectionMatrix); - shader.stop(); - this.atlasID = VoxelLoader.createBlockAtlas(); - } - - private void prepBlockInstance(RenderObject entity) - { - Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotX(), - entity.getRotY(), entity.getRotZ(), entity.getScale()); - shader.loadTransformationMatrix(transformationMatrix); - } - - public void prepareModel(GLTexturedModel model) - { - GL30.glBindVertexArray(model.getRawModel().getVaoID()); - GL20.glEnableVertexAttribArray(0); - GL20.glEnableVertexAttribArray(1); - GL20.glEnableVertexAttribArray(2); - } - - public void unbindModel() - { - GL20.glDisableVertexAttribArray(0); - GL20.glDisableVertexAttribArray(1); - GL20.glDisableVertexAttribArray(2); - GL30.glBindVertexArray(0); - } - - public void enableWireframe() - { if (GingerRegister.getInstance().wireframe) - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); } - - public void disableWireframe() - { if (GingerRegister.getInstance().wireframe) - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); } - - public void prepareRender() - { - // TODO: combine VBOS - shader.start(); - shader.loadSkyColour(Window.getColour()); - shader.loadViewMatrix(GingerRegister.getInstance().game.data.camera); - shader.loadFakeLightingVariable(true); - shader.loadShine(1, 1); - GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, atlasID); - enableWireframe(); - } - - public void render(BlockInstance[] renderList) - { - prepareRender(); - for (BlockInstance entity : renderList) - { - if (entity != null && entity.getModel() != null) - { - GLTexturedModel blockModel = entity.getModel(); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockModel.getTexture().getTextureID()); - prepBlockInstance(entity); - GL11.glDrawElements(GL11.GL_TRIANGLES, blockModel.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); - } - } - // disableWireframe(); - // shader.stop(); - } -} diff --git a/src/main/java/com/halotroop/litecraft/render/VoxelLoader.java b/src/main/java/com/halotroop/litecraft/render/VoxelLoader.java deleted file mode 100644 index 1126882..0000000 --- a/src/main/java/com/halotroop/litecraft/render/VoxelLoader.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.halotroop.litecraft.render; - -import java.nio.ByteBuffer; - -import org.lwjgl.opengl.*; - -import com.github.hydos.ginger.engine.opengl.utils.GLLoader; -import com.halotroop.litecraft.types.block.*; - -public class VoxelLoader extends GLLoader -{ - public static int createBlockAtlas() - { - int width = 16; - int height = 16; - //Prepare the atlas texture and gen it - int atlasId = GL11.glGenTextures(); - //Bind it to openGL - GL11.glBindTexture(GL11.GL_TEXTURE_2D, atlasId); - //Apply the settings for the texture - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); - //Fill the image with blank image data - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width * 2, height * 2, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null); - long maxX = Math.round(Math.sqrt(Blocks.blocks.size())); - int currentX = 0; - int currentY = 0; - for (Block block : Blocks.blocks) - { - //just in case - if (!block.texture.equals("DONTLOAD")) - { - System.out.println(block.texture); - block.updateBlockModelData(); - if (currentX > maxX) - { - currentX = 0; - currentY--; - } - GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, - currentX * width, currentY * height, - width, height, - GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, - block.model.getTexture().getTexture().getImage()); - currentX++; - } - } - return atlasId; - } -} diff --git a/src/main/java/com/halotroop/litecraft/save/LitecraftSave.java b/src/main/java/com/halotroop/litecraft/save/LitecraftSave.java deleted file mode 100644 index 1ad0088..0000000 --- a/src/main/java/com/halotroop/litecraft/save/LitecraftSave.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.halotroop.litecraft.save; - -import java.io.*; -import java.util.Random; - -import org.joml.Vector3f; - -import com.github.hydos.ginger.engine.common.cameras.Camera; -import com.halotroop.litecraft.Litecraft; -import com.halotroop.litecraft.types.entity.PlayerEntity; -import com.halotroop.litecraft.world.*; -import com.halotroop.litecraft.world.dimension.Dimension; - -import tk.valoeghese.sod.*; - -public final class LitecraftSave -{ - public LitecraftSave(String name, boolean mustCreateNew) - { - StringBuilder sb = new StringBuilder(SAVE_DIR).append(name); - File saveDir = new File(sb.toString()); - if (mustCreateNew) - { - while (saveDir.exists()) - { - sb.append('_'); // append "_" to the save name until we get a unique save, if we must create a new save - saveDir = new File(sb.toString()); - } - } - this.file = saveDir; - this.file.mkdirs(); - } - - private final File file; - - public boolean saveChunk(Chunk chunk) - { - StringBuilder fileLocBuilder = new StringBuilder(this.file.getPath()) - .append('/').append(Dimension.getById(chunk.dimension).saveIdentifier) - .append('/').append(chunk.chunkX) - .append('/').append(chunk.chunkZ); - File chunkDir = new File(fileLocBuilder.toString()); - chunkDir.mkdirs(); // create directory for file if it does not exist - // format: ////.sod - File chunkFile = new File(fileLocBuilder.append('/').append(chunk.chunkY).append(".sod").toString()); - try - { - chunkFile.createNewFile(); - BinaryData data = new BinaryData(); // create new empty binary data - chunk.write(data); // write the chunk info to the binary data - return data.write(chunkFile); // write the data to the file, return whether an io exception occurred - } - catch (IOException e) - { - e.printStackTrace(); - return false; // io exception = chunk writing failed at some point - } - } - - public Chunk readChunk(World world, int chunkX, int chunkY, int chunkZ, int dimension) - { - // format: ////.sod - File chunkFile = new File(new StringBuilder(this.file.getPath()) - .append('/').append(Dimension.getById(dimension).saveIdentifier) - .append('/').append(chunkX) - .append('/').append(chunkZ) - .append('/').append(chunkY).append(".sod").toString()); - if (chunkFile.isFile()) - { - BinaryData data = BinaryData.read(chunkFile); - Chunk result = new Chunk(world, chunkX, chunkY, chunkZ, dimension); // create chunk - result.read(data); // load the chunk data we have just read into the chunk - return result; - } - else return null; - } - - public World getWorldOrCreate(Dimension dim) - { - File globalDataFile = new File(this.file.getPath() + "/global_data.sod"); - if (globalDataFile.isFile()) // load world - { - BinaryData data = BinaryData.read(globalDataFile); // read data from the world file - DataSection properties = data.get("properties"); // get the properties data section from the data that we have just read - DataSection playerData = data.get("player"); - long seed = 0; // default seed if we cannot read it is 0 - float playerX = 0, playerY = 0, playerZ = -3; // default player x/y/z - float playerYaw = 0.0f; - try // try read the seed from the file - { - seed = properties.readLong(0); // seed is at index 0 - playerX = playerData.readFloat(0); // player x/y/z is at index 0/1/2 respectively - playerY = playerData.readFloat(1); - playerZ = playerData.readFloat(2); - Camera camera = Litecraft.getInstance().getCamera(); // get camera - camera.setPitch(playerData.readFloat(3)); // read pitch, yaw, roll from 3/4/5 - playerYaw = playerData.readFloat(4); - camera.setYaw(playerYaw); - camera.setRoll(playerData.readFloat(5)); - } - catch (Throwable e) - { - System.out.println("Exception in reading save data! This may be benign, merely an artifact of an update to the contents of the world save data."); - } - World world = new World(seed, RENDER_SIZE, dim, this); // create new world with seed read from file or 0, if it could not be read - world.spawnPlayer(playerX, playerY, playerZ); // spawn player in world - return world; - } - else // create world - { - long seed = new Random().nextLong(); - try - { - globalDataFile.createNewFile(); // create world file - this.writeGlobalData(globalDataFile, seed, new Vector3f(0, 0, -3)); // write global data with default player pos - } - catch (IOException e) - { - // If this fails the world seed will not be consistent across saves - e.printStackTrace(); - } - World world = new World(seed, RENDER_SIZE, dim, this); // create new world with generated seed - world.spawnPlayer(); // spawn player in world - return world; - } - } - - public void saveGlobalData(long seed, PlayerEntity playerEntity) - { - try - { - File globalDataFile = new File(this.file.getPath() + "/global_data.sod"); - globalDataFile.createNewFile(); // create world file if it doesn't exist. - writeGlobalData(globalDataFile, seed, playerEntity.getPosition()); - } - catch (IOException e) - { - System.err.println("A critical error occurred while trying to save world data!"); - e.printStackTrace(); - } - } - - private void writeGlobalData(File globalDataFile, long seed, Vector3f playerPos) - { - BinaryData data = new BinaryData(); // create empty binary data - DataSection properties = new DataSection(); // create empty data section for properties - properties.writeLong(seed); // write seed at index 0 - DataSection playerData = new DataSection(); - playerData.writeFloat(playerPos.x); // default spawn player x/y/z - playerData.writeFloat(playerPos.y); - playerData.writeFloat(playerPos.z); - Camera camera = Litecraft.getInstance().getCamera(); - playerData.writeFloat(camera.getPitch()); - playerData.writeFloat(camera.getYaw()); - playerData.writeFloat(camera.getRoll()); - data.put("properties", properties); // add properties section to data - data.put("player", playerData); // add player section to data - data.write(globalDataFile); // write to file - } - - private static final String SAVE_DIR = "./saves/"; - private static final int RENDER_SIZE = 5; -} diff --git a/src/main/java/com/halotroop/litecraft/screens/ExitGameScreen.java b/src/main/java/com/halotroop/litecraft/screens/ExitGameScreen.java deleted file mode 100644 index ff2affb..0000000 --- a/src/main/java/com/halotroop/litecraft/screens/ExitGameScreen.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.halotroop.litecraft.screens; - -import org.joml.Vector2f; - -import com.github.hydos.ginger.engine.common.api.GingerEngine; -import com.github.hydos.ginger.engine.common.font.GUIText; -import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.common.screen.Screen; -import com.github.hydos.ginger.engine.opengl.api.GingerGL; - -public class ExitGameScreen extends Screen -{ - private GUIText infoText; - // TODO: Add Vulkan text renderer - private GingerEngine engine = GingerGL.getInstance(); - - public ExitGameScreen() - { - infoText = ((GingerGL) engine).registerText("Saving and exiting...", 3, new Vector2f(Window.getWidth() / 2, Window.getHeight() / 2), 1f, true, "info"); - infoText.setBorderWidth(0.5f); - } - - @Override - public void render() - {} - - @Override - public void tick() - {} - - @Override - public void cleanup() - { infoText.remove(); } -} diff --git a/src/main/java/com/halotroop/litecraft/screens/IngameHUD.java b/src/main/java/com/halotroop/litecraft/screens/IngameHUD.java deleted file mode 100644 index f9a2265..0000000 --- a/src/main/java/com/halotroop/litecraft/screens/IngameHUD.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.halotroop.litecraft.screens; - -import org.joml.*; - -import com.github.hydos.ginger.engine.common.api.*; -import com.github.hydos.ginger.engine.common.font.GUIText; -import com.github.hydos.ginger.engine.common.screen.Screen; -import com.github.hydos.ginger.engine.opengl.api.GingerGL; -import com.halotroop.litecraft.Litecraft; - -public class IngameHUD extends Screen -{ - private GUIText debugText; - private GUIText positionText; - // TODO: Add Vulkan text renderer - private GingerEngine engine = GingerGL.getInstance(); - private Litecraft litecraft = Litecraft.getInstance(); - - public IngameHUD() - { - debugText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo"); - debugText.setBorderWidth(0.5f); - positionText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, -0.1f), 1f, true, "posInfo"); - positionText.setBorderWidth(0.5f); - } - - @Override - public void render() - {} - - @Override - public void tick() - { - // long maxMemory = Runtime.getRuntime().maxMemory(); - long totalMemory = Runtime.getRuntime().totalMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - long usedMemory = (totalMemory - freeMemory) / 1024 / 1024; - Vector4i dbg = litecraft.dbgStats; - Vector3f position = GingerRegister.getInstance().game.data.playerObject.getPosition(); - debugText.setText("FPS: " + dbg.x() + " UPS: " + dbg.y() + " TPS: " + dbg.z() + " TWL: " + dbg.w() + " Mem: " + usedMemory + "MB"); - positionText.setText("Position: " + (int) position.x() + ", " + (int) position.y() + ", " + (int) position.z()); - } - - @Override - public void cleanup() - { - debugText.remove(); - positionText.remove(); - } -} diff --git a/src/main/java/com/halotroop/litecraft/screens/TitleScreen.java b/src/main/java/com/halotroop/litecraft/screens/TitleScreen.java deleted file mode 100644 index f6948ef..0000000 --- a/src/main/java/com/halotroop/litecraft/screens/TitleScreen.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.halotroop.litecraft.screens; - -import java.util.ArrayList; - -import org.joml.*; - -import com.github.hydos.ginger.engine.common.api.GingerEngine; -import com.github.hydos.ginger.engine.common.elements.GuiTexture; -import com.github.hydos.ginger.engine.common.elements.buttons.TextureButton; -import com.github.hydos.ginger.engine.common.font.GUIText; -import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.common.screen.Screen; -import com.github.hydos.ginger.engine.opengl.api.GingerGL; -import com.halotroop.litecraft.Litecraft; -import com.halotroop.litecraft.save.LitecraftSave; -import com.halotroop.litecraft.world.dimension.Dimensions; - -/** YeS */ -public class TitleScreen extends Screen -{ - private GUIText debugText; - // TODO: Add Vulkan text renderer - private GingerEngine engine = GingerGL.getInstance(); - private TextureButton playButton; - private Litecraft litecraft = Litecraft.getInstance(); - - public TitleScreen() - { - elements = new ArrayList(); - playButton = ((GingerGL) engine).registerButton("/textures/guis/playbutton.png", new Vector2f(0, 0), new Vector2f(0.25f, 0.1f)); - playButton.show(Litecraft.getInstance().data.guis); - debugText = ((GingerGL) engine).registerText("Loading...", 2, new Vector2f(0, 0), 1f, true, "debugInfo"); - debugText.setBorderWidth(0.5f); - } - - @Override - public void render() - {} - - @Override - public void tick() - { - Vector4i dbg = litecraft.dbgStats; - debugText.setText("FPS: " + dbg.x() + " UPS: " + dbg.y() + " TPS: " + dbg.z() + " TWL: " + dbg.w()); - playButton.update(); - if (playButton.isClicked()) - { - Window.lockMouse(); - if (Litecraft.getInstance().getWorld() == null) - { - Litecraft.getInstance().setSave(new LitecraftSave("SegregatedOrdinalData", false)); - Litecraft.getInstance().changeWorld(Litecraft.getInstance().getSave().getWorldOrCreate(Dimensions.OVERWORLD)); - ((GingerGL) engine).setGingerPlayer(Litecraft.getInstance().getWorld().playerEntity); - } - if (Litecraft.getInstance().getWorld() != null) - { - ((GingerGL) engine).openScreen(new IngameHUD()); - this.cleanup(); - } - //TODO: add world creation gui so it takes u to world creation place - //TODO: add a texture to be rendered behind the gui as an option - } - } - - @Override - public void cleanup() - { - this.debugText.remove(); - this.playButton.hide(Litecraft.getInstance().data.guis); - } -} diff --git a/src/main/java/com/halotroop/litecraft/types/block/Block.java b/src/main/java/com/halotroop/litecraft/types/block/Block.java deleted file mode 100644 index 16aa74c..0000000 --- a/src/main/java/com/halotroop/litecraft/types/block/Block.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.halotroop.litecraft.types.block; - -import java.util.*; - -import com.github.hydos.ginger.engine.common.obj.ModelLoader; -import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; - -public class Block -{ - public static class Properties - { // add properties to this builder! - private boolean visible = true; - private boolean fullCube = true; - private float caveCarveThreshold = -1f; // cannot carve - private final String identifier; - - public Properties(String identifier) - { this.identifier = identifier; } - - public Properties fullCube(boolean fullCube) - { - this.fullCube = fullCube; - return this; - } - - public Properties visible(boolean visible) - { - this.visible = visible; - return this; - } - - public Properties caveCarveThreshold(float threshold) - { - this.caveCarveThreshold = threshold; - return this; - } - } - - public GLTexturedModel model; - private final boolean visible, fullCube; - private final float caveCarveThreshold; - public final String identifier; - public String texture; - - public boolean isFullCube() - { return this.fullCube; } - - public boolean isVisible() - { return this.visible; } - - public float getCaveCarveThreshold() - { return this.caveCarveThreshold; } - - protected Block(Properties properties) - { this((GLTexturedModel) null, properties); } - - protected Block(String texture, Properties properties) - { - this(ModelLoader.loadGenericCube("block/" + texture), properties); - this.texture = texture; - } - - protected Block(GLTexturedModel model, Properties properties) - { - this.model = model; - this.visible = properties.visible; - this.fullCube = properties.fullCube; - this.identifier = properties.identifier; - this.caveCarveThreshold = properties.caveCarveThreshold; - if (model != null) - { - this.texture = model.getTexture().getTexture().getLocation(); - } - else - { - this.texture = "DONTLOAD"; - } - IDENTIFIER_TO_BLOCK.put(this.identifier, this); - Blocks.blocks.add(this); - } - - public void updateBlockModelData() - { - System.out.println("Updating block with texture at block/" + texture); - this.model = ModelLoader.loadGenericCube("block/" + texture); - } - - public static final Block getBlock(String identifier) - { return IDENTIFIER_TO_BLOCK.get(identifier); } - - public static final Block getBlockOrAir(String identifier) - { return IDENTIFIER_TO_BLOCK.getOrDefault(identifier, Blocks.AIR); } - - private static final Map IDENTIFIER_TO_BLOCK = new HashMap<>(); -} diff --git a/src/main/java/com/halotroop/litecraft/types/block/BlockInstance.java b/src/main/java/com/halotroop/litecraft/types/block/BlockInstance.java deleted file mode 100644 index 32dcb7f..0000000 --- a/src/main/java/com/halotroop/litecraft/types/block/BlockInstance.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.halotroop.litecraft.types.block; - -import org.joml.Vector3f; - -import com.github.hydos.ginger.engine.common.elements.objects.RenderObject; -import com.halotroop.litecraft.world.Chunk; - -public class BlockInstance extends RenderObject -{ - public BlockInstance(Block block, Vector3f position) - { super(block.model, position, 0, 0, 0, new Vector3f(1f, 1f, 1f)); } - - public void processCulling(Chunk chunk) - { - Vector3f southNeighbourBlockLocation = this.getPosition(); - southNeighbourBlockLocation.x--; - } -} diff --git a/src/main/java/com/halotroop/litecraft/types/block/Blocks.java b/src/main/java/com/halotroop/litecraft/types/block/Blocks.java deleted file mode 100644 index 5aa198c..0000000 --- a/src/main/java/com/halotroop/litecraft/types/block/Blocks.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.halotroop.litecraft.types.block; - -import java.util.ArrayList; - -import com.halotroop.litecraft.types.block.Block.Properties; - -public final class Blocks -{ - public static ArrayList blocks = new ArrayList(); - public static final Block AIR = new Block(new Properties("air").visible(false).fullCube(false)); - public static final Block GRASS = new Block(new Properties("cubes/soil/grass/grass_top.png").caveCarveThreshold(0.04f)); - public static final Block DIRT = new Block("cubes/soil/dirt.png", new Properties("dirt").caveCarveThreshold(0.04f)); - public static final Block ANDESITE = new Block("cubes/stone/basic/andesite.png", new Properties("andesite").caveCarveThreshold(0.08f)); - public static final Block DIORITE = new Block("cubes/stone/basic/diorite.png", new Properties("diorite").caveCarveThreshold(0.05f)); - public static final Block GRANITE = new Block("cubes/stone/basic/granite.png", new Properties("granite").caveCarveThreshold(0.06f)); - public static final Block GNEISS = new Block("cubes/stone/basic/gneiss.png", new Properties("gneiss").caveCarveThreshold(0.09f)); - - public static Block init() - { return AIR; } -} diff --git a/src/main/java/com/halotroop/litecraft/types/entity/Entity.java b/src/main/java/com/halotroop/litecraft/types/entity/Entity.java deleted file mode 100644 index f9a704f..0000000 --- a/src/main/java/com/halotroop/litecraft/types/entity/Entity.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.halotroop.litecraft.types.entity; - -import org.joml.Vector3f; - -import com.github.hydos.ginger.engine.common.elements.objects.RenderObject; -import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; - -public abstract class Entity extends RenderObject -{ - public Entity(GLTexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, Vector3f scale) - { super(model, position, rotX, rotY, rotZ, scale); } -} diff --git a/src/main/java/com/halotroop/litecraft/types/entity/PlayerEntity.java b/src/main/java/com/halotroop/litecraft/types/entity/PlayerEntity.java deleted file mode 100644 index 8b2e2e4..0000000 --- a/src/main/java/com/halotroop/litecraft/types/entity/PlayerEntity.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.halotroop.litecraft.types.entity; - -import org.joml.Vector3f; - -import com.github.hydos.ginger.engine.common.Constants; -import com.github.hydos.ginger.engine.common.api.GingerRegister; -import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; -import com.halotroop.litecraft.Litecraft; -import com.halotroop.litecraft.util.RelativeDirection; -import com.halotroop.litecraft.world.gen.WorldGenConstants; - -public class PlayerEntity extends Entity implements WorldGenConstants -{ - private boolean isInAir = false; - private double upwardsSpeed; - private boolean noWeight = true; - private int chunkX, chunkY, chunkZ; - - public PlayerEntity(GLTexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, Vector3f scale) - { - super(model, position, rotX, rotY, rotZ, scale); - this.chunkX = (int) position.x >> POS_SHIFT; - this.chunkY = (int) position.y >> POS_SHIFT; - this.chunkZ = (int) position.z >> POS_SHIFT; - } - - public void move(RelativeDirection direction) - { - float ry = (float) Math.toRadians(GingerRegister.getInstance().game.data.camera.getYaw()); - switch (direction) - { - default: - case FORWARD: - position.z -= Math.cos(ry) * Constants.movementSpeed; - position.x += Math.sin(ry) * Constants.movementSpeed; - break; - case BACKWARD: - position.z += Math.cos(ry) * Constants.movementSpeed; - position.x -= Math.sin(ry) * Constants.movementSpeed; - break; - case LEFT: - ry -= RIGHT_ANGLE; - position.z -= Math.cos(ry) * Constants.movementSpeed; - position.x += Math.sin(ry) * Constants.movementSpeed; - break; - case RIGHT: - ry += RIGHT_ANGLE; - position.z -= Math.cos(ry) * Constants.movementSpeed; - position.x += Math.sin(ry) * Constants.movementSpeed; - break; - case UP: - if (this.noWeight) - position.y += Constants.movementSpeed; - else this.jump(); - break; - case DOWN: - position.y -= Constants.movementSpeed; - break; - } - } - - private static final float RIGHT_ANGLE = (float) (Math.PI / 2f); - - private void jump() - { - if (!isInAir) - { - isInAir = true; - this.upwardsSpeed = Constants.jumpPower; - } - } - - public int getChunkX() - { return this.chunkX; } - - public int getChunkY() - { return this.chunkY; } - - public int getChunkZ() - { return this.chunkZ; } - - public void updateMovement() - { - super.increasePosition(0, (float) (upwardsSpeed * (Window.getTime())), 0); - upwardsSpeed += Constants.gravity.y() * Window.getTime(); // TODO: Implement 3D gravity - isInAir = false; - upwardsSpeed = 0; - int newChunkX = (int) position.x >> POS_SHIFT; - int newChunkY = (int) position.y >> POS_SHIFT; - int newChunkZ = (int) position.z >> POS_SHIFT; - if (newChunkX != this.chunkX || newChunkY != this.chunkY || newChunkZ != this.chunkZ) - { - Litecraft.getInstance().getWorld().updateLoadedChunks(newChunkX, newChunkY, newChunkZ); - this.chunkX = newChunkX; - this.chunkY = newChunkY; - this.chunkZ = newChunkZ; - } - } -} diff --git a/src/main/java/com/halotroop/litecraft/util/RelativeDirection.java b/src/main/java/com/halotroop/litecraft/util/RelativeDirection.java deleted file mode 100644 index 2128936..0000000 --- a/src/main/java/com/halotroop/litecraft/util/RelativeDirection.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.halotroop.litecraft.util; - -public enum RelativeDirection -{ - UP, // up up - DOWN, // down down - LEFT, // >left< right - RIGHT, // left >right< - FORWARD, // b - BACKWARD,// a -} diff --git a/src/main/java/com/halotroop/litecraft/util/noise/OctaveSimplexNoise.java b/src/main/java/com/halotroop/litecraft/util/noise/OctaveSimplexNoise.java deleted file mode 100644 index 8608162..0000000 --- a/src/main/java/com/halotroop/litecraft/util/noise/OctaveSimplexNoise.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.halotroop.litecraft.util.noise; - -import java.util.Random; - -public final class OctaveSimplexNoise -{ - protected SimplexNoise[] samplers; - private double clamp; - private double spread, amplitudeLow, amplitudeHigh; - - public OctaveSimplexNoise(Random rand, int octaves) - { this(rand, octaves, 1D, 1D, 1D); } - - public OctaveSimplexNoise(Random rand, int octaves, double spread, double amplitudeHigh, double amplitudeLow) - { - this.samplers = new SimplexNoise[octaves]; - this.clamp = 1D / (1D - (1D / Math.pow(2, octaves))); - for (int i = 0; i < octaves; ++i) - { samplers[i] = new SimplexNoise(rand.nextLong()); } - this.spread = spread; - this.amplitudeLow = amplitudeLow; - this.amplitudeHigh = amplitudeHigh; - } - - public double sample(double x, double y) - { - double amplSpread = 0.5D; - double result = 0; - for (SimplexNoise sampler : this.samplers) - { - result += (amplSpread * sampler.sample(x / (amplSpread * this.spread), y / (amplSpread * this.spread))); - amplSpread *= 0.5D; - } - result = result * this.clamp; - return result > 0 ? result * this.amplitudeHigh : result * this.amplitudeLow; - } - - public double sample(double x, double y, double z) - { - double amplSpread = 0.5D; - double result = 0; - for (SimplexNoise sampler : this.samplers) - { - double divisor = amplSpread * this.spread; - result += (amplSpread * sampler.sample(x / divisor, y / divisor, z / divisor)); - amplSpread *= 0.5D; - } - result = result * this.clamp; - return result > 0 ? result * this.amplitudeHigh : result * this.amplitudeLow; - } -} diff --git a/src/main/java/com/halotroop/litecraft/util/noise/SimplexNoise.java b/src/main/java/com/halotroop/litecraft/util/noise/SimplexNoise.java deleted file mode 100644 index c4eb5e0..0000000 --- a/src/main/java/com/halotroop/litecraft/util/noise/SimplexNoise.java +++ /dev/null @@ -1,854 +0,0 @@ -package com.halotroop.litecraft.util.noise; - -/** OpenSimplex Noise in Java. - * (Using implementation by Kurt Spencer) - * v1.1 (October 5, 2014) - * - Added 2D and 4D implementations. - * - Proper gradient sets for all dimensions, from a - * dimensionally-generalizable scheme with an actual - * rhyme and reason behind it. - * - Removed default permutation array in favor of - * default seed. - * - Changed seed-based constructor to be independent - * of any particular randomization library, so results - * will be the same when ported to other languages. */ -public class SimplexNoise -{ - private static final double STRETCH_CONSTANT_2D = -0.211324865405187; //(1/Math.sqrt(2+1)-1)/2; - private static final double SQUISH_CONSTANT_2D = 0.366025403784439; //(Math.sqrt(2+1)-1)/2; - private static final double STRETCH_CONSTANT_3D = -1.0 / 6; //(1/Math.sqrt(3+1)-1)/3; - private static final double SQUISH_CONSTANT_3D = 1.0 / 3; //(Math.sqrt(3+1)-1)/3; - private static final double NORM_CONSTANT_2D = 47; - private static final double NORM_CONSTANT_3D = 103; - private static final long DEFAULT_SEED = 0; - //Gradients for 2D. They approximate the directions to the - //vertices of an octagon from the center. - private static byte[] gradients2D = new byte[] - { - 5, 2, 2, 5, - -5, 2, -2, 5, - 5, -2, 2, -5, - -5, -2, -2, -5, - }; - //Gradients for 3D. They approximate the directions to the - //vertices of a rhombicuboctahedron from the center, skewed so - //that the triangular and square facets can be inscribed inside - //circles of the same radius. - private static byte[] gradients3D = new byte[] - { - -11, 4, 4, -4, 11, 4, -4, 4, 11, - 11, 4, 4, 4, 11, 4, 4, 4, 11, - -11, -4, 4, -4, -11, 4, -4, -4, 11, - 11, -4, 4, 4, -11, 4, 4, -4, 11, - -11, 4, -4, -4, 11, -4, -4, 4, -11, - 11, 4, -4, 4, 11, -4, 4, 4, -11, - -11, -4, -4, -4, -11, -4, -4, -4, -11, - 11, -4, -4, 4, -11, -4, 4, -4, -11, - }; - private short[] perm; - private short[] permGradIndex3D; - private long seed = -1L; - - public SimplexNoise() - { this(DEFAULT_SEED); } - - //Initializes the class using a permutation array generated from a 64-bit seed. - //Generates a proper permutation (i.e. doesn't merely perform N successive pair swaps on a base array) - //Uses a simple 64-bit LCG. - public SimplexNoise(long seed) - { - this.seed = seed; - perm = new short[256]; - permGradIndex3D = new short[256]; - short[] source = new short[256]; - for (short i = 0; i < 256; i++) - source[i] = i; - seed = seed * 6364136223846793005L + 1442695040888963407L; - seed = seed * 6364136223846793005L + 1442695040888963407L; - seed = seed * 6364136223846793005L + 1442695040888963407L; - for (int i = 255; i >= 0; i--) - { - seed = seed * 6364136223846793005L + 1442695040888963407L; - int r = (int) ((seed + 31) % (i + 1)); - if (r < 0) - r += (i + 1); - perm[i] = source[r]; - permGradIndex3D[i] = (short) ((perm[i] % (gradients3D.length / 3)) * 3); - source[r] = source[i]; - } - } - - private static int fastFloor(double x) - { - int xi = (int) x; - return x < xi ? xi - 1 : xi; - } - - /** Function added to noise by Valoeghese to get seed. */ - public long getSeed() - { return this.seed; } - - //2D OpenSimplex Noise. - public double sample(double x, double y) - { - //Place input coordinates onto grid. - double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; - double xs = x + stretchOffset; - double ys = y + stretchOffset; - //Floor to get grid coordinates of rhombus (stretched square) super-cell origin. - int xsb = (int) Math.floor(xs); - int ysb = (int) Math.floor(ys); - //Skew out to get actual coordinates of rhombus origin. We'll need these later. - double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D; - double xb = xsb + squishOffset; - double yb = ysb + squishOffset; - //Compute grid coordinates relative to rhombus origin. - double xins = xs - xsb; - double yins = ys - ysb; - //Sum those together to get a value that determines which region we're in. - double inSum = xins + yins; - //Positions relative to origin point. - double dx0 = x - xb; - double dy0 = y - yb; - //We'll be defining these inside the next block and using them afterwards. - double dx_ext, dy_ext; - int xsv_ext, ysv_ext; - double value = 0; - //Contribution (1,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1; - if (attn1 > 0) - { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1); - } - //Contribution (0,1) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2; - if (attn2 > 0) - { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2); - } - if (inSum <= 1) - { //We're inside the triangle (2-Simplex) at (0,0) - double zins = 1 - inSum; - if (zins > xins || zins > yins) - { //(0,0) is one of the closest two triangular vertices - if (xins > yins) - { - xsv_ext = xsb + 1; - ysv_ext = ysb - 1; - dx_ext = dx0 - 1; - dy_ext = dy0 + 1; - } - else - { - xsv_ext = xsb - 1; - ysv_ext = ysb + 1; - dx_ext = dx0 + 1; - dy_ext = dy0 - 1; - } - } - else - { //(1,0) and (0,1) are the closest two vertices. - xsv_ext = xsb + 1; - ysv_ext = ysb + 1; - dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; - } - } - else - { //We're inside the triangle (2-Simplex) at (1,1) - double zins = 2 - inSum; - if (zins < xins || zins < yins) - { //(0,0) is one of the closest two triangular vertices - if (xins > yins) - { - xsv_ext = xsb + 2; - ysv_ext = ysb + 0; - dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; - } - else - { - xsv_ext = xsb + 0; - ysv_ext = ysb + 2; - dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; - dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; - } - } - else - { //(1,0) and (0,1) are the closest two vertices. - dx_ext = dx0; - dy_ext = dy0; - xsv_ext = xsb; - ysv_ext = ysb; - } - xsb += 1; - ysb += 1; - dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; - dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; - } - //Contribution (0,0) or (1,1) - double attn0 = 2 - dx0 * dx0 - dy0 * dy0; - if (attn0 > 0) - { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0); - } - //Extra Vertex - double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; - if (attn_ext > 0) - { - attn_ext *= attn_ext; - value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext); - } - return value / NORM_CONSTANT_2D; - } - - //3D OpenSimplex Noise. - public double sample(double x, double y, double z) - { - //Place input coordinates on simplectic honeycomb. - double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D; - double xs = x + stretchOffset; - double ys = y + stretchOffset; - double zs = z + stretchOffset; - //Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin. - int xsb = fastFloor(xs); - int ysb = fastFloor(ys); - int zsb = fastFloor(zs); - //Skew out to get actual coordinates of rhombohedron origin. We'll need these later. - double squishOffset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D; - double xb = xsb + squishOffset; - double yb = ysb + squishOffset; - double zb = zsb + squishOffset; - //Compute simplectic honeycomb coordinates relative to rhombohedral origin. - double xins = xs - xsb; - double yins = ys - ysb; - double zins = zs - zsb; - //Sum those together to get a value that determines which region we're in. - double inSum = xins + yins + zins; - //Positions relative to origin point. - double dx0 = x - xb; - double dy0 = y - yb; - double dz0 = z - zb; - //We'll be defining these inside the next block and using them afterwards. - double dx_ext0, dy_ext0, dz_ext0; - double dx_ext1, dy_ext1, dz_ext1; - int xsv_ext0, ysv_ext0, zsv_ext0; - int xsv_ext1, ysv_ext1, zsv_ext1; - double value = 0; - if (inSum <= 1) - { //We're inside the tetrahedron (3-Simplex) at (0,0,0) - //Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest. - byte aPoint = 0x01; - double aScore = xins; - byte bPoint = 0x02; - double bScore = yins; - if (aScore >= bScore && zins > bScore) - { - bScore = zins; - bPoint = 0x04; - } - else if (aScore < bScore && zins > aScore) - { - aScore = zins; - aPoint = 0x04; - } - //Now we determine the two lattice points not part of the tetrahedron that may contribute. - //This depends on the closest two tetrahedral vertices, including (0,0,0) - double wins = 1 - inSum; - if (wins > aScore || wins > bScore) - { //(0,0,0) is one of the closest two tetrahedral vertices. - byte c = (bScore > aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. - if ((c & 0x01) == 0) - { - xsv_ext0 = xsb - 1; - xsv_ext1 = xsb; - dx_ext0 = dx0 + 1; - dx_ext1 = dx0; - } - else - { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx_ext1 = dx0 - 1; - } - if ((c & 0x02) == 0) - { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0; - if ((c & 0x01) == 0) - { - ysv_ext1 -= 1; - dy_ext1 += 1; - } - else - { - ysv_ext0 -= 1; - dy_ext0 += 1; - } - } - else - { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1; - } - if ((c & 0x04) == 0) - { - zsv_ext0 = zsb; - zsv_ext1 = zsb - 1; - dz_ext0 = dz0; - dz_ext1 = dz0 + 1; - } - else - { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz_ext1 = dz0 - 1; - } - } - else - { //(0,0,0) is not one of the closest two tetrahedral vertices. - byte c = (byte) (aPoint | bPoint); //Our two extra vertices are determined by the closest two. - if ((c & 0x01) == 0) - { - xsv_ext0 = xsb; - xsv_ext1 = xsb - 1; - dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; - } - else - { - xsv_ext0 = xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - } - if ((c & 0x02) == 0) - { - ysv_ext0 = ysb; - ysv_ext1 = ysb - 1; - dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; - } - else - { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - } - if ((c & 0x04) == 0) - { - zsv_ext0 = zsb; - zsv_ext1 = zsb - 1; - dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; - } - else - { - zsv_ext0 = zsv_ext1 = zsb + 1; - dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - } - } - //Contribution (0,0,0) - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; - if (attn0 > 0) - { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0); - } - //Contribution (1,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) - { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); - } - //Contribution (0,1,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; - double dz2 = dz1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) - { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); - } - //Contribution (0,0,1) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) - { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); - } - } - else if (inSum >= 2) - { //We're inside the tetrahedron (3-Simplex) at (1,1,1) - //Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1). - byte aPoint = 0x06; - double aScore = xins; - byte bPoint = 0x05; - double bScore = yins; - if (aScore <= bScore && zins < bScore) - { - bScore = zins; - bPoint = 0x03; - } - else if (aScore > bScore && zins < aScore) - { - aScore = zins; - aPoint = 0x03; - } - //Now we determine the two lattice points not part of the tetrahedron that may contribute. - //This depends on the closest two tetrahedral vertices, including (1,1,1) - double wins = 3 - inSum; - if (wins < aScore || wins < bScore) - { //(1,1,1) is one of the closest two tetrahedral vertices. - byte c = (bScore < aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. - if ((c & 0x01) != 0) - { - xsv_ext0 = xsb + 2; - xsv_ext1 = xsb + 1; - dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - } - else - { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D; - } - if ((c & 0x02) != 0) - { - ysv_ext0 = ysv_ext1 = ysb + 1; - dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - if ((c & 0x01) != 0) - { - ysv_ext1 += 1; - dy_ext1 -= 1; - } - else - { - ysv_ext0 += 1; - dy_ext0 -= 1; - } - } - else - { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D; - } - if ((c & 0x04) != 0) - { - zsv_ext0 = zsb + 1; - zsv_ext1 = zsb + 2; - dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D; - } - else - { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D; - } - } - else - { //(1,1,1) is not one of the closest two tetrahedral vertices. - byte c = (byte) (aPoint & bPoint); //Our two extra vertices are determined by the closest two. - if ((c & 0x01) != 0) - { - xsv_ext0 = xsb + 1; - xsv_ext1 = xsb + 2; - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; - } - else - { - xsv_ext0 = xsv_ext1 = xsb; - dx_ext0 = dx0 - SQUISH_CONSTANT_3D; - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - } - if ((c & 0x02) != 0) - { - ysv_ext0 = ysb + 1; - ysv_ext1 = ysb + 2; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; - } - else - { - ysv_ext0 = ysv_ext1 = ysb; - dy_ext0 = dy0 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - } - if ((c & 0x04) != 0) - { - zsv_ext0 = zsb + 1; - zsv_ext1 = zsb + 2; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; - } - else - { - zsv_ext0 = zsv_ext1 = zsb; - dz_ext0 = dz0 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - } - } - //Contribution (1,1,0) - double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) - { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3); - } - //Contribution (1,0,1) - double dx2 = dx3; - double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) - { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2); - } - //Contribution (0,1,1) - double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dy1 = dy3; - double dz1 = dz2; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) - { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1); - } - //Contribution (1,1,1) - dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; - if (attn0 > 0) - { - attn0 *= attn0; - value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0); - } - } - else - { //We're inside the octahedron (Rectified 3-Simplex) in between. - double aScore; - byte aPoint; - boolean aIsFurtherSide; - double bScore; - byte bPoint; - boolean bIsFurtherSide; - //Decide between point (0,0,1) and (1,1,0) as closest - double p1 = xins + yins; - if (p1 > 1) - { - aScore = p1 - 1; - aPoint = 0x03; - aIsFurtherSide = true; - } - else - { - aScore = 1 - p1; - aPoint = 0x04; - aIsFurtherSide = false; - } - //Decide between point (0,1,0) and (1,0,1) as closest - double p2 = xins + zins; - if (p2 > 1) - { - bScore = p2 - 1; - bPoint = 0x05; - bIsFurtherSide = true; - } - else - { - bScore = 1 - p2; - bPoint = 0x02; - bIsFurtherSide = false; - } - //The closest out of the two (1,0,0) and (0,1,1) will replace the furthest out of the two decided above, if closer. - double p3 = yins + zins; - if (p3 > 1) - { - double score = p3 - 1; - if (aScore <= bScore && aScore < score) - { - aScore = score; - aPoint = 0x06; - aIsFurtherSide = true; - } - else if (aScore > bScore && bScore < score) - { - bScore = score; - bPoint = 0x06; - bIsFurtherSide = true; - } - } - else - { - double score = 1 - p3; - if (aScore <= bScore && aScore < score) - { - aScore = score; - aPoint = 0x01; - aIsFurtherSide = false; - } - else if (aScore > bScore && bScore < score) - { - bScore = score; - bPoint = 0x01; - bIsFurtherSide = false; - } - } - //Where each of the two closest points are determines how the extra two vertices are calculated. - if (aIsFurtherSide == bIsFurtherSide) - { - if (aIsFurtherSide) - { //Both closest points on (1,1,1) side - //One of the two extra points is (1,1,1) - dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb + 1; - //Other extra point is based on the shared axis. - byte c = (byte) (aPoint & bPoint); - if ((c & 0x01) != 0) - { - dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 2; - ysv_ext1 = ysb; - zsv_ext1 = zsb; - } - else if ((c & 0x02) != 0) - { - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb + 2; - zsv_ext1 = zsb; - } - else - { - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb; - zsv_ext1 = zsb + 2; - } - } - else - {//Both closest points on (0,0,0) side - //One of the two extra points is (0,0,0) - dx_ext0 = dx0; - dy_ext0 = dy0; - dz_ext0 = dz0; - xsv_ext0 = xsb; - ysv_ext0 = ysb; - zsv_ext0 = zsb; - //Other extra point is based on the omitted axis. - byte c = (byte) (aPoint | bPoint); - if ((c & 0x01) == 0) - { - dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb - 1; - ysv_ext1 = ysb + 1; - zsv_ext1 = zsb + 1; - } - else if ((c & 0x02) == 0) - { - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 1; - ysv_ext1 = ysb - 1; - zsv_ext1 = zsb + 1; - } - else - { - dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; - xsv_ext1 = xsb + 1; - ysv_ext1 = ysb + 1; - zsv_ext1 = zsb - 1; - } - } - } - else - { //One point on (0,0,0) side, one point on (1,1,1) side - byte c1, c2; - if (aIsFurtherSide) - { - c1 = aPoint; - c2 = bPoint; - } - else - { - c1 = bPoint; - c2 = aPoint; - } - //One contribution is a permutation of (1,1,-1) - if ((c1 & 0x01) == 0) - { - dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb - 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb + 1; - } - else if ((c1 & 0x02) == 0) - { - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb - 1; - zsv_ext0 = zsb + 1; - } - else - { - dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; - dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; - dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D; - xsv_ext0 = xsb + 1; - ysv_ext0 = ysb + 1; - zsv_ext0 = zsb - 1; - } - //One contribution is a permutation of (0,0,2) - dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; - dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; - dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; - xsv_ext1 = xsb; - ysv_ext1 = ysb; - zsv_ext1 = zsb; - if ((c2 & 0x01) != 0) - { - dx_ext1 -= 2; - xsv_ext1 += 2; - } - else if ((c2 & 0x02) != 0) - { - dy_ext1 -= 2; - ysv_ext1 += 2; - } - else - { - dz_ext1 -= 2; - zsv_ext1 += 2; - } - } - //Contribution (1,0,0) - double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; - double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; - double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; - double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; - if (attn1 > 0) - { - attn1 *= attn1; - value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); - } - //Contribution (0,1,0) - double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; - double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; - double dz2 = dz1; - double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; - if (attn2 > 0) - { - attn2 *= attn2; - value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); - } - //Contribution (0,0,1) - double dx3 = dx2; - double dy3 = dy1; - double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; - double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; - if (attn3 > 0) - { - attn3 *= attn3; - value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); - } - //Contribution (1,1,0) - double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; - double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; - double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4; - if (attn4 > 0) - { - attn4 *= attn4; - value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4); - } - //Contribution (1,0,1) - double dx5 = dx4; - double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; - double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5; - if (attn5 > 0) - { - attn5 *= attn5; - value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5); - } - //Contribution (0,1,1) - double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; - double dy6 = dy4; - double dz6 = dz5; - double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6; - if (attn6 > 0) - { - attn6 *= attn6; - value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6); - } - } - //First extra vertex - double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0; - if (attn_ext0 > 0) - { - attn_ext0 *= attn_ext0; - value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0); - } - //Second extra vertex - double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1; - if (attn_ext1 > 0) - { - attn_ext1 *= attn_ext1; - value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1); - } - return value / NORM_CONSTANT_3D; - } - - private double extrapolate(int xsb, int ysb, double dx, double dy) - { - int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; - return gradients2D[index] * dx - + gradients2D[index + 1] * dy; - } - - private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz) - { - int index = permGradIndex3D[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF]; - return gradients3D[index] * dx - + gradients3D[index + 1] * dy - + gradients3D[index + 2] * dz; - } -} \ No newline at end of file diff --git a/src/main/java/com/halotroop/litecraft/world/BlockAccess.java b/src/main/java/com/halotroop/litecraft/world/BlockAccess.java deleted file mode 100644 index 0207ab5..0000000 --- a/src/main/java/com/halotroop/litecraft/world/BlockAccess.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.halotroop.litecraft.world; - -import com.halotroop.litecraft.types.block.Block; - -public interface BlockAccess -{ - Block getBlock(int x, int y, int z); - - void setBlock(int x, int y, int z, Block block); -} \ No newline at end of file diff --git a/src/main/java/com/halotroop/litecraft/world/Chunk.java b/src/main/java/com/halotroop/litecraft/world/Chunk.java deleted file mode 100644 index 979c141..0000000 --- a/src/main/java/com/halotroop/litecraft/world/Chunk.java +++ /dev/null @@ -1,245 +0,0 @@ -package com.halotroop.litecraft.world; - -import java.util.*; -import java.util.function.ToIntFunction; - -import org.joml.Vector3f; - -import com.halotroop.litecraft.logic.SODSerializable; -import com.halotroop.litecraft.render.BlockRenderer; -import com.halotroop.litecraft.types.block.*; -import com.halotroop.litecraft.world.gen.WorldGenConstants; - -import it.unimi.dsi.fastutil.ints.*; -import it.unimi.dsi.fastutil.objects.*; -import tk.valoeghese.sod.*; - -public class Chunk implements BlockAccess, WorldGenConstants, SODSerializable -{ - /** @param x in-chunk x coordinate. - * @param y in-chunk y coordinate. - * @param z in-chunk z coordinate. - * @return creates a long that represents a coordinate, for use as a key in arrays. */ - public static int index(int x, int y, int z) - { return (x & MAX_POS) | ((y & MAX_POS) << POS_SHIFT) | ((z & MAX_POS) << DOUBLE_SHIFT); } - - private final Block[] blocks = new Block[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE]; - private BlockInstance[] blockInstances = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE]; - private boolean shouldRender = false; - public final int chunkX, chunkY, chunkZ; - public final int chunkStartX, chunkStartY, chunkStartZ; - private boolean fullyGenerated = false; - public final int dimension; - private boolean dirty = true; - /** A holder for the rendered blocks in this chunk. This array is *NOT* safe to use for getting BIs at a position! - * It can vary in size from 0 to 512 elements long and must only be read linearly. */ - private BlockInstance[] renderedBlocks = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE]; - - public Chunk(World world, int chunkX, int chunkY, int chunkZ, int dimension) - { - this.chunkX = chunkX; - this.chunkY = chunkY; - this.chunkZ = chunkZ; - this.chunkStartX = chunkX << POS_SHIFT; - this.chunkStartY = chunkY << POS_SHIFT; - this.chunkStartZ = chunkZ << POS_SHIFT; - this.dimension = dimension; - } - - public boolean doRender() - { return this.shouldRender; } - - public void setFullyGenerated(boolean fullyGenerated) - { this.fullyGenerated = fullyGenerated; } - - @Override - public Block getBlock(int x, int y, int z) - { - if (x > CHUNK_SIZE || y > CHUNK_SIZE || z > CHUNK_SIZE || x < 0 || y < 0 || z < 0) - { throw new RuntimeException("Block [" + x + ", " + y + ", " + z + "] out of chunk bounds!"); } - return blocks[index(x, y, z)]; - } - - public BlockInstance getBlockInstance(int x, int y, int z) - { - if (x > CHUNK_SIZE || y > CHUNK_SIZE || z > CHUNK_SIZE || x < 0 || y < 0 || z < 0) - { throw new RuntimeException("BlockInstance [" + x + ", " + y + ", " + z + "] out of chunk bounds!"); } - return this.blockInstances[index(x, y, z)]; - } - - public void render(BlockRenderer blockRenderer) - { - if (shouldRender) - { - if (dirty) - { - dirty = false; - List tempList = new ArrayList<>(); - Arrays.fill(renderedBlocks, null); - for (int x = 0; x < CHUNK_SIZE; x++) - for (int y = 0; y < CHUNK_SIZE; y++) - for (int z = 0; z < CHUNK_SIZE; z++) - { - BlockInstance block = getBlockInstance(x, y, z); - // Check for chunk edges to avoid errors when get the neighboring blocks, TODO fix this - if (x == 0 || x == CHUNK_SIZE - 1 || z == 0 || z == CHUNK_SIZE - 1 || y == 0 || y == CHUNK_SIZE - 1) - { - tempList.add(block); - continue; - } - // Check for air. Yes this is stupid, TODO fix this too - try - { - if (getBlockInstance(x - 1, y, z).getModel() == null || getBlockInstance(x + 1, y, z).getModel() == null || - getBlockInstance(x, y - 1, z).getModel() == null || getBlockInstance(x, y + 1, z).getModel() == null || - getBlockInstance(x, y, z - 1).getModel() == null || getBlockInstance(x, y, z + 1).getModel() == null) - { tempList.add(block); } - } - catch (NullPointerException e) - { // this seems to be a hotspot for errors - e.printStackTrace(); // so I can add a debug breakpoint on this line - throw e; // e - } - } - renderedBlocks = tempList.toArray(BlockInstance[]::new); - } - blockRenderer.prepareRender(); - blockRenderer.render(renderedBlocks); - blockRenderer.shader.stop(); - } - } - - /** Change the block in this exact position - * - * @param x, y, z The coordinate position of block to overwrite - * @param block The block to place there */ - @Override - public void setBlock(int x, int y, int z, Block block) - { - // This section makes sure the blocks don't go out of range - if (x > MAX_POS) - x = MAX_POS; - else if (x < 0) x = 0; - if (y > MAX_POS) - y = MAX_POS; - else if (y < 0) y = 0; - if (z > MAX_POS) - z = MAX_POS; - else if (z < 0) z = 0; - // - this.blocks[index(x, y, z)] = block; - if (this.shouldRender) this.blockInstances[index(x, y, z)] = new BlockInstance(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z)); - dirty = true; - } - - /** Set whether or not the chunk should render */ - public void setRender(boolean render) - { - if (render && !this.shouldRender) // if it has been changed to true - for (int x = 0; x < CHUNK_SIZE; ++x) - for (int y = 0; y < CHUNK_SIZE; ++y) - for (int z = 0; z < CHUNK_SIZE; ++z) - { - Block block = this.blocks[index(x, y, z)]; - this.blockInstances[index(x, y, z)] = new BlockInstance(block, - new Vector3f( - this.chunkStartX + x, - this.chunkStartY + y, - this.chunkStartZ + z)); - } - else if (!render && this.shouldRender) // else if it has been changed to false. - // we need to check both variables because there are two cases that make - // the if statement fall to here - blockInstances = new BlockInstance[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE]; - this.shouldRender = render; - dirty = true; - } - - public boolean isFullyGenerated() - { return this.fullyGenerated; } - - @Override - public void read(BinaryData data) - { - Int2ObjectMap palette = new Int2ObjectArrayMap<>(); - DataSection paletteData = data.get("palette"); - boolean readInt = true; // whether the thing from the palette to be read is int - int intIdCache = 0; - // - for (Object o : paletteData) - { - if (readInt) - { - intIdCache = (int) o; - readInt = false; - } - else - { - palette.put(intIdCache, Block.getBlockOrAir((String) o)); - readInt = true; - } - } - // - IntArrayDataSection blockData = data.getIntArray("block"); - int index = 0; - // Iterate over each block in the chunk - for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes - for (int y = 0; y < CHUNK_SIZE; ++y) - for (int x = 0; x < CHUNK_SIZE; ++x) - { - blocks[index] = palette.get(blockData.readInt(index)); - ++index; - } - // - DataSection properties = data.get("properties"); - try - { - this.fullyGenerated = properties.readBoolean(0); // index 0 is the "fully generated" property - } - catch (Throwable e) - { - if (!readExceptionNotif) - { - System.out.println("An exception occurred reading properties for a chunk! This could be a benign error due to updates to chunk properties."); - readExceptionNotif = true; - } - } - } - - private static boolean readExceptionNotif = false; - private int nextId; // for saving - - @Override - public void write(BinaryData data) - { - Object2IntMap palette = new Object2IntArrayMap<>(); // block to int id - DataSection paletteData = new DataSection(); - IntArrayDataSection blockData = new IntArrayDataSection(); - int index = 0; - nextId = 0; - ToIntFunction nextIdProvider = b -> nextId++; - // - for (int z = 0; z < CHUNK_SIZE; ++z) // z, y, x order for data saving and loading so we can use incremental pos hashes - for (int y = 0; y < CHUNK_SIZE; ++y) - for (int x = 0; x < CHUNK_SIZE; ++x) - { - Block b = blocks[index]; - blockData.writeInt(palette.computeIntIfAbsent(b, nextIdProvider)); - ++index; - } - // - palette.forEach((b, id) -> - { - paletteData.writeInt(id); - paletteData.writeString(b.identifier); - }); - // - data.put("palette", paletteData); - data.put("block", blockData); - // - DataSection properties = new DataSection(); - properties.writeBoolean(this.fullyGenerated); - data.put("properties", properties); - dirty = true; - } -} diff --git a/src/main/java/com/halotroop/litecraft/world/World.java b/src/main/java/com/halotroop/litecraft/world/World.java deleted file mode 100644 index dc2af27..0000000 --- a/src/main/java/com/halotroop/litecraft/world/World.java +++ /dev/null @@ -1,253 +0,0 @@ -package com.halotroop.litecraft.world; - -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.LongConsumer; - -import org.joml.Vector3f; - -import com.halotroop.litecraft.Litecraft; -import com.halotroop.litecraft.render.BlockRenderer; -import com.halotroop.litecraft.save.LitecraftSave; -import com.halotroop.litecraft.types.block.*; -import com.halotroop.litecraft.types.entity.PlayerEntity; -import com.halotroop.litecraft.world.dimension.Dimension; -import com.halotroop.litecraft.world.gen.*; -import com.halotroop.litecraft.world.gen.modifier.WorldModifier; - -import it.unimi.dsi.fastutil.longs.*; - -public class World implements BlockAccess, WorldGenConstants -{ - Long2ObjectMap chunks; - private final WorldModifier[] worldModifiers; - private final ChunkGenerator chunkGenerator; - private final BlockAccess genBlockAccess; - private final LitecraftSave save; - private final long seed; - private final int dimension; - private final ForkJoinPool threadPool; - public PlayerEntity playerEntity; - int renderBound; - int renderBoundVertical; - // dummy block instance for retrieving the default block model - private final BlockInstance dummy; - - public World(long seed, int renderSize, Dimension dim, LitecraftSave save) - { - this.threadPool = new ForkJoinPool(4, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); - this.dummy = new BlockInstance(Blocks.ANDESITE, new Vector3f(0, 0, 0)); - this.dummy.setVisible(false); - this.chunks = new Long2ObjectArrayMap<>(); - this.seed = seed; - this.chunkGenerator = dim.createChunkGenerator(seed); - this.worldModifiers = dim.getWorldModifierArray(); - // initialize world modifiers with seed - for (WorldModifier modifier : this.worldModifiers) - { modifier.initialize(seed); } - this.genBlockAccess = new GenerationWorld(this); - this.save = save; - this.dimension = dim.id; - this.renderBound = renderSize / 2; - this.renderBoundVertical = this.renderBound / 2; - if (this.renderBoundVertical < 2) - { this.renderBoundVertical = 2; } - } - - public int findAir(int x, int z) - { - int y = SEA_LEVEL; - int attemptsRemaining = 255; - while (attemptsRemaining-- > 0) - { - // DO NOT CHANGE TO y++ - if (this.getBlock(x, ++y, z) == Blocks.AIR) - return y; - } - return -1; // if it fails, returns -1 - } - - public void spawnPlayer() - { - int y = this.findAir(0, 0); - if (y == -1) - y = 300; // yeet - this.spawnPlayer(0, y, -3); - } - - public PlayerEntity spawnPlayer(float x, float y, float z) - { - this.playerEntity = (PlayerEntity) Litecraft.getInstance().player; - this.playerEntity.setVisible(false); - // Generate world around player - long time = System.currentTimeMillis(); - System.out.println("Generating world!"); - this.updateLoadedChunks(this.playerEntity.getChunkX(), this.playerEntity.getChunkY(), this.playerEntity.getChunkZ()); - System.out.println("Generated world in " + (System.currentTimeMillis() - time) + " milliseconds"); - // return player - return this.playerEntity; - } - - public Chunk getChunk(int chunkX, int chunkY, int chunkZ) - { - Chunk chunk = this.chunks.computeIfAbsent(posHash(chunkX, chunkY, chunkZ), pos -> - { - Chunk readChunk = save.readChunk(this, chunkX, chunkY, chunkZ, this.dimension); - return readChunk == null ? this.chunkGenerator.generateChunk(this, chunkX, chunkY, chunkZ) : readChunk; - }); - if (chunk.isFullyGenerated()) return chunk; - this.populateChunk(chunkX, chunkY, chunkZ, chunk.chunkStartX, chunk.chunkStartY, chunk.chunkStartZ); - chunk.setFullyGenerated(true); - return chunk; - } - - public Chunk getChunkToLoad(int chunkX, int chunkY, int chunkZ) - { - long posHash = posHash(chunkX, chunkY, chunkZ); - // try get an already loaded chunk - Chunk result = this.chunks.get(posHash); - if (result != null) - return result; - // try read a chunk from memory - result = save.readChunk(this, chunkX, chunkY, chunkZ, this.dimension); - // if neither of those work, generate the chunk - result = result == null ? this.chunkGenerator.generateChunk(this, chunkX, chunkY, chunkZ) : result; - // add chunk to array - this.chunks.put(posHash, result); - return result; - } - - /** @return whether the chunk was unloaded without errors. Will often, but not always, be equal to whether the chunk was already in memory. */ - boolean unloadChunk(long posHash) - { - Chunk chunk = this.chunks.get(posHash); - // If the chunk is not in memory, it does not need to be unloaded - if (chunk == null) return false; - // Otherwise save the chunk - AtomicBoolean result = new AtomicBoolean(false); - CompletableFuture.runAsync(() -> - { - result.set(this.save.saveChunk(chunk)); - this.chunks.remove(posHash); - }, threadPool); - return result.get(); - } - - void populateChunk(Chunk chunk) - { this.populateChunk(chunk.chunkX, chunk.chunkY, chunk.chunkZ, chunk.chunkStartX, chunk.chunkStartY, chunk.chunkStartZ); } - - private void populateChunk(int chunkX, int chunkY, int chunkZ, int chunkStartX, int chunkStartY, int chunkStartZ) - { - Random rand = new Random(this.seed + 5828671L * chunkX + -47245139L * chunkY + 8972357 * (long) chunkZ); - for (WorldModifier modifier : this.worldModifiers) - { modifier.modifyWorld(this.genBlockAccess, rand, chunkStartX, chunkStartY, chunkStartZ); } - } - - /** @return a chunk that has not neccesarily gone through chunk populating. Used in chunk populating to prevent infinite recursion. */ - Chunk getGenChunk(int chunkX, int chunkY, int chunkZ) - { return this.chunks.computeIfAbsent(posHash(chunkX, chunkY, chunkZ), pos -> this.chunkGenerator.generateChunk(this, chunkX, chunkY, chunkZ)); } - - long posHash(int chunkX, int chunkY, int chunkZ) - { return ((long) chunkX & 0x3FF) | (((long) chunkY & 0x3FF) << 10) | (((long) chunkZ & 0x3FF) << 20); } - - @Override - public Block getBlock(int x, int y, int z) - { return this.getChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).getBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS); } - - @Override - public void setBlock(int x, int y, int z, Block block) - { this.getChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).setBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS, block); } - - public void optimiseChunks() - { this.chunks.forEach((pos, chunk) -> optimiseChunk(chunk)); } - - //used for model combining and culling - public Chunk optimiseChunk(Chunk chunk) - { return chunk; } - - public void render(BlockRenderer blockRenderer) - { - blockRenderer.prepareModel(this.dummy.getModel()); - this.chunks.forEach((pos, c) -> - { - if (c != null && c.isFullyGenerated()) - c.render(blockRenderer); - }); - blockRenderer.unbindModel(); - } - - public void unloadAllChunks() - { - LongList chunkPositions = new LongArrayList(); - List> futures = new ArrayList<>(); - if (this.chunks != null) - { - this.chunks.forEach((pos, chunk) -> - { // for every chunk in memory - futures.add(CompletableFuture.runAsync(() -> - { - chunkPositions.add((long) pos); // add pos to chunk positions list for removal later - this.save.saveChunk(chunk); // save chunk - }, threadPool)); - }); - } - futures.forEach(CompletableFuture::join); - chunkPositions.forEach((LongConsumer) (pos -> this.chunks.remove(pos))); // remove all chunks - } - - public long getSeed() - { return this.seed; } - - public static final int SEA_LEVEL = 0; - - public void updateLoadedChunks(int chunkX, int chunkY, int chunkZ) - { - CompletableFuture.runAsync(() -> - { - List toKeep = new ArrayList<>(); - // loop over rendered area, adding chunks that are needed - for (int x = chunkX - this.renderBound; x < chunkX + this.renderBound; x++) - for (int z = chunkZ - this.renderBound; z < chunkZ + this.renderBound; z++) - for (int y = chunkY - this.renderBound; y < chunkY + this.renderBound; y++) - toKeep.add(this.getChunkToLoad(x, y, z)); - LongList toRemove = new LongArrayList(); - // check which loaded chunks are not neccesary - chunks.forEach((pos, chunk) -> - { - if (!toKeep.contains(chunk)) - toRemove.add((long) pos); - }); - // unload unneccesary chunks from chunk array - toRemove.forEach((LongConsumer) this::unloadChunk); - toKeep.forEach(chunk -> - { - if (!chunk.isFullyGenerated()) - { - this.populateChunk(chunk); - chunk.setFullyGenerated(true); - } - boolean alreadyRendering = chunk.doRender(); // if it's already rendering then it's most likely in the map - chunk.setRender(true); - if (!alreadyRendering) - chunks.put(this.posHash(chunk.chunkX, chunk.chunkY, chunk.chunkZ), chunk); - }); - }, threadPool); - } - - private static final class GenerationWorld implements BlockAccess, WorldGenConstants - { - GenerationWorld(World parent) - { this.parent = parent; } - - public final World parent; - - @Override - public Block getBlock(int x, int y, int z) - { return this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).getBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS); } - - @Override - public void setBlock(int x, int y, int z, Block block) - { this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).setBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS, block); } - } -} diff --git a/src/main/java/com/halotroop/litecraft/world/dimension/Dimension.java b/src/main/java/com/halotroop/litecraft/world/dimension/Dimension.java deleted file mode 100644 index a77924f..0000000 --- a/src/main/java/com/halotroop/litecraft/world/dimension/Dimension.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.halotroop.litecraft.world.dimension; - -import java.util.*; - -import com.halotroop.litecraft.world.gen.ChunkGenerator; -import com.halotroop.litecraft.world.gen.modifier.WorldModifier; - -import it.unimi.dsi.fastutil.ints.*; - -public abstract class Dimension -{ - public List worldModifiers = new ArrayList<>(); - public final int id; - public final String saveIdentifier; - - public Dimension(int id, String saveIdentifier) - { - this.id = id; - this.saveIdentifier = saveIdentifier; - ID_TO_DIMENSION.put(id, this); - } - - public Dimension addWorldModifier(WorldModifier modifier) - { - this.worldModifiers.add(modifier); - return this; - } - - public WorldModifier[] getWorldModifierArray() - { return this.worldModifiers.toArray(new WorldModifier[0]); } - - public abstract T createChunkGenerator(long seed); - - public static Dimension getById(int id) - { return ID_TO_DIMENSION.get(id); } - - private static final Int2ObjectMap> ID_TO_DIMENSION = new Int2ObjectArrayMap<>(); -} diff --git a/src/main/java/com/halotroop/litecraft/world/dimension/Dimensions.java b/src/main/java/com/halotroop/litecraft/world/dimension/Dimensions.java deleted file mode 100644 index e4ca965..0000000 --- a/src/main/java/com/halotroop/litecraft/world/dimension/Dimensions.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.halotroop.litecraft.world.dimension; - -import com.halotroop.litecraft.world.gen.EarthChunkGenerator; -import com.halotroop.litecraft.world.gen.modifier.CavesModifier; - -public final class Dimensions -{ - public static final Dimension OVERWORLD = new EarthDimension(0, "earth").addWorldModifier(new CavesModifier()); -} diff --git a/src/main/java/com/halotroop/litecraft/world/dimension/EarthDimension.java b/src/main/java/com/halotroop/litecraft/world/dimension/EarthDimension.java deleted file mode 100644 index 74753ff..0000000 --- a/src/main/java/com/halotroop/litecraft/world/dimension/EarthDimension.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.halotroop.litecraft.world.dimension; - -import com.halotroop.litecraft.world.gen.EarthChunkGenerator; - -class EarthDimension extends Dimension -{ - public EarthDimension(int id, String saveIdentifier) - { super(id, saveIdentifier); } - - @Override - public EarthChunkGenerator createChunkGenerator(long seed) - { return new EarthChunkGenerator(seed, this.id); } -} \ No newline at end of file diff --git a/src/main/java/com/halotroop/litecraft/world/gen/ChunkGenerator.java b/src/main/java/com/halotroop/litecraft/world/gen/ChunkGenerator.java deleted file mode 100644 index 8d11c6a..0000000 --- a/src/main/java/com/halotroop/litecraft/world/gen/ChunkGenerator.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.halotroop.litecraft.world.gen; - -import com.halotroop.litecraft.world.*; - -public interface ChunkGenerator -{ - Chunk generateChunk(World world, int chunkX, int chunkY, int chunkZ); -} diff --git a/src/main/java/com/halotroop/litecraft/world/gen/EarthChunkGenerator.java b/src/main/java/com/halotroop/litecraft/world/gen/EarthChunkGenerator.java deleted file mode 100644 index 51faafc..0000000 --- a/src/main/java/com/halotroop/litecraft/world/gen/EarthChunkGenerator.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.halotroop.litecraft.world.gen; - -import java.util.Random; - -import com.halotroop.litecraft.types.block.*; -import com.halotroop.litecraft.util.noise.OctaveSimplexNoise; -import com.halotroop.litecraft.world.*; - -public class EarthChunkGenerator implements ChunkGenerator, WorldGenConstants -{ - public EarthChunkGenerator(long seed, int dimension) - { - Random rand = new Random(seed); - this.noise = new OctaveSimplexNoise(rand, 3, 250.0, 50.0, 18.0); - this.stoneNoise = new OctaveSimplexNoise(rand, 1); - this.dimension = dimension; - } - - private final OctaveSimplexNoise noise; - private final OctaveSimplexNoise stoneNoise; - private final int dimension; - - @Override - public Chunk generateChunk(World world, int chunkX, int chunkY, int chunkZ) - { - Chunk chunk = new Chunk(world, chunkX, chunkY, chunkZ, this.dimension); - for (int x = 0; x < CHUNK_SIZE; x++) - { - double totalX = x + chunk.chunkStartX; - for (int z = 0; z < CHUNK_SIZE; z++) - { - double totalZ = chunk.chunkStartZ + z; - int height = (int) this.noise.sample(totalX, totalZ); - for (int y = 0; y < CHUNK_SIZE; y++) - { - double rockNoise = this.stoneNoise.sample(totalX / 160.0, (chunk.chunkStartY + y) / 50.0, totalZ / 160.0); - int totalY = chunk.chunkStartY + y; - Block block = Blocks.AIR; - if (totalY < height - 4) - block = pickStone(rockNoise); - else if (totalY < height - 1) - block = Blocks.DIRT; - else if (totalY < height) - block = Blocks.GRASS; - chunk.setBlock(x, y, z, block); - } - } - } - return chunk; - } - - private static Block pickStone(double rockNoise) - { - if (rockNoise < -0.25) - { - return Blocks.ANDESITE; - } - else if (rockNoise < 0) - { - return Blocks.DIORITE; - } - else if (rockNoise < 0.25) - { - return Blocks.GNEISS; - } - else - { - return Blocks.GRANITE; - } - } -} diff --git a/src/main/java/com/halotroop/litecraft/world/gen/WorldGenConstants.java b/src/main/java/com/halotroop/litecraft/world/gen/WorldGenConstants.java deleted file mode 100644 index 8718a7e..0000000 --- a/src/main/java/com/halotroop/litecraft/world/gen/WorldGenConstants.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.halotroop.litecraft.world.gen; - -public interface WorldGenConstants -{ - int POS_SHIFT = 4; - int DOUBLE_SHIFT = POS_SHIFT * 2; - int CHUNK_SIZE = (int) Math.pow(2, POS_SHIFT); - int MAX_POS = CHUNK_SIZE - 1; -} diff --git a/src/main/java/com/halotroop/litecraft/world/gen/modifier/CavesModifier.java b/src/main/java/com/halotroop/litecraft/world/gen/modifier/CavesModifier.java deleted file mode 100644 index 4a7efe4..0000000 --- a/src/main/java/com/halotroop/litecraft/world/gen/modifier/CavesModifier.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.halotroop.litecraft.world.gen.modifier; - -import java.util.Random; - -import com.halotroop.litecraft.types.block.Blocks; -import com.halotroop.litecraft.util.noise.OctaveSimplexNoise; -import com.halotroop.litecraft.world.BlockAccess; -import com.halotroop.litecraft.world.gen.WorldGenConstants; - -public class CavesModifier implements WorldModifier, WorldGenConstants -{ - private OctaveSimplexNoise caveNoise; - - @Override - public void initialize(long seed) - { - Random rand = new Random(seed); - this.caveNoise = new OctaveSimplexNoise(rand, 2, 65.0, 1.0, 1.0); - } - - @Override - public void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ) - { - final int subChunks = CHUNK_SIZE >> 2; // in 4x4x4 blocks - for (int subChunkX = 0; subChunkX < subChunks; subChunkX++) - { - int scOffsetX = subChunkX << 2; // sub chunk offset x - int scTotalX = scOffsetX + chunkStartX; - for (int subChunkZ = 0; subChunkZ < subChunks; subChunkZ++) - { - int scOffsetZ = subChunkZ << 2; // sub chunk offset z - int scTotalZ = scOffsetZ + chunkStartZ; - for (int subChunkY = 0; subChunkY < subChunks; subChunkY++) - { - int scOffsetY = subChunkY << 2; // sub chunk offset y - int scTotalY = scOffsetY + chunkStartY; - double scSampleY = scTotalY * 1.5; // squish caves along y axis a bit - double scUpperYOffset = 4.0 * 1.5; - // calculate noise at each corner of the cube [lower|upper][south|north][west|east] - double noiseLSW = this.caveNoise.sample(scTotalX, scSampleY, scTotalZ); // base = lower south west - double noiseUSW = this.caveNoise.sample(scTotalX, scSampleY + scUpperYOffset, scTotalZ); - double noiseLNW = this.caveNoise.sample(scTotalX, scSampleY, scTotalZ + 4); - double noiseUNW = this.caveNoise.sample(scTotalX, scSampleY + scUpperYOffset, scTotalZ + 4); - double noiseLSE = this.caveNoise.sample(scTotalX + 4, scSampleY, scTotalZ); - double noiseUSE = this.caveNoise.sample(scTotalX + 4, scSampleY + scUpperYOffset, scTotalZ); - double noiseLNE = this.caveNoise.sample(scTotalX + 4, scSampleY, scTotalZ + 4); - double noiseUNE = this.caveNoise.sample(scTotalX + 4, scSampleY + scUpperYOffset, scTotalZ + 4); - // calculate y lerp progresses - // lerp = low + progress * (high - low) - double ypSW = 0.25 * (noiseUSW - noiseLSW); - double ypNW = 0.25 * (noiseUNW - noiseLNW); - double ypSE = 0.25 * (noiseUSE - noiseLSE); - double ypNE = 0.25 * (noiseUNE - noiseLNE); - // initial Y noises - double ySW = noiseLSW; - double ySE = noiseLSE; - double yNW = noiseLNW; - double yNE = noiseLNE; - // loop over y, adding the progress each time - for (int subY = 0; subY < 4; ++subY) - { - int totalY = subY + scTotalY; - // calculate z lerp progresses - double zpW = 0.25 * (yNW - ySW); - double zpE = 0.25 * (yNE - ySE); - // initial Z noises - double zW = ySW; - double zE = ySE; - // loop over z, adding the progress each time - for (int subZ = 0; subZ < 4; ++subZ) - { - int totalZ = subZ + scTotalZ; - // calculate x lerp progress - double lerpProg = 0.25 * (zE - zW); - // initial x noise - double lerpNoise = zW; - // loop over x, adding the progress each time - for (int subX = 0; subX < 4; ++subX) - { - int totalX = subX + scTotalX; - // calculate whether to replace block with air - // if the noise is within the threshold for that block for caves - float threshold = world.getBlock(totalX, totalY, totalZ).getCaveCarveThreshold(); - if (-threshold < lerpNoise && lerpNoise < threshold) - { world.setBlock(totalX, totalY, totalZ, Blocks.AIR); } - // add progress to the noise - lerpNoise += lerpProg; - } - // add z progresses - zW += zpW; - zE += zpE; - } - // add y progresses - ySW += ypSW; - ySE += ypSE; - yNW += ypNW; - yNE += ypNE; - } - } - } - } - } -} diff --git a/src/main/java/com/halotroop/litecraft/world/gen/modifier/WorldModifier.java b/src/main/java/com/halotroop/litecraft/world/gen/modifier/WorldModifier.java deleted file mode 100644 index 18a78d7..0000000 --- a/src/main/java/com/halotroop/litecraft/world/gen/modifier/WorldModifier.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.halotroop.litecraft.world.gen.modifier; - -import java.util.Random; - -import com.halotroop.litecraft.world.BlockAccess; - -public interface WorldModifier -{ - void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ); - - void initialize(long seed); -}