From 180aad05decc7eefa87e4e45d6747c48f40e5361 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Mon, 17 Apr 2023 12:12:01 -0400 Subject: save --- .../net/tylermurphy/Minecraft/Audio/Sound.java | 82 + .../tylermurphy/Minecraft/Audio/SoundManager.java | 45 + .../net/tylermurphy/Minecraft/Chunk/Chunk.java | 111 + .../net/tylermurphy/Minecraft/Chunk/ChunkMesh.java | 214 ++ .../java/net/tylermurphy/Minecraft/Chunk/Cube.java | 156 ++ .../net/tylermurphy/Minecraft/Chunk/Generator.java | 35 + .../tylermurphy/Minecraft/Chunk/PerlinNoise.java | 2147 ++++++++++++++++++++ .../Minecraft/Command/CommandHandler.java | 37 + .../Minecraft/Command/Commands/Teleport.java | 30 + .../tylermurphy/Minecraft/Command/ICommand.java | 11 + .../tylermurphy/Minecraft/Gen/WorldGenerator.java | 112 + .../tylermurphy/Minecraft/Input/CommandInput.java | 57 + .../net/tylermurphy/Minecraft/Input/CoreInput.java | 25 + .../net/tylermurphy/Minecraft/Input/GameInput.java | 85 + .../net/tylermurphy/Minecraft/Input/IInput.java | 12 + .../net/tylermurphy/Minecraft/Input/Input.java | 154 ++ src/main/java/net/tylermurphy/Minecraft/Main.java | 95 + .../Minecraft/Render/ChunkRenderer.java | 99 + .../tylermurphy/Minecraft/Render/Data/Display.java | 175 ++ .../tylermurphy/Minecraft/Render/Data/Mesh.java | 82 + .../tylermurphy/Minecraft/Render/Data/Texture.java | 113 ++ .../tylermurphy/Minecraft/Render/FontRenderer.java | 101 + .../tylermurphy/Minecraft/Render/GuiRenderer.java | 57 + .../tylermurphy/Minecraft/Render/MainRenderer.java | 73 + .../Minecraft/Render/Shaders/ChunkShader.java | 81 + .../Minecraft/Render/Shaders/FontShader.java | 40 + .../Minecraft/Render/Shaders/GuiShader.java | 33 + .../Minecraft/Render/Shaders/QuadShader.java | 37 + .../Minecraft/Render/Util/FrustumCuller.java | 172 ++ .../Minecraft/Render/Util/ShaderProgram.java | 126 ++ .../net/tylermurphy/Minecraft/Scene/Camera.java | 74 + .../Minecraft/Scene/Objects/Entity.java | 105 + .../Minecraft/Scene/Objects/Renderable.java | 46 + .../Minecraft/Scene/Objects/Transform.java | 59 + .../Minecraft/Scene/Objects/WorldOrigin.java | 47 + .../net/tylermurphy/Minecraft/Scene/Player.java | 100 + .../net/tylermurphy/Minecraft/Scene/World.java | 89 + .../tylermurphy/Minecraft/Scripts/GameScript.java | 99 + .../Minecraft/Scripts/PlayerScript.java | 44 + .../net/tylermurphy/Minecraft/Scripts/Script.java | 11 + .../tylermurphy/Minecraft/Scripts/UIScript.java | 62 + .../tylermurphy/Minecraft/Tick/BlockUpdate.java | 53 + .../Minecraft/Tick/GameTicks/GrassTick.java | 50 + .../Minecraft/Tick/GameTicks/WaterTick.java | 45 + .../tylermurphy/Minecraft/Tick/TickManager.java | 24 + .../tylermurphy/Minecraft/UI/Text/Character.java | 72 + .../net/tylermurphy/Minecraft/UI/Text/Line.java | 44 + .../tylermurphy/Minecraft/UI/Text/MetaFile.java | 157 ++ .../tylermurphy/Minecraft/UI/Text/TextMaster.java | 63 + .../Minecraft/UI/Text/TextMeshCreator.java | 140 ++ .../Minecraft/UI/Text/TextMeshData.java | 25 + .../net/tylermurphy/Minecraft/UI/Text/Word.java | 29 + src/main/java/net/tylermurphy/Minecraft/UI/UI.java | 38 + .../net/tylermurphy/Minecraft/UI/UIComponent.java | 104 + .../Minecraft/UI/UIFactory/CommandUI.java | 23 + .../tylermurphy/Minecraft/UI/UIFactory/CoreUI.java | 76 + .../tylermurphy/Minecraft/UI/UIFactory/F3UI.java | 53 + .../Minecraft/UI/UIFactory/SavingUI.java | 17 + .../Minecraft/UI/UIFactory/UIStore.java | 24 + .../java/net/tylermurphy/Minecraft/UI/UIFont.java | 31 + .../java/net/tylermurphy/Minecraft/UI/UIImage.java | 30 + .../tylermurphy/Minecraft/UI/UILayerQuickSort.java | 38 + .../net/tylermurphy/Minecraft/UI/UIMaster.java | 65 + .../java/net/tylermurphy/Minecraft/UI/UIText.java | 110 + .../tylermurphy/Minecraft/Util/ChunkLoader.java | 112 + .../net/tylermurphy/Minecraft/Util/Constants.java | 21 + .../java/net/tylermurphy/Minecraft/Util/Data.java | 16 + .../java/net/tylermurphy/Minecraft/Util/Flags.java | 7 + .../java/net/tylermurphy/Minecraft/Util/Maths.java | 66 + .../tylermurphy/Minecraft/Util/MousePicker.java | 73 + .../Minecraft/Util/ResourceManager.java | 130 ++ 71 files changed, 7069 insertions(+) create mode 100755 src/main/java/net/tylermurphy/Minecraft/Audio/Sound.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Audio/SoundManager.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Chunk/Chunk.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Chunk/ChunkMesh.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Chunk/Cube.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Chunk/Generator.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Chunk/PerlinNoise.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Command/CommandHandler.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Command/Commands/Teleport.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Command/ICommand.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Gen/WorldGenerator.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Input/CommandInput.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Input/CoreInput.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Input/GameInput.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Input/IInput.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Input/Input.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Main.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/ChunkRenderer.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Display.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Mesh.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Data/Texture.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/FontRenderer.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/GuiRenderer.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/MainRenderer.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Shaders/ChunkShader.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Shaders/FontShader.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Shaders/GuiShader.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Shaders/QuadShader.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Util/FrustumCuller.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Render/Util/ShaderProgram.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Camera.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Entity.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Renderable.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/Transform.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Objects/WorldOrigin.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/Player.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scene/World.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scripts/GameScript.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scripts/PlayerScript.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scripts/Script.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Scripts/UIScript.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Tick/BlockUpdate.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Tick/GameTicks/GrassTick.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Tick/GameTicks/WaterTick.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Tick/TickManager.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/Character.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/Line.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/MetaFile.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMaster.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshCreator.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshData.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/Text/Word.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UI.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIComponent.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CommandUI.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CoreUI.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/F3UI.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/SavingUI.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/UIStore.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIFont.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIImage.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UILayerQuickSort.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIMaster.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/UI/UIText.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/ChunkLoader.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/Constants.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/Data.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/Flags.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/Maths.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/MousePicker.java create mode 100755 src/main/java/net/tylermurphy/Minecraft/Util/ResourceManager.java (limited to 'src/main') diff --git a/src/main/java/net/tylermurphy/Minecraft/Audio/Sound.java b/src/main/java/net/tylermurphy/Minecraft/Audio/Sound.java new file mode 100755 index 0000000..58852da --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Audio/Sound.java @@ -0,0 +1,82 @@ +package net.tylermurphy.Minecraft.Audio; + +import org.lwjgl.openal.AL10; +import org.lwjgl.system.*; + +import net.tylermurphy.Minecraft.Util.Constants; + +import java.nio.*; + +import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.stb.STBVorbis.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.libc.LibCStdlib.*; + +public class Sound { + + int bufferId; + int sourceId; + + protected Sound(String fileName) { + ShortBuffer rawAudioBuffer; + + int channels; + int sampleRate; + + try (MemoryStack stack = stackPush()) { + IntBuffer channelsBuffer = stack.mallocInt(1); + IntBuffer sampleRateBuffer = stack.mallocInt(1); + rawAudioBuffer = stb_vorbis_decode_filename(Constants.OGG_LOCATION + fileName +".ogg", channelsBuffer, sampleRateBuffer); + channels = channelsBuffer.get(0); + sampleRate = sampleRateBuffer.get(0); + } + + int format = -1; + if (channels == 1) { + format = AL_FORMAT_MONO16; + } else if (channels == 2) { + format = AL_FORMAT_STEREO16; + } + + bufferId = alGenBuffers(); + alBufferData(bufferId, format, rawAudioBuffer, sampleRate); + free(rawAudioBuffer); + sourceId = alGenSources(); + alSourcei(sourceId, AL_BUFFER, bufferId); + } + + public void play() { + stop(); + alSourcePlay(sourceId); + } + + public boolean isPlaying() { + return AL10.alGetSourcei(sourceId, AL10.AL_SOURCE_STATE) == AL10.AL_PLAYING; + } + + public void stop() { + alSourceStop(sourceId); + } + + public void pause() { + alSourcePause(sourceId); + } + + public void resume() { + alSourcePlay(sourceId); + } + + public void setPosition(int x,int y,int z) { + AL10.alSource3f(sourceId, AL10.AL_POSITION, x, y, z); + } + + public void setLooping(boolean loop) { + AL10.alSourcei(sourceId, AL10.AL_LOOPING, loop ? 1 : 0); + } + + protected void cleanUp() { + alDeleteSources(sourceId); + alDeleteBuffers(bufferId); + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Audio/SoundManager.java b/src/main/java/net/tylermurphy/Minecraft/Audio/SoundManager.java new file mode 100755 index 0000000..10b7d6d --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Audio/SoundManager.java @@ -0,0 +1,45 @@ +package net.tylermurphy.Minecraft.Audio; + +import java.util.ArrayList; + +import java.util.List; + +import org.lwjgl.openal.*; + +public class SoundManager { + + private static long device; + private static long context; + private static List sounds; + + public static void init() { + String defaultDeviceName = ALC10.alcGetString(0, ALC10.ALC_DEFAULT_DEVICE_SPECIFIER); + device = ALC10.alcOpenDevice(defaultDeviceName); + int[] attributes = {0}; + context = ALC10.alcCreateContext(device, attributes); + ALC10.alcMakeContextCurrent(context); + ALCCapabilities alcCapabilities = ALC.createCapabilities(device); + AL.createCapabilities(alcCapabilities); + sounds = new ArrayList<>(); + AL11.alDistanceModel(AL11.AL_LINEAR_DISTANCE_CLAMPED); + } + + public static Sound loadSound(String fileName) { + Sound sound = new Sound(fileName); + sounds.add(sound); + return sound; + } + + public static void cleanUp() { + for(Sound sound : sounds) { + sound.cleanUp(); + } + ALC10.alcDestroyContext(context); + ALC10.alcCloseDevice(device); + } + + public static void setListenerData(float x, float y, float z) { + AL10.alListener3f(AL10.AL_POSITION, x, y, z); + AL10.alListener3f(AL10.AL_VELOCITY, 0, 0, 0); + } +} \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Chunk/Chunk.java b/src/main/java/net/tylermurphy/Minecraft/Chunk/Chunk.java new file mode 100755 index 0000000..f9979e6 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Chunk/Chunk.java @@ -0,0 +1,111 @@ +package net.tylermurphy.Minecraft.Chunk; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import net.tylermurphy.Minecraft.Gen.WorldGenerator; +import net.tylermurphy.Minecraft.Scene.Objects.Renderable; +import net.tylermurphy.Minecraft.Scene.World; + +public class Chunk { + + private static final ExecutorService threadpool = Executors.newCachedThreadPool(); + + public final int gridX; + public final int gridZ; + public final int chunk_seed; + + public byte[][][] cubes; + + private Renderable chunkRenderable, transparentRenderable; + + private ChunkMesh chunkMesh, transparentChunkMesh; + + private final boolean generate; + private boolean initialized = false; + private boolean updating = true; + private boolean scheduled = false; + private int pendingUpdates = 0; + + public Chunk(int gridX, int gridZ, boolean generate) { + this.gridX = gridX; + this.gridZ = gridZ; + this.generate = generate; + this.chunk_seed = gridX * World.seed ^ gridZ; + cubes = new byte[16][256][16]; + } + + public boolean isSafe() { + return initialized; + } + + public Renderable renderable() { + return chunkRenderable; + } + + public void deleteRenderable(){ + this.chunkRenderable = null; + } + + public Renderable transparentRenderable(){ + return transparentRenderable; + } + + public void deleteTransparentRenderable(){ + this.transparentRenderable = null; + } + + public void scheduleFutureMeshUpdate(){ + this.scheduled = true; + } + + public boolean isScheduled(){ + return scheduled; + } + + public void updateMesh() { + if(!initialized || updating){ + pendingUpdates++; + return; + } + chunkMesh = new ChunkMesh(); + transparentChunkMesh = new ChunkMesh(); + updating = true; + scheduled = false; + pendingUpdates--; + threadpool.submit(() -> { + chunkMesh.update(this, false); + transparentChunkMesh.update(this, true); + }); + } + + public boolean loadMesh() { + if(!initialized || !updating) return false; + if(chunkMesh.completed && transparentChunkMesh.completed) { + if(chunkRenderable != null && chunkRenderable.getMesh() != null) + chunkRenderable.getMesh().delete(); + chunkRenderable = chunkMesh.createChunkMesh(); + chunkMesh = null; + if(transparentRenderable != null && transparentRenderable.getMesh() != null) + transparentRenderable.getMesh().delete(); + transparentRenderable = transparentChunkMesh.createChunkMesh(); + transparentChunkMesh = null; + updating = false; + if(pendingUpdates > 0) updateMesh(); + return true; + } + return false; + } + + public void initialize() { + chunkMesh = new ChunkMesh(); + transparentChunkMesh = new ChunkMesh(); + threadpool.submit(() -> { + if(generate) WorldGenerator.generate(this); + chunkMesh.update(this, false); + transparentChunkMesh.update(this, true); + initialized = true; + }); + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Chunk/ChunkMesh.java b/src/main/java/net/tylermurphy/Minecraft/Chunk/ChunkMesh.java new file mode 100755 index 0000000..093243a --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Chunk/ChunkMesh.java @@ -0,0 +1,214 @@ +package net.tylermurphy.Minecraft.Chunk; + +import static net.tylermurphy.Minecraft.Chunk.Cube.*; + +import java.util.ArrayList; +import java.util.List; + +import net.tylermurphy.Minecraft.Scene.Objects.Transform; +import org.json.JSONArray; +import org.json.JSONObject; +import org.joml.Vector2f; +import org.joml.Vector3f; + +import net.tylermurphy.Minecraft.Render.Data.Mesh; +import net.tylermurphy.Minecraft.Scene.World; +import net.tylermurphy.Minecraft.Scene.Objects.Renderable; + +public class ChunkMesh { + + private List verticies; + private List tranaparentVerticies; + private List positionsList; + private List normalsList; + private List tcsList; + private List lightingList; + private List layerList; + + public float[] positions, tcs, normals, lighting, layers; + + private Chunk chunk; + + private boolean transparent; + + public boolean completed = false; + + public void update(Chunk chunk, boolean transparent) { + + this.chunk = chunk; + this.transparent = transparent; + this.completed = false; + + verticies = new ArrayList<>(); + tranaparentVerticies = new ArrayList<>(); + positionsList = new ArrayList<>(); + normalsList = new ArrayList<>(); + tcsList = new ArrayList<>(); + lightingList = new ArrayList<>(); + layerList = new ArrayList<>(); + + buildMesh(); + populateLists(); + + this.completed = true; + } + + private void buildMesh() { + for(int x=0;x<16;x++) { + for(int y=0; y<256; y++) { + for(int z=0; z<16; z++) { + + if(chunk.cubes[x][y][z] == AIR) continue; + + if(getBlock(chunk.cubes[x][y][z]).transparent != transparent) continue; + + boolean px = true, nx = true, py = true, ny = true, pz = true, nz = true; + + if(x<15) px = chunk.cubes[x + 1][y][z] != AIR && transparentCheck(x + 1, y, z, x, y, z); + else px = getCube(chunk.gridX + 1, chunk.gridZ, 0, y, z) != AIR && transparentCheck(getCube(chunk.gridX + 1, chunk.gridZ, 0, y, z), x, y, z); + if(x>0) nx = chunk.cubes[x - 1][y][z] != AIR && transparentCheck(x - 1, y, z, x, y, z); + else nx = getCube(chunk.gridX - 1, chunk.gridZ, 15, y, z) != AIR && transparentCheck(getCube(chunk.gridX - 1, chunk.gridZ, 15, y, z), x, y, z); + if(y<255) py = chunk.cubes[x][y + 1][z] != AIR && transparentCheck(x, y + 1, z, x, y, z); + if(y>0) ny = chunk.cubes[x][y - 1][z] != AIR && transparentCheck(x, y - 1, z, x, y, z); + if(z<15) pz = chunk.cubes[x][y][z + 1] != AIR && transparentCheck(x, y, z + 1, x, y, z); + else pz = getCube(chunk.gridX, chunk.gridZ + 1, x, y, 0) != AIR && transparentCheck(getCube(chunk.gridX, chunk.gridZ + 1, x, y, 0), x, y, z); + if(z>0) nz = chunk.cubes[x][y][z - 1] != AIR && transparentCheck(x, y, z - 1, x, y, z); + else nz = getCube(chunk.gridX, chunk.gridZ - 1, x, y, 15) != AIR && transparentCheck(getCube(chunk.gridX, chunk.gridZ - 1, x, y, 15), x, y, z); + + JSONObject positions = getBlock(chunk.cubes[x][y][z]).positions; + if(chunk.cubes[x][y][z]==17 && ( y==255 || chunk.cubes[x][y+1][z] != 17 )) { + + if(y<255) { + byte xp,xn,zp,zn; + + if(x<15) xp = chunk.cubes[x+1][y+1][z]; + else xp = getCube(chunk.gridX+1,chunk.gridZ,0,y+1,z); + if(x<0) xn = chunk.cubes[x-1][y+1][z]; + else xn = getCube(chunk.gridX-1,chunk.gridZ,15,y+1,z); + if(z<15) zp = chunk.cubes[x][y+1][z+1]; + else zp = getCube(chunk.gridX,chunk.gridZ+1,x,y+1,0); + if(z<0) zn = chunk.cubes[x][y+1][z-1]; + else zn = getCube(chunk.gridX,chunk.gridZ-1,x,y+1,15); + + if(xp != 17 && xn != 17 && zp != 17 && zn != 17) { + positions = models.get("water"); + py = false; + } + } else { + positions = models.get("water"); + py = false; + } + + } + + if(getBlock(chunk.cubes[x][y][z]).transparent && chunk.cubes[x][y][z] != 17 && (y == 0 || chunk.cubes[x][y-1][z] == 17)) { + ny = false; + } + + JSONArray PX_POS = positions.getJSONArray("PX_POS"); + JSONArray NX_POS = positions.getJSONArray("NX_POS"); + JSONArray PY_POS = positions.getJSONArray("PY_POS"); + JSONArray NY_POS = positions.getJSONArray("NY_POS"); + JSONArray PZ_POS = positions.getJSONArray("PZ_POS"); + JSONArray NZ_POS = positions.getJSONArray("NZ_POS"); + + if(!px) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PX_POS.getJSONArray(i).getDouble(0) + x, (float) PX_POS.getJSONArray(i).getDouble(1) + y, (float) PX_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_px, .9f)); } } + if(!nx) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NX_POS.getJSONArray(i).getDouble(0) + x, (float) NX_POS.getJSONArray(i).getDouble(1) + y, (float) NX_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_nx, .9f)); } } + if(!py) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PY_POS.getJSONArray(i).getDouble(0) + x, (float) PY_POS.getJSONArray(i).getDouble(1) + y, (float) PY_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_py, 1f)); } } + if(!ny) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NY_POS.getJSONArray(i).getDouble(0) + x, (float) NY_POS.getJSONArray(i).getDouble(1) + y, (float) NY_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_ny, 1f)); } } + if(!pz) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PZ_POS.getJSONArray(i).getDouble(0) + x, (float) PZ_POS.getJSONArray(i).getDouble(1) + y, (float) PZ_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_pz, .8f)); } } + if(!nz) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NZ_POS.getJSONArray(i).getDouble(0) + x, (float) NZ_POS.getJSONArray(i).getDouble(1) + y, (float) NZ_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_nz, .8f)); } } + } + } + } + } + + private byte getCube(int gx, int gz, int x, int y, int z) { + Chunk c = World.getChunk(gx,gz); + if(c == null) return 0; + return c.cubes[x][y][z]; + } + + private boolean transparentCheck(int x1,int y1,int z1,int x2,int y2,int z2) { + return transparentCheck(chunk.cubes[x1][y1][z1], x2, y2, z2); + } + + private boolean transparentCheck(byte block,int x2,int y2,int z2) { + if(getBlock(block).alwaysRenderNeighbors || getBlock(chunk.cubes[x2][y2][z2]).alwaysRenderNeighbors) + return false; + else if(!getBlock(block).transparent && !getBlock(chunk.cubes[x2][y2][z2]).transparent && block == chunk.cubes[x2][y2][z2]) + return true; + else return getBlock(block).transparent == getBlock(chunk.cubes[x2][y2][z2]).transparent || !getBlock(block).transparent; + } + + static class Vertex{ + Vector3f positions; + Vector2f uvs; + Vector3f normals; + float light; + float layer; + Vertex(Vector3f positions, Vector2f uvs, Vector3f normals, float layer, float light){ + this.positions = positions; + this.uvs = uvs; + this.normals = normals; + this.layer = layer; + this.light = light; + } + } + + private void populateLists() { + for(Vertex vertex : verticies) { + positionsList.add(vertex.positions.x); + positionsList.add(vertex.positions.y); + positionsList.add(vertex.positions.z); + tcsList.add(vertex.uvs.x); + tcsList.add(vertex.uvs.y); + normalsList.add(vertex.normals.x); + normalsList.add(vertex.normals.y); + normalsList.add(vertex.normals.z); + lightingList.add(vertex.light); + layerList.add(vertex.layer); + } + + positions = new float[positionsList.size()]; + tcs = new float[tcsList.size()]; + normals = new float[normalsList.size()]; + lighting = new float[lightingList.size()]; + layers = new float[layerList.size()]; + + for(int i=0;i models = new HashMap<>(); + + public static HashMap textures = new HashMap<>(); + public static HashMap texturePairings = new HashMap<>(); + + public static HashMap blocks = new HashMap<>(); + public static HashMap blockPairings = new HashMap<>(); + + public static Cube getBlock(byte b){ + return blocks.get((int) b); + } + + public static Cube getBlock(String s){ + return blocks.get(blockPairings.get(s)); + } + + private static JSONObject loadJsonFile(File file){ + StringBuilder contentBuilder = new StringBuilder(); + try (Stream stream = Files.lines( Paths.get(file.getPath()), StandardCharsets.UTF_8)){ + stream.forEach(s -> contentBuilder.append(s).append("\n")); + } catch (IOException e) { + e.printStackTrace(); + } + return new JSONObject(contentBuilder.toString()); + } + + private static void loadModels(){ + models = new HashMap<>(); + File dir = new File("assets/models"); + File[] directoryListing = dir.listFiles(); + assert directoryListing != null; + for(File file : directoryListing){ + JSONObject json = loadJsonFile(file); + models.put(file.getName().replaceFirst("[.][^.]+$", ""), json); + } + } + + private static void loadTextures(){ + textures = new HashMap<>(); + texturePairings = new HashMap<>(); + File dir = new File("assets/textures/blocks"); + File[] directoryListing = dir.listFiles(); + int i = 0; + assert directoryListing != null; + for(File file : directoryListing){ + String name = file.getName().replaceFirst("[.][^.]+$", ""); + textures.put(i, Texture.loadRawTextureData("blocks/"+name)); + texturePairings.put(name, i); + i++; + } + TEXTURE = Texture.loadTexture2DArray(textures); + } + + private static void loadBlocks(){ + blocks = new HashMap<>(); + blockPairings = new HashMap<>(); + File file = new File("assets/blocks/blocks.json"); + JSONObject json = loadJsonFile(file); + for(String key : json.keySet()){ + String name = json.getString(key); + int id = Integer.parseInt(key); + blockPairings.put(name, id); + File block_file = new File("assets/blocks/" + name + ".json"); + JSONObject block = loadJsonFile(block_file); + blocks.put(id, createCube(name, block)); + } + } + + private static Cube createCube(String name, JSONObject json){ + Cube cube = new Cube(); + cube.positions = models.get(json.getString("model")); + cube.transparent = json.getBoolean("transparent"); + cube.alwaysRenderNeighbors = json.getBoolean("renderNeighbors"); + cube.placeable = json.getBoolean("placeable"); + cube.name = name; + cube.tick_update_delay = 20; + JSONObject textureList = json.getJSONObject("textures"); + if(json.getString("texture").equals("all")){ + cube.tex_px = texturePairings.get(textureList.getString("face")); + cube.tex_nx = texturePairings.get(textureList.getString("face")); + cube.tex_py = texturePairings.get(textureList.getString("face")); + cube.tex_ny = texturePairings.get(textureList.getString("face")); + cube.tex_pz = texturePairings.get(textureList.getString("face")); + cube.tex_nz = texturePairings.get(textureList.getString("face")); + } else if(json.getString("texture").equals("side")){ + cube.tex_px = texturePairings.get(textureList.getString("side")); + cube.tex_nx = texturePairings.get(textureList.getString("side")); + cube.tex_py = texturePairings.get(textureList.getString("top")); + cube.tex_ny = texturePairings.get(textureList.getString("bottom")); + cube.tex_pz = texturePairings.get(textureList.getString("side")); + cube.tex_nz = texturePairings.get(textureList.getString("side")); + } + return cube; + } + + public static void init() { + + loadModels(); + loadTextures(); + loadBlocks(); + + } + + public static Vector3f[] NORMALS = { + + new Vector3f(0.f, 0.f, 0.f), + new Vector3f(0.f, 0.f, 0.f), + new Vector3f(0.f, 0.f, 0.f), + new Vector3f(0.f, 0.f, 0.f), + new Vector3f(0.f, 0.f, 0.f), + new Vector3f(0.f, 0.f, 0.f) + + }; + + public static Vector2f[] TEXTURE_CORDS = { + + new Vector2f(0.f, 0.f), + new Vector2f(0.f, 1.f), + new Vector2f(1.f, 1.f), + new Vector2f(1.f, 1.f), + new Vector2f(1.f, 0.f), + new Vector2f(0.f, 0.f) + + }; + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Chunk/Generator.java b/src/main/java/net/tylermurphy/Minecraft/Chunk/Generator.java new file mode 100755 index 0000000..395923e --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Chunk/Generator.java @@ -0,0 +1,35 @@ +package net.tylermurphy.Minecraft.Chunk; + +import net.tylermurphy.Minecraft.Scene.World; + +public class Generator { + + private static void generateLandscape(Chunk c) { + for(int x=0;x<16;x++) { + for(int z=0;z<16;z++) { + + int biome = (int) (PerlinNoise.getNoise(World.seed, c.gridX*16+x, c.gridZ*16+z, PerlinNoise.NoiseType.Cellular)*3)+3; + biome = Math.max(1, Math.min(6, biome)); + + int height1 = (int) (PerlinNoise.getNoise(World.seed, c.gridX*16+x, c.gridZ*16+z, PerlinNoise.NoiseType.PerlinFractal)*biome)+biome; + int height2 = (int) (PerlinNoise.getNoise(World.seed+1, c.gridX*16+x, c.gridZ*16+z, PerlinNoise.NoiseType.Perlin)*biome)+biome; + int height3 = (int) (PerlinNoise.getNoise(World.seed+2, c.gridX*16+x, c.gridZ*16+z, PerlinNoise.NoiseType.Simplex)*biome)+biome; + + int top = 90 + height1 + height2 - height3; + + for(int y=0;y<256;y++) { + if(y= 0 ? (int) f : (int) f - 1); + } + + + private static int FastRound(float f) { + return (f >= 0) ? (int) (f + (float) 0.5) : (int) (f - (float) 0.5); + } + + + private static float Lerp(float a, float b, float t) { + return a + t * (b - a); + } + + + private static float InterpHermiteFunc(float t) { + return t * t * (3 - 2 * t); + } + + + private static float InterpQuinticFunc(float t) { + return t * t * t * (t * (t * 6 - 15) + 10); + } + + + private static float CubicLerp(float a, float b, float c, float d, float t) { + float p = (d - c) - (a - b); + return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b; + } + + private void CalculateFractalBounding() { + float amp = m_gain; + float ampFractal = 1; + for (int i = 1; i < m_octaves; i++) { + ampFractal += amp; + amp *= m_gain; + } + m_fractalBounding = 1 / ampFractal; + } + + // Hashing + private final static int X_PRIME = 1619; + private final static int Y_PRIME = 31337; + private final static int Z_PRIME = 6971; + private final static int W_PRIME = 1013; + + private static int Hash2D(int seed, int x, int y) { + int hash = seed; + hash ^= X_PRIME * x; + hash ^= Y_PRIME * y; + + hash = hash * hash * hash * 60493; + hash = (hash >> 13) ^ hash; + + return hash; + } + + private static int Hash3D(int seed, int x, int y, int z) { + int hash = seed; + hash ^= X_PRIME * x; + hash ^= Y_PRIME * y; + hash ^= Z_PRIME * z; + + hash = hash * hash * hash * 60493; + hash = (hash >> 13) ^ hash; + + return hash; + } + + private static float ValCoord2D(int seed, int x, int y) { + int n = seed; + n ^= X_PRIME * x; + n ^= Y_PRIME * y; + + return (n * n * n * 60493) / (float) 2147483648.0; + } + + private static float ValCoord3D(int seed, int x, int y, int z) { + int n = seed; + n ^= X_PRIME * x; + n ^= Y_PRIME * y; + n ^= Z_PRIME * z; + + return (n * n * n * 60493) / (float) 2147483648.0; + } + + private static float ValCoord4D(int seed, int x, int y, int z, int w) { + int n = seed; + n ^= X_PRIME * x; + n ^= Y_PRIME * y; + n ^= Z_PRIME * z; + n ^= W_PRIME * w; + + return (n * n * n * 60493) / (float) 2147483648.0; + } + + private static float GradCoord2D(int seed, int x, int y, float xd, float yd) { + int hash = seed; + hash ^= X_PRIME * x; + hash ^= Y_PRIME * y; + + hash = hash * hash * hash * 60493; + hash = (hash >> 13) ^ hash; + + Float2 g = GRAD_2D[hash & 7]; + + return xd * g.x + yd * g.y; + } + + private static float GradCoord3D(int seed, int x, int y, int z, float xd, float yd, float zd) { + int hash = seed; + hash ^= X_PRIME * x; + hash ^= Y_PRIME * y; + hash ^= Z_PRIME * z; + + hash = hash * hash * hash * 60493; + hash = (hash >> 13) ^ hash; + + Float3 g = GRAD_3D[hash & 15]; + + return xd * g.x + yd * g.y + zd * g.z; + } + + private static float GradCoord4D(int seed, int x, int y, int z, int w, float xd, float yd, float zd, float wd) { + int hash = seed; + hash ^= X_PRIME * x; + hash ^= Y_PRIME * y; + hash ^= Z_PRIME * z; + hash ^= W_PRIME * w; + + hash = hash * hash * hash * 60493; + hash = (hash >> 13) ^ hash; + + hash &= 31; + float a = yd, b = zd, c = wd; // X,Y,Z + switch (hash >> 3) { // OR, DEPENDING ON HIGH ORDER 2 BITS: + case 1: + a = wd; + b = xd; + c = yd; + break; // W,X,Y + case 2: + a = zd; + b = wd; + c = xd; + break; // Z,W,X + case 3: + a = yd; + b = zd; + c = wd; + break; // Y,Z,W + } + return ((hash & 4) == 0 ? -a : a) + ((hash & 2) == 0 ? -b : b) + ((hash & 1) == 0 ? -c : c); + } + + public float GetNoise(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_noiseType) { + case Value: + return SingleValue(m_seed, x, y, z); + case ValueFractal: + switch (m_fractalType) { + case FBM: + return SingleValueFractalFBM(x, y, z); + case Billow: + return SingleValueFractalBillow(x, y, z); + case RigidMulti: + return SingleValueFractalRigidMulti(x, y, z); + default: + return 0; + } + case Perlin: + return SinglePerlin(m_seed, x, y, z); + case PerlinFractal: + switch (m_fractalType) { + case FBM: + return SinglePerlinFractalFBM(x, y, z); + case Billow: + return SinglePerlinFractalBillow(x, y, z); + case RigidMulti: + return SinglePerlinFractalRigidMulti(x, y, z); + default: + return 0; + } + case Simplex: + return SingleSimplex(m_seed, x, y, z); + case SimplexFractal: + switch (m_fractalType) { + case FBM: + return SingleSimplexFractalFBM(x, y, z); + case Billow: + return SingleSimplexFractalBillow(x, y, z); + case RigidMulti: + return SingleSimplexFractalRigidMulti(x, y, z); + default: + return 0; + } + case Cellular: + switch (m_cellularReturnType) { + case CellValue: + case NoiseLookup: + case Distance: + return SingleCellular(x, y, z); + default: + return SingleCellular2Edge(x, y, z); + } + case WhiteNoise: + return GetWhiteNoise(x, y, z); + case Cubic: + return SingleCubic(m_seed, x, y, z); + case CubicFractal: + switch (m_fractalType) { + case FBM: + return SingleCubicFractalFBM(x, y, z); + case Billow: + return SingleCubicFractalBillow(x, y, z); + case RigidMulti: + return SingleCubicFractalRigidMulti(x, y, z); + default: + return 0; + } + default: + return 0; + } + } + + public float GetNoise(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_noiseType) { + case Value: + return SingleValue(m_seed, x, y); + case ValueFractal: + switch (m_fractalType) { + case FBM: + return SingleValueFractalFBM(x, y); + case Billow: + return SingleValueFractalBillow(x, y); + case RigidMulti: + return SingleValueFractalRigidMulti(x, y); + default: + return 0; + } + case Perlin: + return SinglePerlin(m_seed, x, y); + case PerlinFractal: + switch (m_fractalType) { + case FBM: + return SinglePerlinFractalFBM(x, y); + case Billow: + return SinglePerlinFractalBillow(x, y); + case RigidMulti: + return SinglePerlinFractalRigidMulti(x, y); + default: + return 0; + } + case Simplex: + return SingleSimplex(m_seed, x, y); + case SimplexFractal: + switch (m_fractalType) { + case FBM: + return SingleSimplexFractalFBM(x, y); + case Billow: + return SingleSimplexFractalBillow(x, y); + case RigidMulti: + return SingleSimplexFractalRigidMulti(x, y); + default: + return 0; + } + case Cellular: + switch (m_cellularReturnType) { + case CellValue: + case NoiseLookup: + case Distance: + return SingleCellular(x, y); + default: + return SingleCellular2Edge(x, y); + } + case WhiteNoise: + return GetWhiteNoise(x, y); + case Cubic: + return SingleCubic(m_seed, x, y); + case CubicFractal: + switch (m_fractalType) { + case FBM: + return SingleCubicFractalFBM(x, y); + case Billow: + return SingleCubicFractalBillow(x, y); + case RigidMulti: + return SingleCubicFractalRigidMulti(x, y); + default: + return 0; + } + default: + return 0; + } + } + + // White Noise + + private int FloatCast2Int(float f) { + int i = Float.floatToRawIntBits(f); + + return i ^ (i >> 16); + } + + public float GetWhiteNoise(float x, float y, float z, float w) { + int xi = FloatCast2Int(x); + int yi = FloatCast2Int(y); + int zi = FloatCast2Int(z); + int wi = FloatCast2Int(w); + + return ValCoord4D(m_seed, xi, yi, zi, wi); + } + + public float GetWhiteNoise(float x, float y, float z) { + int xi = FloatCast2Int(x); + int yi = FloatCast2Int(y); + int zi = FloatCast2Int(z); + + return ValCoord3D(m_seed, xi, yi, zi); + } + + public float GetWhiteNoise(float x, float y) { + int xi = FloatCast2Int(x); + int yi = FloatCast2Int(y); + + return ValCoord2D(m_seed, xi, yi); + } + + public float GetWhiteNoiseInt(int x, int y, int z, int w) { + return ValCoord4D(m_seed, x, y, z, w); + } + + public float GetWhiteNoiseInt(int x, int y, int z) { + return ValCoord3D(m_seed, x, y, z); + } + + public float GetWhiteNoiseInt(int x, int y) { + return ValCoord2D(m_seed, x, y); + } + + // Value Noise + public float GetValueFractal(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleValueFractalFBM(x, y, z); + case Billow: + return SingleValueFractalBillow(x, y, z); + case RigidMulti: + return SingleValueFractalRigidMulti(x, y, z); + default: + return 0; + } + } + + private float SingleValueFractalFBM(float x, float y, float z) { + int seed = m_seed; + float sum = SingleValue(seed, x, y, z); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += SingleValue(++seed, x, y, z) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleValueFractalBillow(float x, float y, float z) { + int seed = m_seed; + float sum = Math.abs(SingleValue(seed, x, y, z)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SingleValue(++seed, x, y, z)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleValueFractalRigidMulti(float x, float y, float z) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleValue(seed, x, y, z)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleValue(++seed, x, y, z))) * amp; + } + + return sum; + } + + public float GetValue(float x, float y, float z) { + return SingleValue(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); + } + + private float SingleValue(int seed, float x, float y, float z) { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int z0 = FastFloor(z); + int x1 = x0 + 1; + int y1 = y0 + 1; + int z1 = z0 + 1; + + float xs, ys, zs; + switch (m_interp) { + default: + case Linear: + xs = x - x0; + ys = y - y0; + zs = z - z0; + break; + case Hermite: + xs = InterpHermiteFunc(x - x0); + ys = InterpHermiteFunc(y - y0); + zs = InterpHermiteFunc(z - z0); + break; + case Quintic: + xs = InterpQuinticFunc(x - x0); + ys = InterpQuinticFunc(y - y0); + zs = InterpQuinticFunc(z - z0); + break; + } + + float xf00 = Lerp(ValCoord3D(seed, x0, y0, z0), ValCoord3D(seed, x1, y0, z0), xs); + float xf10 = Lerp(ValCoord3D(seed, x0, y1, z0), ValCoord3D(seed, x1, y1, z0), xs); + float xf01 = Lerp(ValCoord3D(seed, x0, y0, z1), ValCoord3D(seed, x1, y0, z1), xs); + float xf11 = Lerp(ValCoord3D(seed, x0, y1, z1), ValCoord3D(seed, x1, y1, z1), xs); + + float yf0 = Lerp(xf00, xf10, ys); + float yf1 = Lerp(xf01, xf11, ys); + + return Lerp(yf0, yf1, zs); + } + + public float GetValueFractal(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleValueFractalFBM(x, y); + case Billow: + return SingleValueFractalBillow(x, y); + case RigidMulti: + return SingleValueFractalRigidMulti(x, y); + default: + return 0; + } + } + + private float SingleValueFractalFBM(float x, float y) { + int seed = m_seed; + float sum = SingleValue(seed, x, y); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += SingleValue(++seed, x, y) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleValueFractalBillow(float x, float y) { + int seed = m_seed; + float sum = Math.abs(SingleValue(seed, x, y)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + amp *= m_gain; + sum += (Math.abs(SingleValue(++seed, x, y)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleValueFractalRigidMulti(float x, float y) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleValue(seed, x, y)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleValue(++seed, x, y))) * amp; + } + + return sum; + } + + public float GetValue(float x, float y) { + return SingleValue(m_seed, x * m_frequency, y * m_frequency); + } + + private float SingleValue(int seed, float x, float y) { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int x1 = x0 + 1; + int y1 = y0 + 1; + + float xs, ys; + switch (m_interp) { + default: + case Linear: + xs = x - x0; + ys = y - y0; + break; + case Hermite: + xs = InterpHermiteFunc(x - x0); + ys = InterpHermiteFunc(y - y0); + break; + case Quintic: + xs = InterpQuinticFunc(x - x0); + ys = InterpQuinticFunc(y - y0); + break; + } + + float xf0 = Lerp(ValCoord2D(seed, x0, y0), ValCoord2D(seed, x1, y0), xs); + float xf1 = Lerp(ValCoord2D(seed, x0, y1), ValCoord2D(seed, x1, y1), xs); + + return Lerp(xf0, xf1, ys); + } + + // Gradient Noise + public float GetPerlinFractal(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SinglePerlinFractalFBM(x, y, z); + case Billow: + return SinglePerlinFractalBillow(x, y, z); + case RigidMulti: + return SinglePerlinFractalRigidMulti(x, y, z); + default: + return 0; + } + } + + private float SinglePerlinFractalFBM(float x, float y, float z) { + int seed = m_seed; + float sum = SinglePerlin(seed, x, y, z); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += SinglePerlin(++seed, x, y, z) * amp; + } + + return sum * m_fractalBounding; + } + + private float SinglePerlinFractalBillow(float x, float y, float z) { + int seed = m_seed; + float sum = Math.abs(SinglePerlin(seed, x, y, z)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SinglePerlin(++seed, x, y, z)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SinglePerlinFractalRigidMulti(float x, float y, float z) { + int seed = m_seed; + float sum = 1 - Math.abs(SinglePerlin(seed, x, y, z)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SinglePerlin(++seed, x, y, z))) * amp; + } + + return sum; + } + + public float GetPerlin(float x, float y, float z) { + return SinglePerlin(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); + } + + private float SinglePerlin(int seed, float x, float y, float z) { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int z0 = FastFloor(z); + int x1 = x0 + 1; + int y1 = y0 + 1; + int z1 = z0 + 1; + + float xs, ys, zs; + switch (m_interp) { + default: + case Linear: + xs = x - x0; + ys = y - y0; + zs = z - z0; + break; + case Hermite: + xs = InterpHermiteFunc(x - x0); + ys = InterpHermiteFunc(y - y0); + zs = InterpHermiteFunc(z - z0); + break; + case Quintic: + xs = InterpQuinticFunc(x - x0); + ys = InterpQuinticFunc(y - y0); + zs = InterpQuinticFunc(z - z0); + break; + } + + float xd0 = x - x0; + float yd0 = y - y0; + float zd0 = z - z0; + float xd1 = xd0 - 1; + float yd1 = yd0 - 1; + float zd1 = zd0 - 1; + + float xf00 = Lerp(GradCoord3D(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord3D(seed, x1, y0, z0, xd1, yd0, zd0), xs); + float xf10 = Lerp(GradCoord3D(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord3D(seed, x1, y1, z0, xd1, yd1, zd0), xs); + float xf01 = Lerp(GradCoord3D(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord3D(seed, x1, y0, z1, xd1, yd0, zd1), xs); + float xf11 = Lerp(GradCoord3D(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord3D(seed, x1, y1, z1, xd1, yd1, zd1), xs); + + float yf0 = Lerp(xf00, xf10, ys); + float yf1 = Lerp(xf01, xf11, ys); + + return Lerp(yf0, yf1, zs); + } + + public float GetPerlinFractal(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SinglePerlinFractalFBM(x, y); + case Billow: + return SinglePerlinFractalBillow(x, y); + case RigidMulti: + return SinglePerlinFractalRigidMulti(x, y); + default: + return 0; + } + } + + private float SinglePerlinFractalFBM(float x, float y) { + int seed = m_seed; + float sum = SinglePerlin(seed, x, y); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += SinglePerlin(++seed, x, y) * amp; + } + + return sum * m_fractalBounding; + } + + private float SinglePerlinFractalBillow(float x, float y) { + int seed = m_seed; + float sum = Math.abs(SinglePerlin(seed, x, y)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SinglePerlin(++seed, x, y)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SinglePerlinFractalRigidMulti(float x, float y) { + int seed = m_seed; + float sum = 1 - Math.abs(SinglePerlin(seed, x, y)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SinglePerlin(++seed, x, y))) * amp; + } + + return sum; + } + + public float GetPerlin(float x, float y) { + return SinglePerlin(m_seed, x * m_frequency, y * m_frequency); + } + + private float SinglePerlin(int seed, float x, float y) { + int x0 = FastFloor(x); + int y0 = FastFloor(y); + int x1 = x0 + 1; + int y1 = y0 + 1; + + float xs, ys; + switch (m_interp) { + default: + case Linear: + xs = x - x0; + ys = y - y0; + break; + case Hermite: + xs = InterpHermiteFunc(x - x0); + ys = InterpHermiteFunc(y - y0); + break; + case Quintic: + xs = InterpQuinticFunc(x - x0); + ys = InterpQuinticFunc(y - y0); + break; + } + + float xd0 = x - x0; + float yd0 = y - y0; + float xd1 = xd0 - 1; + float yd1 = yd0 - 1; + + float xf0 = Lerp(GradCoord2D(seed, x0, y0, xd0, yd0), GradCoord2D(seed, x1, y0, xd1, yd0), xs); + float xf1 = Lerp(GradCoord2D(seed, x0, y1, xd0, yd1), GradCoord2D(seed, x1, y1, xd1, yd1), xs); + + return Lerp(xf0, xf1, ys); + } + + // Simplex Noise + public float GetSimplexFractal(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleSimplexFractalFBM(x, y, z); + case Billow: + return SingleSimplexFractalBillow(x, y, z); + case RigidMulti: + return SingleSimplexFractalRigidMulti(x, y, z); + default: + return 0; + } + } + + private float SingleSimplexFractalFBM(float x, float y, float z) { + int seed = m_seed; + float sum = SingleSimplex(seed, x, y, z); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += SingleSimplex(++seed, x, y, z) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleSimplexFractalBillow(float x, float y, float z) { + int seed = m_seed; + float sum = Math.abs(SingleSimplex(seed, x, y, z)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SingleSimplex(++seed, x, y, z)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleSimplexFractalRigidMulti(float x, float y, float z) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleSimplex(seed, x, y, z)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleSimplex(++seed, x, y, z))) * amp; + } + + return sum; + } + + public float GetSimplex(float x, float y, float z) { + return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); + } + + private final static float F3 = (float) (1.0 / 3.0); + private final static float G3 = (float) (1.0 / 6.0); + private final static float G33 = G3 * 3 - 1; + + private float SingleSimplex(int seed, float x, float y, float z) { + float t = (x + y + z) * F3; + int i = FastFloor(x + t); + int j = FastFloor(y + t); + int k = FastFloor(z + t); + + t = (i + j + k) * G3; + float x0 = x - (i - t); + float y0 = y - (j - t); + float z0 = z - (k - t); + + int i1, j1, k1; + int i2, j2, k2; + + if (x0 >= y0) { + if (y0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 1; + k2 = 0; + } else if (x0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 0; + k2 = 1; + } else // x0 < z0 + { + i1 = 0; + j1 = 0; + k1 = 1; + i2 = 1; + j2 = 0; + k2 = 1; + } + } else // x0 < y0 + { + if (y0 < z0) { + i1 = 0; + j1 = 0; + k1 = 1; + i2 = 0; + j2 = 1; + k2 = 1; + } else if (x0 < z0) { + i1 = 0; + j1 = 1; + k1 = 0; + i2 = 0; + j2 = 1; + k2 = 1; + } else // x0 >= z0 + { + i1 = 0; + j1 = 1; + k1 = 0; + i2 = 1; + j2 = 1; + k2 = 0; + } + } + + float x1 = x0 - i1 + G3; + float y1 = y0 - j1 + G3; + float z1 = z0 - k1 + G3; + float x2 = x0 - i2 + F3; + float y2 = y0 - j2 + F3; + float z2 = z0 - k2 + F3; + float x3 = x0 + G33; + float y3 = y0 + G33; + float z3 = z0 + G33; + + float n0, n1, n2, n3; + + t = (float) 0.6 - x0 * x0 - y0 * y0 - z0 * z0; + if (t < 0) n0 = 0; + else { + t *= t; + n0 = t * t * GradCoord3D(seed, i, j, k, x0, y0, z0); + } + + t = (float) 0.6 - x1 * x1 - y1 * y1 - z1 * z1; + if (t < 0) n1 = 0; + else { + t *= t; + n1 = t * t * GradCoord3D(seed, i + i1, j + j1, k + k1, x1, y1, z1); + } + + t = (float) 0.6 - x2 * x2 - y2 * y2 - z2 * z2; + if (t < 0) n2 = 0; + else { + t *= t; + n2 = t * t * GradCoord3D(seed, i + i2, j + j2, k + k2, x2, y2, z2); + } + + t = (float) 0.6 - x3 * x3 - y3 * y3 - z3 * z3; + if (t < 0) n3 = 0; + else { + t *= t; + n3 = t * t * GradCoord3D(seed, i + 1, j + 1, k + 1, x3, y3, z3); + } + + return 32 * (n0 + n1 + n2 + n3); + } + + public float GetSimplexFractal(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleSimplexFractalFBM(x, y); + case Billow: + return SingleSimplexFractalBillow(x, y); + case RigidMulti: + return SingleSimplexFractalRigidMulti(x, y); + default: + return 0; + } + } + + private float SingleSimplexFractalFBM(float x, float y) { + int seed = m_seed; + float sum = SingleSimplex(seed, x, y); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += SingleSimplex(++seed, x, y) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleSimplexFractalBillow(float x, float y) { + int seed = m_seed; + float sum = Math.abs(SingleSimplex(seed, x, y)) * 2 - 1; + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SingleSimplex(++seed, x, y)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleSimplexFractalRigidMulti(float x, float y) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleSimplex(seed, x, y)); + float amp = 1; + + for (int i = 1; i < m_octaves; i++) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleSimplex(++seed, x, y))) * amp; + } + + return sum; + } + + public float GetSimplex(float x, float y) { + return SingleSimplex(m_seed, x * m_frequency, y * m_frequency); + } + + private final static float F2 = (float) (1.0 / 2.0); + private final static float G2 = (float) (1.0 / 4.0); + + private float SingleSimplex(int seed, float x, float y) { + float t = (x + y) * F2; + int i = FastFloor(x + t); + int j = FastFloor(y + t); + + t = (i + j) * G2; + float X0 = i - t; + float Y0 = j - t; + + float x0 = x - X0; + float y0 = y - Y0; + + int i1, j1; + if (x0 > y0) { + i1 = 1; + j1 = 0; + } else { + i1 = 0; + j1 = 1; + } + + float x1 = x0 - i1 + G2; + float y1 = y0 - j1 + G2; + float x2 = x0 - 1 + F2; + float y2 = y0 - 1 + F2; + + float n0, n1, n2; + + t = (float) 0.5 - x0 * x0 - y0 * y0; + if (t < 0) n0 = 0; + else { + t *= t; + n0 = t * t * GradCoord2D(seed, i, j, x0, y0); + } + + t = (float) 0.5 - x1 * x1 - y1 * y1; + if (t < 0) n1 = 0; + else { + t *= t; + n1 = t * t * GradCoord2D(seed, i + i1, j + j1, x1, y1); + } + + t = (float) 0.5 - x2 * x2 - y2 * y2; + if (t < 0) n2 = 0; + else { + t *= t; + n2 = t * t * GradCoord2D(seed, i + 1, j + 1, x2, y2); + } + + return 50 * (n0 + n1 + n2); + } + + public float GetSimplex(float x, float y, float z, float w) { + return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency, w * m_frequency); + } + + private static final byte[] SIMPLEX_4D = + { + 0, 1, 2, 3, 0, 1, 3, 2, 0, 0, 0, 0, 0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, + 0, 2, 1, 3, 0, 0, 0, 0, 0, 3, 1, 2, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 3, 0, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 2, 3, 1, 0, + 1, 0, 2, 3, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 2, 1, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 3, 0, 2, 1, 0, 0, 0, 0, 3, 1, 2, 0, + 2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 2, 0, 0, 0, 0, 3, 2, 0, 1, 3, 2, 1, 0 + }; + + private final static float F4 = (float) ((2.23606797 - 1.0) / 4.0); + private final static float G4 = (float) ((5.0 - 2.23606797) / 20.0); + + private float SingleSimplex(int seed, float x, float y, float z, float w) { + float n0, n1, n2, n3, n4; + float t = (x + y + z + w) * F4; + int i = FastFloor(x + t); + int j = FastFloor(y + t); + int k = FastFloor(z + t); + int l = FastFloor(w + t); + t = (i + j + k + l) * G4; + float X0 = i - t; + float Y0 = j - t; + float Z0 = k - t; + float W0 = l - t; + float x0 = x - X0; + float y0 = y - Y0; + float z0 = z - Z0; + float w0 = w - W0; + + int c = (x0 > y0) ? 32 : 0; + c += (x0 > z0) ? 16 : 0; + c += (y0 > z0) ? 8 : 0; + c += (x0 > w0) ? 4 : 0; + c += (y0 > w0) ? 2 : 0; + c += (z0 > w0) ? 1 : 0; + c <<= 2; + + int i1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; + int i2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; + int i3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; + int j1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; + int j2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; + int j3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; + int k1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; + int k2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; + int k3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; + int l1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; + int l2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; + int l3 = SIMPLEX_4D[c] >= 1 ? 1 : 0; + + float x1 = x0 - i1 + G4; + float y1 = y0 - j1 + G4; + float z1 = z0 - k1 + G4; + float w1 = w0 - l1 + G4; + float x2 = x0 - i2 + 2 * G4; + float y2 = y0 - j2 + 2 * G4; + float z2 = z0 - k2 + 2 * G4; + float w2 = w0 - l2 + 2 * G4; + float x3 = x0 - i3 + 3 * G4; + float y3 = y0 - j3 + 3 * G4; + float z3 = z0 - k3 + 3 * G4; + float w3 = w0 - l3 + 3 * G4; + float x4 = x0 - 1 + 4 * G4; + float y4 = y0 - 1 + 4 * G4; + float z4 = z0 - 1 + 4 * G4; + float w4 = w0 - 1 + 4 * G4; + + t = (float) 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; + if (t < 0) n0 = 0; + else { + t *= t; + n0 = t * t * GradCoord4D(seed, i, j, k, l, x0, y0, z0, w0); + } + t = (float) 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; + if (t < 0) n1 = 0; + else { + t *= t; + n1 = t * t * GradCoord4D(seed, i + i1, j + j1, k + k1, l + l1, x1, y1, z1, w1); + } + t = (float) 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; + if (t < 0) n2 = 0; + else { + t *= t; + n2 = t * t * GradCoord4D(seed, i + i2, j + j2, k + k2, l + l2, x2, y2, z2, w2); + } + t = (float) 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; + if (t < 0) n3 = 0; + else { + t *= t; + n3 = t * t * GradCoord4D(seed, i + i3, j + j3, k + k3, l + l3, x3, y3, z3, w3); + } + t = (float) 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; + if (t < 0) n4 = 0; + else { + t *= t; + n4 = t * t * GradCoord4D(seed, i + 1, j + 1, k + 1, l + 1, x4, y4, z4, w4); + } + + return 27 * (n0 + n1 + n2 + n3 + n4); + } + + // Cubic Noise + public float GetCubicFractal(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleCubicFractalFBM(x, y, z); + case Billow: + return SingleCubicFractalBillow(x, y, z); + case RigidMulti: + return SingleCubicFractalRigidMulti(x, y, z); + default: + return 0; + } + } + + private float SingleCubicFractalFBM(float x, float y, float z) { + int seed = m_seed; + float sum = SingleCubic(seed, x, y, z); + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += SingleCubic(++seed, x, y, z) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleCubicFractalBillow(float x, float y, float z) { + int seed = m_seed; + float sum = Math.abs(SingleCubic(seed, x, y, z)) * 2 - 1; + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SingleCubic(++seed, x, y, z)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleCubicFractalRigidMulti(float x, float y, float z) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleCubic(seed, x, y, z)); + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + z *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleCubic(++seed, x, y, z))) * amp; + } + + return sum; + } + + public float GetCubic(float x, float y, float z) { + return SingleCubic(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); + } + + private final static float CUBIC_3D_BOUNDING = 1 / (float) (1.5 * 1.5 * 1.5); + + private float SingleCubic(int seed, float x, float y, float z) { + int x1 = FastFloor(x); + int y1 = FastFloor(y); + int z1 = FastFloor(z); + + int x0 = x1 - 1; + int y0 = y1 - 1; + int z0 = z1 - 1; + int x2 = x1 + 1; + int y2 = y1 + 1; + int z2 = z1 + 1; + int x3 = x1 + 2; + int y3 = y1 + 2; + int z3 = z1 + 2; + + float xs = x - (float) x1; + float ys = y - (float) y1; + float zs = z - (float) z1; + + return CubicLerp( + CubicLerp( + CubicLerp(ValCoord3D(seed, x0, y0, z0), ValCoord3D(seed, x1, y0, z0), ValCoord3D(seed, x2, y0, z0), ValCoord3D(seed, x3, y0, z0), xs), + CubicLerp(ValCoord3D(seed, x0, y1, z0), ValCoord3D(seed, x1, y1, z0), ValCoord3D(seed, x2, y1, z0), ValCoord3D(seed, x3, y1, z0), xs), + CubicLerp(ValCoord3D(seed, x0, y2, z0), ValCoord3D(seed, x1, y2, z0), ValCoord3D(seed, x2, y2, z0), ValCoord3D(seed, x3, y2, z0), xs), + CubicLerp(ValCoord3D(seed, x0, y3, z0), ValCoord3D(seed, x1, y3, z0), ValCoord3D(seed, x2, y3, z0), ValCoord3D(seed, x3, y3, z0), xs), + ys), + CubicLerp( + CubicLerp(ValCoord3D(seed, x0, y0, z1), ValCoord3D(seed, x1, y0, z1), ValCoord3D(seed, x2, y0, z1), ValCoord3D(seed, x3, y0, z1), xs), + CubicLerp(ValCoord3D(seed, x0, y1, z1), ValCoord3D(seed, x1, y1, z1), ValCoord3D(seed, x2, y1, z1), ValCoord3D(seed, x3, y1, z1), xs), + CubicLerp(ValCoord3D(seed, x0, y2, z1), ValCoord3D(seed, x1, y2, z1), ValCoord3D(seed, x2, y2, z1), ValCoord3D(seed, x3, y2, z1), xs), + CubicLerp(ValCoord3D(seed, x0, y3, z1), ValCoord3D(seed, x1, y3, z1), ValCoord3D(seed, x2, y3, z1), ValCoord3D(seed, x3, y3, z1), xs), + ys), + CubicLerp( + CubicLerp(ValCoord3D(seed, x0, y0, z2), ValCoord3D(seed, x1, y0, z2), ValCoord3D(seed, x2, y0, z2), ValCoord3D(seed, x3, y0, z2), xs), + CubicLerp(ValCoord3D(seed, x0, y1, z2), ValCoord3D(seed, x1, y1, z2), ValCoord3D(seed, x2, y1, z2), ValCoord3D(seed, x3, y1, z2), xs), + CubicLerp(ValCoord3D(seed, x0, y2, z2), ValCoord3D(seed, x1, y2, z2), ValCoord3D(seed, x2, y2, z2), ValCoord3D(seed, x3, y2, z2), xs), + CubicLerp(ValCoord3D(seed, x0, y3, z2), ValCoord3D(seed, x1, y3, z2), ValCoord3D(seed, x2, y3, z2), ValCoord3D(seed, x3, y3, z2), xs), + ys), + CubicLerp( + CubicLerp(ValCoord3D(seed, x0, y0, z3), ValCoord3D(seed, x1, y0, z3), ValCoord3D(seed, x2, y0, z3), ValCoord3D(seed, x3, y0, z3), xs), + CubicLerp(ValCoord3D(seed, x0, y1, z3), ValCoord3D(seed, x1, y1, z3), ValCoord3D(seed, x2, y1, z3), ValCoord3D(seed, x3, y1, z3), xs), + CubicLerp(ValCoord3D(seed, x0, y2, z3), ValCoord3D(seed, x1, y2, z3), ValCoord3D(seed, x2, y2, z3), ValCoord3D(seed, x3, y2, z3), xs), + CubicLerp(ValCoord3D(seed, x0, y3, z3), ValCoord3D(seed, x1, y3, z3), ValCoord3D(seed, x2, y3, z3), ValCoord3D(seed, x3, y3, z3), xs), + ys), + zs) * CUBIC_3D_BOUNDING; + } + + + public float GetCubicFractal(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_fractalType) { + case FBM: + return SingleCubicFractalFBM(x, y); + case Billow: + return SingleCubicFractalBillow(x, y); + case RigidMulti: + return SingleCubicFractalRigidMulti(x, y); + default: + return 0; + } + } + + private float SingleCubicFractalFBM(float x, float y) { + int seed = m_seed; + float sum = SingleCubic(seed, x, y); + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += SingleCubic(++seed, x, y) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleCubicFractalBillow(float x, float y) { + int seed = m_seed; + float sum = Math.abs(SingleCubic(seed, x, y)) * 2 - 1; + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum += (Math.abs(SingleCubic(++seed, x, y)) * 2 - 1) * amp; + } + + return sum * m_fractalBounding; + } + + private float SingleCubicFractalRigidMulti(float x, float y) { + int seed = m_seed; + float sum = 1 - Math.abs(SingleCubic(seed, x, y)); + float amp = 1; + int i = 0; + + while (++i < m_octaves) { + x *= m_lacunarity; + y *= m_lacunarity; + + amp *= m_gain; + sum -= (1 - Math.abs(SingleCubic(++seed, x, y))) * amp; + } + + return sum; + } + + public float GetCubic(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + return SingleCubic(0, x, y); + } + + private final static float CUBIC_2D_BOUNDING = 1 / (float) (1.5 * 1.5); + + private float SingleCubic(int seed, float x, float y) { + int x1 = FastFloor(x); + int y1 = FastFloor(y); + + int x0 = x1 - 1; + int y0 = y1 - 1; + int x2 = x1 + 1; + int y2 = y1 + 1; + int x3 = x1 + 2; + int y3 = y1 + 2; + + float xs = x - (float) x1; + float ys = y - (float) y1; + + return CubicLerp( + CubicLerp(ValCoord2D(seed, x0, y0), ValCoord2D(seed, x1, y0), ValCoord2D(seed, x2, y0), ValCoord2D(seed, x3, y0), + xs), + CubicLerp(ValCoord2D(seed, x0, y1), ValCoord2D(seed, x1, y1), ValCoord2D(seed, x2, y1), ValCoord2D(seed, x3, y1), + xs), + CubicLerp(ValCoord2D(seed, x0, y2), ValCoord2D(seed, x1, y2), ValCoord2D(seed, x2, y2), ValCoord2D(seed, x3, y2), + xs), + CubicLerp(ValCoord2D(seed, x0, y3), ValCoord2D(seed, x1, y3), ValCoord2D(seed, x2, y3), ValCoord2D(seed, x3, y3), + xs), + ys) * CUBIC_2D_BOUNDING; + } + + // Cellular Noise + public float GetCellular(float x, float y, float z) { + x *= m_frequency; + y *= m_frequency; + z *= m_frequency; + + switch (m_cellularReturnType) { + case CellValue: + case NoiseLookup: + case Distance: + return SingleCellular(x, y, z); + default: + return SingleCellular2Edge(x, y, z); + } + } + + private float SingleCellular(float x, float y, float z) { + int xr = FastRound(x); + int yr = FastRound(y); + int zr = FastRound(z); + + float distance = 999999; + int xc = 0, yc = 0, zc = 0; + + switch (m_cellularDistanceFunction) { + case Euclidean: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ; + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + zc = zi; + } + } + } + } + break; + case Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ); + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + zc = zi; + } + } + } + } + break; + case Natural: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ); + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + zc = zi; + } + } + } + } + break; + } + + switch (m_cellularReturnType) { + case CellValue: + return ValCoord3D(0, xc, yc, zc); + + case NoiseLookup: + Float3 vec = CELL_3D[Hash3D(m_seed, xc, yc, zc) & 255]; + return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y, zc + vec.z); + + case Distance: + return distance - 1; + default: + return 0; + } + } + + private float SingleCellular2Edge(float x, float y, float z) { + int xr = FastRound(x); + int yr = FastRound(y); + int zr = FastRound(z); + + float distance = 999999; + float distance2 = 999999; + + switch (m_cellularDistanceFunction) { + case Euclidean: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ; + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + } + break; + case Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ); + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + } + break; + case Natural: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + for (int zi = zr - 1; zi <= zr + 1; zi++) { + Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + float vecZ = zi - z + vec.z; + + float newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ); + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + } + break; + default: + break; + } + + switch (m_cellularReturnType) { + case Distance2: + return distance2 - 1; + case Distance2Add: + return distance2 + distance - 1; + case Distance2Sub: + return distance2 - distance - 1; + case Distance2Mul: + return distance2 * distance - 1; + case Distance2Div: + return distance / distance2 - 1; + default: + return 0; + } + } + + public float GetCellular(float x, float y) { + x *= m_frequency; + y *= m_frequency; + + switch (m_cellularReturnType) { + case CellValue: + case NoiseLookup: + case Distance: + return SingleCellular(x, y); + default: + return SingleCellular2Edge(x, y); + } + } + + private float SingleCellular(float x, float y) { + int xr = FastRound(x); + int yr = FastRound(y); + + float distance = 999999; + int xc = 0, yc = 0; + + switch (m_cellularDistanceFunction) { + default: + case Euclidean: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = vecX * vecX + vecY * vecY; + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + } + } + } + break; + case Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = (Math.abs(vecX) + Math.abs(vecY)); + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + } + } + } + break; + case Natural: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY); + + if (newDistance < distance) { + distance = newDistance; + xc = xi; + yc = yi; + } + } + } + break; + } + + switch (m_cellularReturnType) { + case CellValue: + return ValCoord2D(0, xc, yc); + + case NoiseLookup: + Float2 vec = CELL_2D[Hash2D(m_seed, xc, yc) & 255]; + return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y); + + case Distance: + return distance - 1; + default: + return 0; + } + } + + private float SingleCellular2Edge(float x, float y) { + int xr = FastRound(x); + int yr = FastRound(y); + + float distance = 999999; + float distance2 = 999999; + + switch (m_cellularDistanceFunction) { + default: + case Euclidean: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = vecX * vecX + vecY * vecY; + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + break; + case Manhattan: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = Math.abs(vecX) + Math.abs(vecY); + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + break; + case Natural: + for (int xi = xr - 1; xi <= xr + 1; xi++) { + for (int yi = yr - 1; yi <= yr + 1; yi++) { + Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; + + float vecX = xi - x + vec.x; + float vecY = yi - y + vec.y; + + float newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY); + + distance2 = Math.max(Math.min(distance2, newDistance), distance); + distance = Math.min(distance, newDistance); + } + } + break; + } + + switch (m_cellularReturnType) { + case Distance2: + return distance2 - 1; + case Distance2Add: + return distance2 + distance - 1; + case Distance2Sub: + return distance2 - distance - 1; + case Distance2Mul: + return distance2 * distance - 1; + case Distance2Div: + return distance / distance2 - 1; + default: + return 0; + } + } + + public void GradientPerturb(Vector3f v3) { + SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v3); + } + + public void GradientPerturbFractal(Vector3f v3) { + int seed = m_seed; + float amp = m_gradientPerturbAmp * m_fractalBounding; + float freq = m_frequency; + + SingleGradientPerturb(seed, amp, m_frequency, v3); + + for (int i = 1; i < m_octaves; i++) { + freq *= m_lacunarity; + amp *= m_gain; + SingleGradientPerturb(++seed, amp, freq, v3); + } + } + + private void SingleGradientPerturb(int seed, float perturbAmp, float frequency, Vector3f v3) { + float xf = v3.x * frequency; + float yf = v3.y * frequency; + float zf = v3.z * frequency; + + int x0 = FastFloor(xf); + int y0 = FastFloor(yf); + int z0 = FastFloor(zf); + int x1 = x0 + 1; + int y1 = y0 + 1; + int z1 = z0 + 1; + + float xs, ys, zs; + switch (m_interp) { + default: + case Linear: + xs = xf - x0; + ys = yf - y0; + zs = zf - z0; + break; + case Hermite: + xs = InterpHermiteFunc(xf - x0); + ys = InterpHermiteFunc(yf - y0); + zs = InterpHermiteFunc(zf - z0); + break; + case Quintic: + xs = InterpQuinticFunc(xf - x0); + ys = InterpQuinticFunc(yf - y0); + zs = InterpQuinticFunc(zf - z0); + break; + } + + Float3 vec0 = CELL_3D[Hash3D(seed, x0, y0, z0) & 255]; + Float3 vec1 = CELL_3D[Hash3D(seed, x1, y0, z0) & 255]; + + float lx0x = Lerp(vec0.x, vec1.x, xs); + float ly0x = Lerp(vec0.y, vec1.y, xs); + float lz0x = Lerp(vec0.z, vec1.z, xs); + + vec0 = CELL_3D[Hash3D(seed, x0, y1, z0) & 255]; + vec1 = CELL_3D[Hash3D(seed, x1, y1, z0) & 255]; + + float lx1x = Lerp(vec0.x, vec1.x, xs); + float ly1x = Lerp(vec0.y, vec1.y, xs); + float lz1x = Lerp(vec0.z, vec1.z, xs); + + float lx0y = Lerp(lx0x, lx1x, ys); + float ly0y = Lerp(ly0x, ly1x, ys); + float lz0y = Lerp(lz0x, lz1x, ys); + + vec0 = CELL_3D[Hash3D(seed, x0, y0, z1) & 255]; + vec1 = CELL_3D[Hash3D(seed, x1, y0, z1) & 255]; + + lx0x = Lerp(vec0.x, vec1.x, xs); + ly0x = Lerp(vec0.y, vec1.y, xs); + lz0x = Lerp(vec0.z, vec1.z, xs); + + vec0 = CELL_3D[Hash3D(seed, x0, y1, z1) & 255]; + vec1 = CELL_3D[Hash3D(seed, x1, y1, z1) & 255]; + + lx1x = Lerp(vec0.x, vec1.x, xs); + ly1x = Lerp(vec0.y, vec1.y, xs); + lz1x = Lerp(vec0.z, vec1.z, xs); + + v3.x += Lerp(lx0y, Lerp(lx0x, lx1x, ys), zs) * perturbAmp; + v3.y += Lerp(ly0y, Lerp(ly0x, ly1x, ys), zs) * perturbAmp; + v3.z += Lerp(lz0y, Lerp(lz0x, lz1x, ys), zs) * perturbAmp; + } + + public void GradientPerturb(Vector2f v2) { + SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v2); + } + + public void GradientPerturbFractal(Vector2f v2) { + int seed = m_seed; + float amp = m_gradientPerturbAmp * m_fractalBounding; + float freq = m_frequency; + + SingleGradientPerturb(seed, amp, m_frequency, v2); + + for (int i = 1; i < m_octaves; i++) { + freq *= m_lacunarity; + amp *= m_gain; + SingleGradientPerturb(++seed, amp, freq, v2); + } + } + + private void SingleGradientPerturb(int seed, float perturbAmp, float frequency, Vector2f v2) { + float xf = v2.x * frequency; + float yf = v2.y * frequency; + + int x0 = FastFloor(xf); + int y0 = FastFloor(yf); + int x1 = x0 + 1; + int y1 = y0 + 1; + + float xs, ys; + switch (m_interp) { + default: + case Linear: + xs = xf - x0; + ys = yf - y0; + break; + case Hermite: + xs = InterpHermiteFunc(xf - x0); + ys = InterpHermiteFunc(yf - y0); + break; + case Quintic: + xs = InterpQuinticFunc(xf - x0); + ys = InterpQuinticFunc(yf - y0); + break; + } + + Float2 vec0 = CELL_2D[Hash2D(seed, x0, y0) & 255]; + Float2 vec1 = CELL_2D[Hash2D(seed, x1, y0) & 255]; + + float lx0x = Lerp(vec0.x, vec1.x, xs); + float ly0x = Lerp(vec0.y, vec1.y, xs); + + vec0 = CELL_2D[Hash2D(seed, x0, y1) & 255]; + vec1 = CELL_2D[Hash2D(seed, x1, y1) & 255]; + + float lx1x = Lerp(vec0.x, vec1.x, xs); + float ly1x = Lerp(vec0.y, vec1.y, xs); + + v2.x += Lerp(lx0x, lx1x, ys) * perturbAmp; + v2.y += Lerp(ly0x, ly1x, ys) * perturbAmp; + } + +} \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Command/CommandHandler.java b/src/main/java/net/tylermurphy/Minecraft/Command/CommandHandler.java new file mode 100755 index 0000000..c289604 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Command/CommandHandler.java @@ -0,0 +1,37 @@ +package net.tylermurphy.Minecraft.Command; + +import net.tylermurphy.Minecraft.Command.Commands.Teleport; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + + +public class CommandHandler { + + public final static Map REGISTER = new HashMap<>(); + + public static void registerCommands() { + register(new Teleport()); + } + + private static void register(ICommand command) { + if (!REGISTER.containsKey(command.getInvoke())) { + REGISTER.put(command.getInvoke().toLowerCase(), command); + } + } + + public static void handleCommand(String text) { + final String[] split = text.replaceFirst( + "(?i)" + Pattern.quote("/"), "").split("\\s+"); + final String invoke = split[0].toLowerCase(); + if(REGISTER.containsKey(invoke)) { + ICommand command = REGISTER.get(invoke); + final List args = Arrays.asList(split).subList(1, split.length); + command.invoke(args); + } + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Command/Commands/Teleport.java b/src/main/java/net/tylermurphy/Minecraft/Command/Commands/Teleport.java new file mode 100755 index 0000000..a48955c --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Command/Commands/Teleport.java @@ -0,0 +1,30 @@ +package net.tylermurphy.Minecraft.Command.Commands; + +import java.util.List; + +import org.joml.Vector3f; + +import net.tylermurphy.Minecraft.Command.ICommand; +import net.tylermurphy.Minecraft.Scene.World; + +public class Teleport implements ICommand { + + public void invoke(List args) { + if(args.size() < 3) return; + float x,y,z; + try { + x = Float.parseFloat(args.get(0)); + y = Float.parseFloat(args.get(1)); + z = Float.parseFloat(args.get(2)); + } catch (Exception e) { + return; + } + + World.player.getTransform().setGlobalPosition(new Vector3f(x,y,z)); + } + + public String getInvoke() { + return "tp"; + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Command/ICommand.java b/src/main/java/net/tylermurphy/Minecraft/Command/ICommand.java new file mode 100755 index 0000000..c3b85d3 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Command/ICommand.java @@ -0,0 +1,11 @@ +package net.tylermurphy.Minecraft.Command; + +import java.util.List; + +public interface ICommand { + + public void invoke(List args); + + public String getInvoke(); + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Gen/WorldGenerator.java b/src/main/java/net/tylermurphy/Minecraft/Gen/WorldGenerator.java new file mode 100755 index 0000000..b912ccd --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Gen/WorldGenerator.java @@ -0,0 +1,112 @@ +package net.tylermurphy.Minecraft.Gen; + +import net.tylermurphy.Minecraft.Chunk.Chunk; +import net.tylermurphy.Minecraft.Chunk.PerlinNoise; +import net.tylermurphy.Minecraft.Scene.World; + +public class WorldGenerator { + + private static int OCTAVES = 2; + private static int AMPLITUDE = 10; + private static int ROUGHNESS = 3; + + public static int generateHeight(int x, int z) { + float total = 0; + float d = (float) Math.pow(2, OCTAVES-1); + for(int i=0;i2 && top > 90) { + c.cubes[x][top+1][z] = 15; + c.cubes[x][top+2][z] = 15; + c.cubes[x][top+3][z] = 15; + } + } else { + if(n1*n2/n4*n3>2 && top > 90) { + if(x < 1 || x > 14 || z < 1 || z > 14) continue; + c.cubes[x][top+1][z] = 10; + c.cubes[x][top+2][z] = 10; + c.cubes[x][top+3][z] = 10; + + c.cubes[x-1][top+3][z] = 12; + c.cubes[x-1][top+3][z+1] = 12; + c.cubes[x][top+3][z+1] = 12; + c.cubes[x+1][top+3][z+1] = 12; + c.cubes[x+1][top+3][z] = 12; + c.cubes[x+1][top+3][z-1] = 12; + c.cubes[x][top+3][z-1] = 12; + c.cubes[x-1][top+3][z-1] = 12; + + c.cubes[x+1][top+4][z] = 12; + c.cubes[x-1][top+4][z] = 12; + c.cubes[x][top+4][z+1] = 12; + c.cubes[x][top+4][z-1] = 12; + c.cubes[x][top+4][z] = 12; + } + } + } + } + } + + public static void generate(Chunk c) { + generateLandscape(c); + generateNature(c); + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Input/CommandInput.java b/src/main/java/net/tylermurphy/Minecraft/Input/CommandInput.java new file mode 100755 index 0000000..85540ab --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Input/CommandInput.java @@ -0,0 +1,57 @@ +package net.tylermurphy.Minecraft.Input; + +import org.lwjgl.glfw.GLFW; + +import net.tylermurphy.Minecraft.Command.CommandHandler; +import net.tylermurphy.Minecraft.Scene.World; + +import static net.tylermurphy.Minecraft.UI.UIMaster.*; + +public class CommandInput extends IInput { + + public void keyPressed(int keyCode) { + switch(keyCode) { + case GLFW.GLFW_KEY_ESCAPE: + Input.setEnabled("CommandInput", false); + Input.setEnabled("GameInput", true); + bindUI(3); + setEnabled(false); + getText("commandBar").setText(""); + World.player.isPaused = false; + break; + case GLFW.GLFW_KEY_BACKSPACE: + bindUI(3); + String currentText = getText("commandBar").getTextString(); + if(currentText.length() > 0) + getText("commandBar").setText(currentText.substring(0,currentText.length()-1)); + break; + case GLFW.GLFW_KEY_ENTER: + bindUI(3); + setEnabled(false); + + String command = getText("commandBar").getTextString(); + CommandHandler.handleCommand(command); + + Input.setEnabled("CommandInput", false); + Input.setEnabled("GameInput", true); + getText("commandBar").setText(""); + World.player.isPaused = false; + break; + } + } + + public void keyRelesed(int keyCode) {} + + public void mousePressed(int mouseButton) {} + + public void mouseRelesed(int mouseButton) {} + + public void charAction(char c) { + bindUI(3); + String currentText = getText("commandBar").getTextString(); + + currentText += c; + getText("commandBar").setText(currentText); + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Input/CoreInput.java b/src/main/java/net/tylermurphy/Minecraft/Input/CoreInput.java new file mode 100755 index 0000000..2732805 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Input/CoreInput.java @@ -0,0 +1,25 @@ +package net.tylermurphy.Minecraft.Input; + +import org.lwjgl.glfw.GLFW; + +import net.tylermurphy.Minecraft.Render.Data.Display; + +public class CoreInput extends IInput { + + public void keyPressed(int keyCode) { + switch(keyCode) { + case GLFW.GLFW_KEY_F11: + Display.setFullScreen(!Display.fullscreen); + break; + } + } + + public void keyRelesed(int keyCode) {} + + public void mousePressed(int mouseButton) {} + + public void mouseRelesed(int mouseButton) {} + + public void charAction(char c) {} + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Input/GameInput.java b/src/main/java/net/tylermurphy/Minecraft/Input/GameInput.java new file mode 100755 index 0000000..5da40a6 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Input/GameInput.java @@ -0,0 +1,85 @@ +package net.tylermurphy.Minecraft.Input; + +import static net.tylermurphy.Minecraft.UI.UIMaster.*; + +import net.tylermurphy.Minecraft.Scene.Objects.WorldOrigin; +import org.lwjgl.glfw.GLFW; +import org.joml.Vector3f; + +import net.tylermurphy.Minecraft.Chunk.Cube; +import net.tylermurphy.Minecraft.Scene.World; +import net.tylermurphy.Minecraft.Util.Flags; +import net.tylermurphy.Minecraft.Util.MousePicker; + +public class GameInput extends IInput { + + byte blockId = 1; + + public void keyPressed(int keyCode) { + switch(keyCode) { + case GLFW.GLFW_KEY_ESCAPE: + Flags.actionForceClose = true; break; + case GLFW.GLFW_KEY_F3: + bindUI(1); + setEnabled(!isEnabled()); + break; + case GLFW.GLFW_KEY_EQUAL: + do { + blockId++; + if (blockId > (byte) (Cube.blocks.size() - 1)) blockId = 0; + } while (!Cube.getBlock(blockId).placeable); + bindUI(1); + getText("block").setText("Block Selected: minecraft:"+Cube.getBlock(blockId).name); + break; + case GLFW.GLFW_KEY_MINUS: + do { + blockId--; + if (blockId < 0) blockId = (byte) (Cube.blocks.size() - 1); + } while (!Cube.getBlock(blockId).placeable); + bindUI(1); + getText("block").setText("Block Selected: minecraft:"+Cube.getBlock(blockId).name); + break; + case GLFW.GLFW_KEY_F2: + World.player.isFlying = !World.player.isFlying; + break; + case GLFW.GLFW_KEY_K: + if(World.player.isDead) { + World.player.isDead = false; + World.player.health = 20; + World.world_origin = new WorldOrigin(0,0); + World.player.getTransform().setPosition(new Vector3f(0, World.getHighestBlock(0, 0)+1,0)); + bindUI(0); + getText("dead").setEnabled(false); + getImage("crosshair").setEnabled(true); + } + break; + case GLFW.GLFW_KEY_SLASH: + this.enabled = false; + Input.setEnabled("CommandInput", true); + bindUI(3); + setEnabled(true); + World.player.isPaused = true; + break; + } + } + + public void keyRelesed(int keyCode) {} + + public void mousePressed(int mouseButton) { + switch(mouseButton) { + case GLFW.GLFW_MOUSE_BUTTON_1: + if(MousePicker.breakPos!=null) + World.setBlock((int)MousePicker.breakPos.x,(int)MousePicker.breakPos.y,(int)MousePicker.breakPos.z, Cube.AIR); + break; + case GLFW.GLFW_MOUSE_BUTTON_2: + if(MousePicker.placePos!=null && !World.player.collides(MousePicker.placePos.x,MousePicker.placePos.y,MousePicker.placePos.z)) + World.setBlock((int)MousePicker.placePos.x,(int)MousePicker.placePos.y,(int)MousePicker.placePos.z, blockId); + break; + } + } + + public void mouseRelesed(int mouseButton) {} + + public void charAction(char c) {} + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Input/IInput.java b/src/main/java/net/tylermurphy/Minecraft/Input/IInput.java new file mode 100755 index 0000000..0eb48e7 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Input/IInput.java @@ -0,0 +1,12 @@ +package net.tylermurphy.Minecraft.Input; + +public abstract class IInput { + + public boolean enabled = true; + + public abstract void keyPressed(int keyCode); + public abstract void keyRelesed(int keyCode); + public abstract void mousePressed(int mouseButton); + public abstract void mouseRelesed(int mouseButton); + public abstract void charAction(char c); +} \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Input/Input.java b/src/main/java/net/tylermurphy/Minecraft/Input/Input.java new file mode 100755 index 0000000..86deb12 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Input/Input.java @@ -0,0 +1,154 @@ +package net.tylermurphy.Minecraft.Input; + +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWCursorPosCallback; +import org.lwjgl.glfw.GLFWKeyCallback; +import org.lwjgl.glfw.GLFWMouseButtonCallback; + +import org.lwjgl.glfw.GLFWCharCallback; + +public class Input { + + private static List inputs = new ArrayList(); + + private static boolean[] keys = new boolean[GLFW.GLFW_KEY_LAST]; + private static boolean[] mouseButtons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST]; + private static double mouseX, mouseY; + private static double mouseX_last, mouseY_last; + + private static GLFWKeyCallback keyboard; + private static GLFWCursorPosCallback mouseMove; + private static GLFWMouseButtonCallback mouseButton; + private static GLFWCharCallback character; + + public static void init() { + + keyboard = new GLFWKeyCallback() { + public void invoke(long window, int key, int scancode, int action, int mods) { + switch(action) { + case GLFW.GLFW_PRESS: + keys[key] = true; + for(IInput input : inputs) { + if(!input.enabled) continue; + input.keyPressed(key); + } + break; + case GLFW.GLFW_RELEASE: + keys[key] = false; + for(IInput input : inputs) { + if(!input.enabled) continue; + input.keyRelesed(key); + } + break; + } + + } + }; + + mouseMove = new GLFWCursorPosCallback() { + public void invoke(long window, double xPos, double yPos) { + mouseX = xPos; mouseY = yPos; + } + }; + + mouseButton = new GLFWMouseButtonCallback() { + public void invoke(long window, int button, int action, int mods) { + switch(action) { + case GLFW.GLFW_PRESS: + mouseButtons[button] = true; + for(IInput input : inputs) { + if(!input.enabled) continue; + input.mousePressed(button); + } + break; + case GLFW.GLFW_RELEASE: + mouseButtons[button] = false; + for(IInput input : inputs) { + if(!input.enabled) continue; + input.mouseRelesed(button); + } + break; + } + } + }; + + character = new GLFWCharCallback() { + public void invoke(long window, int key) { + for(IInput input : inputs) { + if(!input.enabled) continue; + input.charAction((char)key); + } + } + }; + } + + public static void addInput(IInput input) { + inputs.add(input); + } + + public static void destroy() { + keyboard.free(); + mouseMove.free(); + mouseButton.free(); + character.free(); + } + + public static boolean isKeyDown(int key) { + return keys[key]; + } + + public static boolean isButtonDown(int button) { + return mouseButtons[button]; + } + + public static double getMouseX() { + return mouseX; + } + + public static double getMouseY() { + return mouseY; + } + + public static double getMouseDX() { + double d = -(mouseX_last - mouseX); + mouseX_last = mouseX; + return d; + } + + public static double getMouseDY() { + double d = mouseY_last - mouseY; + mouseY_last = mouseY; + return d; + } + + public static GLFWKeyCallback getKeyboardCallback() { + return keyboard; + } + + public static GLFWCursorPosCallback getMouseMoveCallback() { + return mouseMove; + } + + public static GLFWMouseButtonCallback getMouseButtonCallback() { + return mouseButton; + } + + public static GLFWCharCallback getCharCallback() { + return character; + } + + public static void setEnabled(String className, boolean enabled) { + for(IInput input : inputs) { + String fullName = input.getClass().getTypeName(); + fullName = fullName.substring(fullName.lastIndexOf(".")+1,fullName.length()); + if(className.equals(fullName)) { + input.enabled = enabled; + } + } + } + + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Main.java b/src/main/java/net/tylermurphy/Minecraft/Main.java new file mode 100755 index 0000000..ea10bd9 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Main.java @@ -0,0 +1,95 @@ +package net.tylermurphy.Minecraft; + +import java.util.ArrayList; +import java.util.List; + +import net.tylermurphy.Minecraft.Audio.SoundManager; +import net.tylermurphy.Minecraft.Chunk.Cube; +import net.tylermurphy.Minecraft.Command.CommandHandler; +import net.tylermurphy.Minecraft.Input.*; +import net.tylermurphy.Minecraft.Render.MainRenderer; +import net.tylermurphy.Minecraft.Render.Data.Texture; +import net.tylermurphy.Minecraft.Scripts.*; +import net.tylermurphy.Minecraft.Render.Data.Display; +import net.tylermurphy.Minecraft.Util.Flags; + +public class Main { + + private static long currentTime = System.nanoTime(); + private static long nanoSeconendsPassed; + private static int tps,ticks; + + public static String currentWorld = "test"; + + private static final List