From 180aad05decc7eefa87e4e45d6747c48f40e5361 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Mon, 17 Apr 2023 12:12:01 -0400 Subject: save --- .../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 +++++++++++++++++++++ 7 files changed, 425 insertions(+) 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/java/net/tylermurphy/Minecraft/Util') diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/ChunkLoader.java b/src/main/java/net/tylermurphy/Minecraft/Util/ChunkLoader.java new file mode 100755 index 0000000..2e81fc9 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/ChunkLoader.java @@ -0,0 +1,112 @@ +package net.tylermurphy.Minecraft.Util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import net.tylermurphy.Minecraft.Chunk.Chunk; +import net.tylermurphy.Minecraft.Scene.World; +import org.joml.Vector2i; + +public class ChunkLoader { + + private static final ArrayList keys_to_be_removed = new ArrayList<>(); + + private static final HashMap loaded_regions = new HashMap<>(); + + public static void run() { + try { + int cx,cz; + cx = (int) ((World.player.getTransform().getGlobalPosition().x)/16); + cz = (int) ((World.player.getTransform().getGlobalPosition().z)/16); + keys_to_be_removed.clear(); + for(Chunk c : World.getChunks()) { + if(c.gridX < cx-World.renderDistance || c.gridX > cx+World.renderDistance || c.gridZ < cz-World.renderDistance || c.gridZ > cz+World.renderDistance) { + + int x = c.gridX; int z = c.gridZ; + int regionX = x > 0 ? x / 16 : (x - 16) / 16; + int regionZ = z > 0 ? z / 16 : (z - 16) / 16; + Data region = loaded_regions.get(getRegionKey(regionX,regionZ)); + byte[] data = ResourceManager.flattenArray(c.cubes); + region.BYTE_ARRAYS.put(getChunkKey(x,z), data); + loaded_regions.put(getRegionKey(regionX,regionZ), region); + + if(c.renderable() != null) + c.renderable().getMesh().delete(); + c.deleteRenderable(); + if(c.transparentRenderable() != null) + c.transparentRenderable().getMesh().delete(); + c.deleteTransparentRenderable(); + c.cubes = null; + keys_to_be_removed.add(new Vector2i(c.gridX, c.gridZ)); + } + } + for(Vector2i pos : keys_to_be_removed) { + World.removeChunk(pos.x, pos.y); + } + for(int x=cx-World.renderDistance; x 0 ? x / 16 : (x - 16) / 16; + int regionZ = z > 0 ? z / 16 : (z - 16) / 16; + Data region = loaded_regions.get(getRegionKey(regionX,regionZ)); + byte[] data = ResourceManager.flattenArray(c.cubes); + region.BYTE_ARRAYS.put(getChunkKey(x,z), data); + loaded_regions.put(getRegionKey(regionX,regionZ), region); + } + for(Map.Entry entry : loaded_regions.entrySet()) { + ResourceManager.saveObject("region/", entry.getKey(), entry.getValue()); + } + } + + private static void update(int x, int z) { + Chunk c = World.getChunkUnsafe(x, z); + if(c != null) c.updateMesh(); + } + + private static Chunk loadChunk(int gridX, int gridZ) { + int regionX = gridX > 0 ? gridX / 16 : (gridX - 16) / 16; + int regionZ = gridZ > 0 ? gridZ / 16 : (gridZ - 16) / 16; + Data region; + if(!loaded_regions.containsKey(getRegionKey(regionX,regionZ))) { + Object reg = ResourceManager.loadObject("region/", getRegionKey(regionX,regionZ)); + if(reg == null) region = new Data(); + else region = (Data)reg; + loaded_regions.put(getRegionKey(regionX,regionZ), region); + } else region = loaded_regions.get(getRegionKey(regionX,regionZ)); + if(region.BYTE_ARRAYS.containsKey(getChunkKey(gridX,gridZ))) { + byte[] data = region.BYTE_ARRAYS.get(getChunkKey(gridX,gridZ)); + Chunk chunk = new Chunk(gridX,gridZ,true); + chunk.cubes = ResourceManager.expandArray(data); + return chunk; + } else { + return new Chunk(gridX,gridZ,true); + } + } + + public static String getRegionKey(int regionX, int regionZ) { + return regionX+"x"+regionZ+"z.region"; + } + + public static String getChunkKey(int gridX, int gridZ) { + return gridX+"x"+gridZ+"z"; + } +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/Constants.java b/src/main/java/net/tylermurphy/Minecraft/Util/Constants.java new file mode 100755 index 0000000..d657e83 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/Constants.java @@ -0,0 +1,21 @@ +package net.tylermurphy.Minecraft.Util; + +public class Constants { + + public static final String SHADER_LOCATION = "assets/shaders/"; + public static final String PNG_LOCATION = "assets/textures/"; + public static final String FNT_LOCATION = "assets/font/"; + public static final String OGG_LOCATION = "assets/sounds/"; + public static final String SAVES_LOCATION = "saves"; + + public static final float NEAR_DISTANCE = 0.1f; + public static final float FAR_DISTANCE = 1000; + public static final float FOV = 70; + + public static final float RED = 0.78125f; + public static final float GREEN = 0.8984375f; + public static final float BLUE = 0.8984375f; + + public static final int RENDER_DISTANCE = 24; + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/Data.java b/src/main/java/net/tylermurphy/Minecraft/Util/Data.java new file mode 100755 index 0000000..7c4213d --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/Data.java @@ -0,0 +1,16 @@ +package net.tylermurphy.Minecraft.Util; + +import java.io.Serializable; +import java.util.HashMap; + +public class Data implements Serializable { + + private static final long serialVersionUID = 6866388687418069074L; + + public final HashMap BYTE_ARRAYS = new HashMap<>(); + + public final HashMap FLOATS = new HashMap<>(); + public final HashMap INTS = new HashMap<>(); + public final HashMap BOOLEANS = new HashMap<>(); + +} \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/Flags.java b/src/main/java/net/tylermurphy/Minecraft/Util/Flags.java new file mode 100755 index 0000000..8282ad9 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/Flags.java @@ -0,0 +1,7 @@ +package net.tylermurphy.Minecraft.Util; + +public class Flags { + + public static boolean actionForceClose = false; + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/Maths.java b/src/main/java/net/tylermurphy/Minecraft/Util/Maths.java new file mode 100755 index 0000000..89343e1 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/Maths.java @@ -0,0 +1,66 @@ +package net.tylermurphy.Minecraft.Util; + +import org.joml.Vector2f; +import org.joml.Vector3f; +import org.joml.Matrix4f; + +import net.tylermurphy.Minecraft.Scene.Camera; + +public class Maths { + + public static Matrix4f createTransformationMatrix(Vector2f translation, Vector2f scale) { + Matrix4f matrix = new Matrix4f(); + matrix.identity(); + matrix.translate(translation.x, translation.y, 0); + matrix.scale(new Vector3f(scale.x, scale.y, 1f)); + return matrix; + } + + public static Matrix4f createTransformationMatrix(Vector3f translation, float rx, float ry, float rz, float scale) { + Matrix4f matrix = new Matrix4f(); + matrix.identity(); + matrix.translate(translation); + matrix.rotate((float) Math.toRadians(rx), new Vector3f(1,0,0)); + matrix.rotate((float) Math.toRadians(ry), new Vector3f(0,1,0)); + matrix.rotate((float) Math.toRadians(rz), new Vector3f(0,0,1)); + matrix.scale(scale); + return matrix; + } + + public static Matrix4f createViewMatrix(Camera camera) { + Matrix4f viewMatrix = new Matrix4f(); + viewMatrix.identity(); + viewMatrix.rotate((float) Math.toRadians(camera.getPitch()), new Vector3f(1, 0, 0)); + viewMatrix.rotate((float) Math.toRadians(camera.getYaw()), new Vector3f(0, 1, 0)); + Vector3f cameraPos = camera.getPosition(); + Vector3f negativeCameraPos = new Vector3f(-cameraPos.x,-cameraPos.y,-cameraPos.z); + viewMatrix.translate(negativeCameraPos); + return viewMatrix; + } + + public static float barryCentric(Vector3f p1, Vector3f p2, Vector3f p3, Vector2f pos) { + float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z); + float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det; + float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det; + float l3 = 1.0f - l1 - l2; + return l1 * p1.y + l2 * p2.y + l3 * p3.y; + } + + public static float getDistance(float x1, float z1, float x2, float z2) { + float x = (x2-x1) * (x2-x1); + float z = (z2-z1) * (z2-z1); + float answer = (float) Math.sqrt(x + z); + System.out.println(answer); + return answer; + } + + public static float getDistance(Vector3f vec1, Vector3f vec2) { + float x = (vec1.x-vec2.x) * (vec1.x-vec2.x); + float z = (vec1.z-vec2.z) * (vec1.z-vec2.z); + float answer = (float) Math.sqrt(x + z); + return answer; + } + + + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/MousePicker.java b/src/main/java/net/tylermurphy/Minecraft/Util/MousePicker.java new file mode 100755 index 0000000..d35a1d1 --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/MousePicker.java @@ -0,0 +1,73 @@ +package net.tylermurphy.Minecraft.Util; + +import net.tylermurphy.Minecraft.Render.Data.Display; +import org.joml.Matrix4f; +import org.joml.Vector2f; +import org.joml.Vector3f; +import org.joml.Vector4f; + +import net.tylermurphy.Minecraft.Chunk.Cube; +import net.tylermurphy.Minecraft.Scene.World; + +public class MousePicker { + + public static Vector3f breakPos = new Vector3f(); + public static Vector3f placePos = new Vector3f(); + + private static Matrix4f projectionMatrix; + private static Matrix4f viewMatrix; + + public static void init(Matrix4f projection) { + projectionMatrix = projection; + } + + public static void update() { + viewMatrix = Maths.createViewMatrix(World.camera); + Vector3f currentRay = calculateMouseRay(); + breakPos = search(currentRay, World.player.getTransform().getPosition(), 0); + if(breakPos == null) placePos = null; + } + + private static Vector3f calculateMouseRay() { + float mouseX = (float) Display.getWidth()/2; + float mouseY = (float) Display.getHeight()/2; + Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY); + Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f); + Vector4f eyeCoords = toEyeCoords(clipCoords); + return toWorldCoords(eyeCoords); + } + + private static Vector3f toWorldCoords(Vector4f eyeCoords) { + Matrix4f invertedView = viewMatrix; + Vector4f rayWorld = invertedView.invert().transform(eyeCoords);; + Vector3f mouseRay = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z); + mouseRay.normalize(); + return mouseRay; + } + + private static Vector4f toEyeCoords(Vector4f clipCoords) { + Matrix4f invertedProjection = projectionMatrix; + Vector4f eyeCoords = invertedProjection.invert().transform(clipCoords); + return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f); + } + + private static Vector2f getNormalisedDeviceCoordinates(float mouseX, float mouseY) { + float x = (2.0f * mouseX) / Display.getWidth() - 1f; + float y = (2.0f * mouseY) / Display.getHeight() - 1f; + return new Vector2f(x, y); + } + + private static Vector3f search(Vector3f ray, Vector3f position, int recursionCount) { + Vector3f ppos = World.player.getTransform().getPosition(); + if(Math.abs(position.x-ppos.x) > 4 || Math.abs(position.y-ppos.y) > 4 || Math.abs(position.z-ppos.z) > 4 ) return null; + if(recursionCount > 200) return null; + int intX = Math.round(position.x); + int intY = Math.round(position.y+1); + int intZ = Math.round(position.z); + if(World.getBlock(intX, intY, intZ) != Cube.AIR && World.getBlock(intX, intY, intZ) != 17) + return new Vector3f(intX,intY,intZ); + placePos = new Vector3f(intX,intY,intZ); + return search(ray,new Vector3f(position.x+ray.x/4,position.y+ray.y/4,position.z+ray.z/4), recursionCount++); + } + +} diff --git a/src/main/java/net/tylermurphy/Minecraft/Util/ResourceManager.java b/src/main/java/net/tylermurphy/Minecraft/Util/ResourceManager.java new file mode 100755 index 0000000..fc6f96f --- /dev/null +++ b/src/main/java/net/tylermurphy/Minecraft/Util/ResourceManager.java @@ -0,0 +1,130 @@ +package net.tylermurphy.Minecraft.Util; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +import net.tylermurphy.Minecraft.Main; + +public class ResourceManager { + + static String saveName; + + protected static void init(String saveName) { + ResourceManager.saveName = saveName; + } + + private static byte[] compress(byte[] data){ + ByteArrayOutputStream baos = null; + Deflater dfl = new Deflater(); + dfl.setLevel(Deflater.BEST_COMPRESSION); + dfl.setInput(data); + dfl.finish(); + baos = new ByteArrayOutputStream(); + byte[] tmp = new byte[4*1024]; + try { + while(!dfl.finished()) { + int size = dfl.deflate(tmp); + baos.write(tmp, 0, size); + } + } catch(Exception e) { + + } finally { + try { + if(baos != null) baos.close(); + } catch(Exception e) {} + } + return baos.toByteArray(); + } + + protected static byte[] decompress(byte[] data){ + ByteArrayOutputStream baos = null; + Inflater ifl = new Inflater(); + ifl.setInput(data); + baos = new ByteArrayOutputStream(); + byte[] tmp = new byte[4*1024]; + try { + while(!ifl.finished()) { + int size = ifl.inflate(tmp); + baos.write(tmp, 0, size); + } + } catch(Exception e) { + + } finally { + try { + if(baos != null) baos.close(); + } catch(Exception e) {} + } + return baos.toByteArray(); + } + + public static byte[][][] expandArray(byte[] data) { + byte[] result = decompress(data); + byte[][][] cubes = new byte[16][256][16]; + for (int x = 0 ; x != 16 ; x++) { + for (int y = 0 ; y != 256 ; y++) { + for (int z = 0 ; z != 16 ; z++) { + cubes[x][y][z] = result[256 * 16 * x + 16 * y + z]; + } + } + } + return cubes; + } + + public static byte[] flattenArray(byte[][][] cubes) { + byte[] data = new byte[16*256*16]; + for (int x = 0 ; x != 16 ; x++) { + for (int y = 0 ; y != 256 ; y++) { + for (int z = 0 ; z != 16 ; z++) { + data[256 * 16 * x + 16 * y + z] = cubes[x][y][z]; + } + } + } + byte[] result = compress(data); + return result; + } + + public static Object loadObject(String pass_path, String fileName) { + String path = Constants.SAVES_LOCATION+"/"+Main.currentWorld+"/"+pass_path+"/"; + ObjectInputStream is = null; + try { + is = new ObjectInputStream(new FileInputStream(new File(path+fileName))); + Object object = is.readObject(); + is.close(); + return object; + } catch(Exception e) { + } finally { + try { + if(is!=null) is.close(); + } catch(Exception e) { + } + } + return null; + } + + public static void saveObject(String pass_path, String fileName, Object o) { + String path = Constants.SAVES_LOCATION+"/"+Main.currentWorld+"/"+pass_path+"/"; + ObjectOutputStream os = null; + try { + File folder = new File(path); + folder.mkdirs(); + File file = new File(path+fileName); + if(!file.exists()) file.createNewFile(); + os = new ObjectOutputStream(new FileOutputStream(file)); + os.writeObject(o); + os.close(); + } catch(Exception e) { + + } finally { + try { + if(os!=null) os.close(); + } catch(Exception e) {} + } + } + +} -- cgit v1.2.3-freya