diff --git a/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java b/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java index d45ff10..0e096e6 100644 --- a/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java @@ -21,9 +21,8 @@ protected void getLeftText(CallbackInfoReturnable> info) { int q = WakesDebugInfo.quadsRendered; info.getReturnValue().add(String.format("[Wakes] Rendering %d quads for %d wake nodes", q, WakeHandler.getInstance().getTotal())); info.getReturnValue().add(String.format("[Wakes] Node logic: %.2fms/t", 10e-6 * WakesDebugInfo.nodeLogicTime)); - info.getReturnValue().add(String.format("[Wakes] Mesh gen: %.2fms/t", 10e-6 * WakesDebugInfo.meshGenerationTime)); + info.getReturnValue().add(String.format("[Wakes] Texturing: %.2fms/t", q * 10e-6 * WakesDebugInfo.texturingTime)); info.getReturnValue().add(String.format("[Wakes] Rendering: %.3fms/f", 10e-6 * WakesDebugInfo.wakeRenderingTime.stream().reduce(0L, Long::sum) / WakesDebugInfo.wakeRenderingTime.size())); - info.getReturnValue().add(String.format(" - Texturing: %.2fms/t", q * 10e-6 * WakesDebugInfo.texturingTime.stream().reduce(0L, Long::sum) / WakesDebugInfo.texturingTime.size())); info.getReturnValue().add(String.format(" - Drawing: %.2fms/t", q * 10e-6 * WakesDebugInfo.drawingTime.stream().reduce(0L, Long::sum) / WakesDebugInfo.drawingTime.size())); } } diff --git a/src/main/java/com/goby56/wakes/render/WakeQuad.java b/src/main/java/com/goby56/wakes/render/WakeQuad.java deleted file mode 100644 index e7dee98..0000000 --- a/src/main/java/com/goby56/wakes/render/WakeQuad.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.goby56.wakes.render; - -import com.goby56.wakes.WakesClient; -import com.goby56.wakes.render.enums.WakeColor; -import com.goby56.wakes.simulation.WakeNode; -import net.minecraft.client.color.world.BiomeColors; -import net.minecraft.util.math.Box; -import net.minecraft.world.World; -import org.lwjgl.system.MemoryUtil; - -import java.util.Objects; - -public class WakeQuad { - public final int x; - public final float y; - public final int z; - public final int w; - public final int h; - public final WakeNode[][] nodes; - - public WakeQuad(int x, float y, int z, int w, int h, WakeNode[][] affectedNodes) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - this.h = h; - this.nodes = affectedNodes; - } - - public Box toBox() { - return new Box(x, y, z, x + w, y + 1, z + h); - } - - public void populatePixels(WakeTexture texture, World world) { - long x = Math.floorMod(this.x, 32); - long z = Math.floorMod(this.z, 32); - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - WakeNode node = nodes[i][j]; - long nodeOffset = 4L * (((z + i) * 32L * texture.res) + (x + j) * texture.res); - int waterCol = BiomeColors.getWaterColor(world, node.blockPos()); - float opacity = (float) ((-Math.pow(node.t, 2) + 1) * WakesClient.CONFIG_INSTANCE.wakeOpacity); - for (int r = 0; r < texture.res; r++) { - for (int c = 0; c < texture.res; c++) { - float avg = 0; - avg += (node.u[0][r + 1][c + 1] + node.u[1][r + 1][c + 1] + node.u[2][r + 1][c + 1]) / 3; - int color = WakeColor.getColor(avg, waterCol, opacity); - long pixelOffset = 4L * (((long) r * texture.res) + c); - MemoryUtil.memPutInt(texture.imgPtr + nodeOffset + pixelOffset, color); - } - } - } - } - } - - @Override - public int hashCode() { - return Objects.hash(x, z, w, h); - } -} diff --git a/src/main/java/com/goby56/wakes/render/WakeRenderer.java b/src/main/java/com/goby56/wakes/render/WakeRenderer.java index 0551c4d..33314e7 100644 --- a/src/main/java/com/goby56/wakes/render/WakeRenderer.java +++ b/src/main/java/com/goby56/wakes/render/WakeRenderer.java @@ -36,7 +36,7 @@ public void afterTranslucent(WorldRenderContext context) { if (wakeHandler == null || wakeHandler.resolutionResetScheduled) return; - ArrayList quads = wakeHandler.getVisible(context.frustum()); + ArrayList bricks = wakeHandler.getVisible(context.frustum(), Brick.class); Matrix4f matrix = context.matrixStack().peek().getPositionMatrix(); RenderSystem.enableBlend(); @@ -46,8 +46,8 @@ public void afterTranslucent(WorldRenderContext context) { if (resolution.res != WakeNode.res) return; int n = 0; long tRendering = System.nanoTime(); - for (var quad : quads) { - wakeTextures.get(resolution).render(matrix, context.camera(), quad, context.world()); + for (var brick : bricks) { + wakeTextures.get(resolution).render(matrix, context.camera(), brick); n++; } WakesDebugInfo.wakeRenderingTime.add(System.nanoTime() - tRendering); diff --git a/src/main/java/com/goby56/wakes/render/WakeTexture.java b/src/main/java/com/goby56/wakes/render/WakeTexture.java index 69ce33b..3640741 100644 --- a/src/main/java/com/goby56/wakes/render/WakeTexture.java +++ b/src/main/java/com/goby56/wakes/render/WakeTexture.java @@ -1,6 +1,8 @@ package com.goby56.wakes.render; import com.goby56.wakes.render.enums.RenderType; +import com.goby56.wakes.simulation.Brick; +import com.goby56.wakes.simulation.QuadTree; import com.goby56.wakes.simulation.WakeNode; import com.goby56.wakes.utils.WakesDebugInfo; import com.mojang.blaze3d.platform.GlConst; @@ -8,6 +10,8 @@ import com.mojang.blaze3d.platform.TextureUtil; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.render.*; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import org.joml.Matrix4f; @@ -16,15 +20,15 @@ import org.lwjgl.opengl.GL14; import org.lwjgl.system.MemoryUtil; +import java.nio.IntBuffer; + public class WakeTexture { public int res; public int glTexId; - public long imgPtr; public WakeTexture(int res) { this.res = res; this.glTexId = TextureUtil.generateTextureId(); - this.imgPtr = MemoryUtil.nmemAlloc((long) 32 * res * 32 * res * 4); GlStateManager._bindTexture(glTexId); GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); @@ -35,21 +39,18 @@ public WakeTexture(int res) { GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GL12.GL_TEXTURE_MIN_FILTER, GL12.GL_NEAREST); GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAG_FILTER, GL12.GL_NEAREST); - GlStateManager._texImage2D(GlConst.GL_TEXTURE_2D, 0, GlConst.GL_RGBA, 32 * res, 32 * res, 0, GlConst.GL_RGBA, GlConst.GL_UNSIGNED_BYTE, null); + GlStateManager._texImage2D(GlConst.GL_TEXTURE_2D, 0, GlConst.GL_RGBA, QuadTree.BRICK_WIDTH * res, QuadTree.BRICK_WIDTH * res, 0, GlConst.GL_RGBA, GlConst.GL_UNSIGNED_BYTE, null); } - public void render(Matrix4f matrix, Camera camera, WakeQuad quad, World world) { - long tTexture = System.nanoTime(); - quad.populatePixels(this, world); - WakesDebugInfo.texturingTime.add(System.nanoTime() - tTexture); - + public void render(Matrix4f matrix, Camera camera, Brick brick) { long tDrawing = System.nanoTime(); GlStateManager._bindTexture(glTexId); GlStateManager._pixelStore(GlConst.GL_UNPACK_ROW_LENGTH, 0); GlStateManager._pixelStore(GlConst.GL_UNPACK_SKIP_PIXELS, 0); GlStateManager._pixelStore(GlConst.GL_UNPACK_SKIP_ROWS, 0); GlStateManager._pixelStore(GlConst.GL_UNPACK_ALIGNMENT, 4); - GlStateManager._texSubImage2D(GlConst.GL_TEXTURE_2D, 0, 0, 0, 32 * res, 32 * res, GlConst.GL_RGBA, GlConst.GL_UNSIGNED_BYTE, imgPtr); + GlStateManager._texSubImage2D(GlConst.GL_TEXTURE_2D, 0,0,0,brick.dim * brick.texRes, brick.dim * brick.texRes, GlConst.GL_RGBA, GlConst.GL_UNSIGNED_BYTE, brick.imgPtr); + RenderSystem.setShaderTexture(0, glTexId); RenderSystem.setShader(RenderType.getProgram()); RenderSystem.enableDepthTest(); // Is it THIS simple? https://github.com/Goby56/wakes/issues/46 @@ -57,45 +58,33 @@ public void render(Matrix4f matrix, Camera camera, WakeQuad quad, World world) { BufferBuilder buffer = Tessellator.getInstance().getBuffer(); buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL); - WakeNode[][] nodes = quad.nodes; - int X = nodes.length - 1; - int Z = nodes[0].length - 1; - float u = quad.x / 32f; - float v = quad.z / 32f; - float uOffset = quad.w / 32f; - float vOffset = quad.h / 32f; - Vector3f pos = new Vec3d(quad.x, quad.y, quad.z).add(camera.getPos().negate()).toVector3f(); - + Vector3f pos = brick.pos.add(camera.getPos().negate()).toVector3f(); buffer.vertex(matrix, pos.x, pos.y, pos.z) .color(1f, 1f, 1f, 1f) - .texture(u, v) + .texture(0, 0) .overlay(OverlayTexture.DEFAULT_UV) - .light(light(nodes[0][0], world)) + .light(14680064) .normal(0f, 1f, 0f).next(); - buffer.vertex(matrix, pos.x, pos.y, pos.z + quad.h) + buffer.vertex(matrix, pos.x, pos.y, pos.z + brick.dim) .color(1f, 1f, 1f, 1f) - .texture(u, v + vOffset) + .texture(0, 1) .overlay(OverlayTexture.DEFAULT_UV) - .light(light(nodes[0][Z], world)) + .light(14680064) .normal(0f, 1f, 0f).next(); - buffer.vertex(matrix, pos.x + quad.w, pos.y, pos.z + quad.h) + buffer.vertex(matrix, pos.x + brick.dim, pos.y, pos.z + brick.dim) .color(1f, 1f, 1f, 1f) - .texture(u + uOffset, v + vOffset) + .texture(1, 1) .overlay(OverlayTexture.DEFAULT_UV) - .light(light(nodes[X][Z], world)) + .light(14680064) .normal(0f, 1f, 0f).next(); - buffer.vertex(matrix, pos.x + quad.w, pos.y, pos.z) + buffer.vertex(matrix, pos.x + brick.dim, pos.y, pos.z) .color(1f, 1f, 1f, 1f) - .texture(u + uOffset, v) + .texture(1, 0) .overlay(OverlayTexture.DEFAULT_UV) - .light(light(nodes[X][0], world)) + .light(14680064) .normal(0f, 1f, 0f).next(); Tessellator.getInstance().draw(); WakesDebugInfo.drawingTime.add(System.nanoTime() - tDrawing); } - - private static int light(WakeNode node, World world) { - return WorldRenderer.getLightmapCoordinates(world, node.blockPos()); - } } diff --git a/src/main/java/com/goby56/wakes/render/debug/WakeDebugRenderer.java b/src/main/java/com/goby56/wakes/render/debug/WakeDebugRenderer.java index 50a3f95..c262e67 100644 --- a/src/main/java/com/goby56/wakes/render/debug/WakeDebugRenderer.java +++ b/src/main/java/com/goby56/wakes/render/debug/WakeDebugRenderer.java @@ -2,6 +2,7 @@ import com.goby56.wakes.WakesClient; import com.goby56.wakes.simulation.WakeHandler; +import com.goby56.wakes.simulation.WakeNode; import com.goby56.wakes.utils.WakesDebugInfo; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; @@ -18,9 +19,9 @@ public class WakeDebugRenderer implements WorldRenderEvents.DebugRender { public void beforeDebugRender(WorldRenderContext context) { WakeHandler wakeHandler = WakeHandler.getInstance(); if (WakesClient.CONFIG_INSTANCE.drawDebugBoxes) { - for (var quad : wakeHandler.getVisible(context.frustum())) { - Box box = new Box(quad.x, quad.y - 0.1f, quad.z, quad.x + quad.w, quad.y - 0.2f, quad.z + quad.h); - var col = Color.getHSBColor(new Random(quad.hashCode()).nextFloat(), 1f, 1f).getRGBColorComponents(null); + for (var node : wakeHandler.getVisible(context.frustum(), WakeNode.class)) { + Box box = new Box(node.x, node.height - 0.1f, node.z, node.x + 1, node.height - 0.2f, node.z + 1); + var col = Color.getHSBColor(new Random(node.hashCode()).nextFloat(), 1f, 1f).getRGBColorComponents(null); DebugRenderer.drawBox(context.matrixStack(), context.consumers(), box.offset(context.camera().getPos().negate()), col[0], col[1], col[2], 0.5f); diff --git a/src/main/java/com/goby56/wakes/simulation/Brick.java b/src/main/java/com/goby56/wakes/simulation/Brick.java index 635af3f..7e8f3b9 100644 --- a/src/main/java/com/goby56/wakes/simulation/Brick.java +++ b/src/main/java/com/goby56/wakes/simulation/Brick.java @@ -1,46 +1,61 @@ package com.goby56.wakes.simulation; -import com.goby56.wakes.render.WakeQuad; +import com.goby56.wakes.WakesClient; +import com.goby56.wakes.render.WakeTexture; +import com.goby56.wakes.render.enums.WakeColor; import com.goby56.wakes.utils.WakesDebugInfo; -import net.minecraft.client.MinecraftClient; +import kroppeb.stareval.function.Type; import net.minecraft.client.render.Frustum; -import net.minecraft.text.Text; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; +import org.lwjgl.system.MemoryUtil; +import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Stream; public class Brick { - public int[] bitMask = new int[32]; private final WakeNode[][] nodes; public final int capacity; public final int dim; public int occupied = 0; - public final Vec3d pos; - public final ArrayList quads; public Brick NORTH; public Brick EAST; public Brick SOUTH; public Brick WEST; - public Brick(int x, float y, int z) { - this.dim = 32; + public long imgPtr = -1; + public int texRes; + + public Brick(int x, float y, int z, int width) { + this.dim = width; this.capacity = dim * dim; this.nodes = new WakeNode[dim][dim]; this.pos = new Vec3d(x, y, z); - this.quads = new ArrayList<>(); + initTexture(WakesClient.CONFIG_INSTANCE.wakeResolution.res); + } + + public void initTexture(int res) { + long size = 4L * dim * dim * res * res; + if (imgPtr == -1) { + this.imgPtr = MemoryUtil.nmemAlloc(size); + } else { + this.imgPtr = MemoryUtil.nmemRealloc(imgPtr, size); + } + this.texRes = res; } + public void deallocTexture() { + MemoryUtil.nmemFree(imgPtr); + } public boolean tick() { - quads.clear(); long tNode = System.nanoTime(); for (int z = 0; z < dim; z++) { for (int x = 0; x < dim; x++) { @@ -52,18 +67,20 @@ public boolean tick() { } } WakesDebugInfo.nodeLogicTime += (System.nanoTime() - tNode); - if (occupied != 0) { - long tMesh = System.nanoTime(); - generateMesh(); - WakesDebugInfo.meshGenerationTime += (System.nanoTime() - tMesh); - } + long tTexturing = System.nanoTime(); + populatePixels(); + WakesDebugInfo.texturingTime += (System.nanoTime() - tTexturing); return occupied != 0; } - public void query(Frustum frustum, ArrayList output) { - for (WakeQuad quad : quads) { - Box b = quad.toBox(); - if (frustum.isVisible(b)) output.add(quad); + public void query(Frustum frustum, ArrayList output) { + for (int z = 0; z < dim; z++) { + for (int x = 0; x < dim; x++) { + var node = this.get(x, z); + if (node == null) continue; + Box b = node.toBox(); + if (frustum.isVisible(b)) output.add(node); + } } } @@ -89,20 +106,18 @@ public WakeNode get(int x, int z) { public void insert(WakeNode node) { int x = Math.floorMod(node.x, dim), z = Math.floorMod(node.z, dim); + this.set(x, z, node); for (WakeNode neighbor : getAdjacentNodes(x, z)) { neighbor.updateAdjacency(node); } - this.set(x, z, node); } protected void set(int x, int z, WakeNode node) { boolean wasNull = nodes[z][x] == null; nodes[z][x] = node; if (node == null) { - bitMask[x] &= ~(1 << (dim - z - 1)); if (!wasNull) this.occupied--; } else { - bitMask[x] |= (1 << (dim - z - 1)); if (wasNull) this.occupied++; } } @@ -141,43 +156,29 @@ public void updateAdjacency(Brick brick) { } } - public void generateMesh() { - var ints = bitMask; - for (int i = 0; i < dim; i++) { - int j = 0; - while (j < dim) { - j += Integer.numberOfTrailingZeros(ints[i] >>> j); - if (j >= dim) continue; + public void populatePixels() { + for (int z = 0; z < dim; z++) { + for (int x = 0; x < dim; x++) { + WakeNode node = this.get(z, x); + + int waterCol = node != null ? node.waterColor : 0; + float opacity = node != null ? (float) ((-Math.pow(node.t, 2) + 1) * WakesClient.CONFIG_INSTANCE.wakeOpacity) : 0; - int h = Integer.numberOfTrailingZeros(~(ints[i] >>> j)); + long nodeOffset = 4L * (((long) z * dim * texRes) + (long) x * texRes); + for (int r = 0; r < texRes; r++) { + for (int c = 0; c < texRes; c++) { + float avg = 0; + if (node != null) { + avg += (node.u[0][r + 1][c + 1] + node.u[1][r + 1][c + 1] + node.u[2][r + 1][c + 1]) / 3; + } + int color = WakeColor.getColor(avg, waterCol, opacity); - int hm = (h == 32) ? ~0 : (1 << h) - 1; - int mask = hm << j; + long pixelOffset = 4L * (((long) r * texRes) + c); - int w = 1; - while (i + w < dim) { - int nextH = (ints[i + w] >>> j) & hm; - if (nextH != hm) { - break; + MemoryUtil.memPutInt(imgPtr + nodeOffset + pixelOffset, color); } - ints[i + w] &= ~mask; - w++; } - quads.add(new WakeQuad((int) (i + pos.x), (float) pos.y, (int) (dim - j - h + pos.z), w, h, getFromArea(i, dim - j - h, w, h))); - j += h; - } - } - } - - private WakeNode[][] getFromArea(int x, int z, int w, int h) { - WakeNode[][] nodes = new WakeNode[h][w]; - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - WakeNode node = this.get(x + j, z + i); - assert node != null; - nodes[i][j] = node; } } - return nodes; } } \ No newline at end of file diff --git a/src/main/java/com/goby56/wakes/simulation/QuadTree.java b/src/main/java/com/goby56/wakes/simulation/QuadTree.java index 19c066c..df4fb31 100644 --- a/src/main/java/com/goby56/wakes/simulation/QuadTree.java +++ b/src/main/java/com/goby56/wakes/simulation/QuadTree.java @@ -1,20 +1,19 @@ package com.goby56.wakes.simulation; -import com.goby56.wakes.render.WakeQuad; import net.minecraft.client.render.Frustum; import net.minecraft.util.math.Box; -import net.minecraft.world.World; +import java.nio.IntBuffer; import java.util.*; public class QuadTree { - private static final int MAX_DEPTH = 21; + public static final int BRICK_WIDTH = 4; + private static final int MAX_DEPTH = (int) (26 - Math.log(BRICK_WIDTH) / Math.log(2)); private static final int ROOT_X = (int) - Math.pow(2, 25); private static final int ROOT_Z = (int) - Math.pow(2, 25); private static final int ROOT_WIDTH = (int) Math.pow(2, 26); private final QuadTree ROOT; - private final QuadTree PARENT; private List children; private final DecentralizedBounds bounds; @@ -23,18 +22,23 @@ public class QuadTree { private final float yLevel; public QuadTree(float y) { - this(ROOT_X, y, ROOT_Z, ROOT_WIDTH, 0, null, null); + this(ROOT_X, y, ROOT_Z, ROOT_WIDTH, 0, null); } - private QuadTree(int x, float y, int z, int width, int depth, QuadTree root, QuadTree parent) { + private QuadTree(int x, float y, int z, int width, int depth, QuadTree root) { this.bounds = new DecentralizedBounds(x, y, z, width); this.depth = depth; this.ROOT = root == null ? this : root; - this.PARENT = parent; this.yLevel = y; + } + + private boolean hasLeaf() { + return depth == MAX_DEPTH && brick != null; + } + + private void initLeaf() { if (depth >= MAX_DEPTH) { - assert bounds.width() == 32; - this.brick = new Brick(x, y, z); + this.brick = new Brick(bounds.x, yLevel, bounds.z, bounds.width); this.ROOT.updateAdjacency(this); } } @@ -56,7 +60,7 @@ protected void updateAdjacency(QuadTree leaf) { } public boolean tick() { - if (brick != null) { + if (hasLeaf()) { return brick.tick(); } if (children == null) return false; @@ -74,7 +78,10 @@ public boolean insert(WakeNode node) { return false; } - if (this.brick != null) { + if (depth == MAX_DEPTH) { + if (brick == null) { + initLeaf(); + } brick.insert(node); return true; } @@ -86,34 +93,44 @@ public boolean insert(WakeNode node) { return false; } - public void query(Frustum frustum, ArrayList output) { + public void query(Frustum frustum, ArrayList output, Class type) { if (!frustum.isVisible(this.bounds.toBox((int) yLevel))) { return; } - if (brick != null) { - brick.query(frustum, output); + if (hasLeaf() && brick.occupied > 0) { + // TODO ADD VISIBLE NODES CHECK + if (type.equals(Brick.class)) { + output.add(type.cast(brick)); + } + if (type.equals(WakeNode.class)) { + ArrayList nodes = new ArrayList<>(); + brick.query(frustum, nodes); + for (var node : nodes) { + output.add(type.cast(node)); + } + } return; } if (children == null) return; for (var tree : children) { - tree.query(frustum, output); + tree.query(frustum, output, type); } } private void subdivide() { - if (brick != null) return; + if (depth == MAX_DEPTH) return; int x = this.bounds.x; int z = this.bounds.z; int w = this.bounds.width >> 1; children = new ArrayList<>(); - children.add(0, new QuadTree(x, yLevel, z, w, depth + 1, this.ROOT, this)); // NW - children.add(1, new QuadTree(x + w, yLevel, z, w, depth + 1, this.ROOT, this)); // NE - children.add(2, new QuadTree(x, yLevel, z + w, w, depth + 1, this.ROOT, this)); // SW - children.add(3, new QuadTree(x + w, yLevel, z + w, w, depth + 1, this.ROOT, this)); // SE + children.add(0, new QuadTree(x, yLevel, z, w, depth + 1, this.ROOT)); // NW + children.add(1, new QuadTree(x + w, yLevel, z, w, depth + 1, this.ROOT)); // NE + children.add(2, new QuadTree(x, yLevel, z + w, w, depth + 1, this.ROOT)); // SW + children.add(3, new QuadTree(x + w, yLevel, z + w, w, depth + 1, this.ROOT)); // SE } public int count() { - if (brick != null) { + if (hasLeaf()) { return brick.occupied; } if (children == null) return 0; @@ -124,6 +141,7 @@ public void prune() { if (children != null) { for (var tree : children) { tree.prune(); + if (tree.hasLeaf()) tree.brick.deallocTexture(); } children.set(0, null); children.set(1, null); diff --git a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java index c385d5c..3c37de1 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java @@ -2,7 +2,6 @@ import com.goby56.wakes.WakesClient; import com.goby56.wakes.config.enums.Resolution; -import com.goby56.wakes.render.WakeQuad; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Frustum; import net.minecraft.client.world.ClientWorld; @@ -78,11 +77,11 @@ public void insert(WakeNode node) { this.toBeInserted.get(i).add(node); } - public ArrayList getVisible(Frustum frustum) { - ArrayList visibleQuads = new ArrayList<>(); + public ArrayList getVisible(Frustum frustum, Class type) { + ArrayList visibleQuads = new ArrayList<>(); for (int i = 0; i < this.maxY - this.minY; i++) { if (this.trees.get(i) != null) { - this.trees.get(i).query(frustum, visibleQuads); + this.trees.get(i).query(frustum, visibleQuads, type); } } return visibleQuads; diff --git a/src/main/java/com/goby56/wakes/simulation/WakeNode.java b/src/main/java/com/goby56/wakes/simulation/WakeNode.java index be6101e..580f99b 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeNode.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeNode.java @@ -3,6 +3,8 @@ import com.goby56.wakes.WakesClient; import com.goby56.wakes.utils.WakesUtils; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.color.world.BiomeColors; +import net.minecraft.client.render.WorldRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.fluid.FluidState; @@ -40,6 +42,9 @@ public class WakeNode implements Position, Age { public float t = 0; public int floodLevel; + public int waterColor = 0; + public int lightCoordinate = 0; + // public WakeNode(int x, int z) { // this.x = x; // this.z = z; @@ -140,7 +145,8 @@ public boolean tick() { this.u[0][z][x] *= beta; } } - + waterColor = BiomeColors.getWaterColor(MinecraftClient.getInstance().world, this.blockPos()); + lightCoordinate = WorldRenderer.getLightmapCoordinates(MinecraftClient.getInstance().world, this.blockPos()); floodFill(); return true; } diff --git a/src/main/java/com/goby56/wakes/tests/BrickIndexingTest.java b/src/main/java/com/goby56/wakes/tests/BrickIndexingTest.java index 5420a6c..1b1077d 100644 --- a/src/main/java/com/goby56/wakes/tests/BrickIndexingTest.java +++ b/src/main/java/com/goby56/wakes/tests/BrickIndexingTest.java @@ -1,13 +1,5 @@ package com.goby56.wakes.tests; -import com.goby56.wakes.render.WakeQuad; -import com.goby56.wakes.simulation.Brick; -import com.goby56.wakes.simulation.WakeNode; -import net.minecraft.util.math.Vec3d; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - public class BrickIndexingTest { // @Test // void brickBitMaskCreation() { diff --git a/src/main/java/com/goby56/wakes/tests/GreedyMesherTest.java b/src/main/java/com/goby56/wakes/tests/GreedyMesherTest.java index f5317f9..f92d46c 100644 --- a/src/main/java/com/goby56/wakes/tests/GreedyMesherTest.java +++ b/src/main/java/com/goby56/wakes/tests/GreedyMesherTest.java @@ -1,6 +1,5 @@ package com.goby56.wakes.tests; -import com.goby56.wakes.render.WakeQuad; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/main/java/com/goby56/wakes/utils/WakesDebugInfo.java b/src/main/java/com/goby56/wakes/utils/WakesDebugInfo.java index f5f4cb5..ee00d53 100644 --- a/src/main/java/com/goby56/wakes/utils/WakesDebugInfo.java +++ b/src/main/java/com/goby56/wakes/utils/WakesDebugInfo.java @@ -3,17 +3,15 @@ import java.util.ArrayList; public class WakesDebugInfo { - public static double meshGenerationTime = 0; public static double nodeLogicTime = 0; - public static ArrayList texturingTime = new ArrayList<>(); + public static double texturingTime = 0; public static ArrayList drawingTime = new ArrayList<>(); public static ArrayList wakeRenderingTime = new ArrayList<>(); // Frames averaged each tick public static int quadsRendered = 0; public static void reset() { - meshGenerationTime = 0; nodeLogicTime = 0; - texturingTime = new ArrayList<>(); + texturingTime = 0; drawingTime = new ArrayList<>(); wakeRenderingTime = new ArrayList<>(); }