From 40db6c75e460576c11f71b190a45c5804e00893e Mon Sep 17 00:00:00 2001 From: Goby56 <60710855+Goby56@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:53:14 +0200 Subject: [PATCH 1/4] nodes in wrong brick y level --- .../java/com/goby56/wakes/debug/WakeDebugRenderer.java | 7 +++++++ src/main/java/com/goby56/wakes/simulation/Brick.java | 1 + src/main/java/com/goby56/wakes/simulation/QuadTree.java | 2 +- src/main/java/com/goby56/wakes/simulation/WakeHandler.java | 2 +- src/main/java/com/goby56/wakes/simulation/WakeNode.java | 2 ++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java b/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java index 37b8d32..9e2aba8 100644 --- a/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java +++ b/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java @@ -4,6 +4,7 @@ import com.goby56.wakes.simulation.Brick; import com.goby56.wakes.simulation.WakeHandler; import com.goby56.wakes.simulation.WakeNode; +import kroppeb.stareval.function.Type; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.minecraft.client.render.debug.DebugRenderer; @@ -11,6 +12,8 @@ import net.minecraft.util.math.Vec3d; import java.awt.*; +import java.util.HashMap; +import java.util.Map; import java.util.Random; public class WakeDebugRenderer implements WorldRenderEvents.DebugRender { @@ -18,14 +21,18 @@ public class WakeDebugRenderer implements WorldRenderEvents.DebugRender { @Override public void beforeDebugRender(WorldRenderContext context) { WakeHandler wakeHandler = WakeHandler.getInstance(); + Map nodeHeights = new HashMap<>(); + Map brickHeights = new HashMap<>(); if (WakesClient.CONFIG_INSTANCE.drawDebugBoxes) { for (var node : wakeHandler.getVisible(context.frustum(), WakeNode.class)) { + nodeHeights.merge((int) node.height, 1, Integer::sum); Box box = new Box(node.x, node.height - 0.1f, node.z, node.x + 1, node.height - 0.2f, node.z + 1); DebugRenderer.drawBox(context.matrixStack(), context.consumers(), box.offset(context.camera().getPos().negate()), 1, 0, 1, 0.5f); } for (var brick : wakeHandler.getVisible(context.frustum(), Brick.class)) { + brickHeights.merge((int) brick.pos.y, 1, Integer::sum); Vec3d pos = brick.pos; Box box = new Box(pos.x, pos.y - 0.2f, pos.z, pos.x + brick.dim, pos.y - 0.3f, pos.z + brick.dim); var col = Color.getHSBColor(new Random(pos.hashCode()).nextFloat(), 1f, 1f).getRGBColorComponents(null); diff --git a/src/main/java/com/goby56/wakes/simulation/Brick.java b/src/main/java/com/goby56/wakes/simulation/Brick.java index c606ba6..024025d 100644 --- a/src/main/java/com/goby56/wakes/simulation/Brick.java +++ b/src/main/java/com/goby56/wakes/simulation/Brick.java @@ -113,6 +113,7 @@ public WakeNode get(int x, int z) { } public void insert(WakeNode node) { + if (Math.abs(node.height - this.pos.y) > 1f) System.out.printf("INSERTING %s IN WRONG BRICK (%f)\n", node, this.pos.y); int x = Math.floorMod(node.x, dim), z = Math.floorMod(node.z, dim); if (nodes[z][x] != null) { nodes[z][x].revive(node); diff --git a/src/main/java/com/goby56/wakes/simulation/QuadTree.java b/src/main/java/com/goby56/wakes/simulation/QuadTree.java index 6957e55..de17362 100644 --- a/src/main/java/com/goby56/wakes/simulation/QuadTree.java +++ b/src/main/java/com/goby56/wakes/simulation/QuadTree.java @@ -38,7 +38,7 @@ private boolean hasLeaf() { private void initLeaf() { if (depth >= MAX_DEPTH) { - this.brick = new Brick(bounds.x, yLevel, bounds.z, bounds.width); + this.brick = new Brick(bounds.x, this.yLevel, bounds.z, bounds.width); this.ROOT.updateAdjacency(this); } } diff --git a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java index a6b9371..b55dd37 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java @@ -94,7 +94,7 @@ private int getArrayIndex(int height) { if (height < this.minY || height > this.maxY) { return -1; } - return height + Math.abs(this.minY); + return height - this.minY; } public static void scheduleResolutionChange(Resolution newRes) { diff --git a/src/main/java/com/goby56/wakes/simulation/WakeNode.java b/src/main/java/com/goby56/wakes/simulation/WakeNode.java index d123b9a..92b6159 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeNode.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeNode.java @@ -42,6 +42,8 @@ public class WakeNode implements Position, Age { public float t = 0; public int floodLevel; + public Entity spawner; + //TODO MORE GENERALIZED CONSTRUCTOR public WakeNode(Vec3d position, int initialStrength) { this.initValues(); From 4169c8e4356a6ced307169b1184c17805a679444 Mon Sep 17 00:00:00 2001 From: Goby56 <60710855+Goby56@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:52:05 +0200 Subject: [PATCH 2/4] F*CK I HATE JAVA well its not that bad but WHY does Arraylist::add at index SHIFT THE WHOLE ARRAY AHHH. Anyway now the splash planes wont show D: --- .../com/goby56/wakes/config/WakesConfig.java | 1 - .../goby56/wakes/config/YACLIntegration.java | 3 - .../com/goby56/wakes/debug/DebugCommand.java | 1 + .../goby56/wakes/debug/WakeDebugRenderer.java | 9 +- .../com/goby56/wakes/duck/ProducesWake.java | 4 +- .../goby56/wakes/mixin/LilyPadFallMixin.java | 2 +- .../goby56/wakes/mixin/WakeSpawnerMixin.java | 12 +- .../particle/custom/SplashCloudParticle.java | 5 +- .../particle/custom/SplashPlaneParticle.java | 5 +- .../com/goby56/wakes/render/WakeTexture.java | 3 +- .../java/com/goby56/wakes/simulation/Age.java | 8 -- .../com/goby56/wakes/simulation/Brick.java | 1 - .../com/goby56/wakes/simulation/Position.java | 14 -- .../com/goby56/wakes/simulation/QuadTree.java | 3 +- .../goby56/wakes/simulation/WakeHandler.java | 48 ++++--- .../com/goby56/wakes/simulation/WakeNode.java | 132 +++++++----------- .../com/goby56/wakes/utils/WakesUtils.java | 43 +++--- .../resources/assets/wakes/lang/en_us.yml | 1 - 18 files changed, 118 insertions(+), 177 deletions(-) delete mode 100644 src/main/java/com/goby56/wakes/simulation/Age.java delete mode 100644 src/main/java/com/goby56/wakes/simulation/Position.java diff --git a/src/main/java/com/goby56/wakes/config/WakesConfig.java b/src/main/java/com/goby56/wakes/config/WakesConfig.java index b7df804..49358fe 100644 --- a/src/main/java/com/goby56/wakes/config/WakesConfig.java +++ b/src/main/java/com/goby56/wakes/config/WakesConfig.java @@ -26,7 +26,6 @@ public class WakesConfig { "mobs", EffectSpawningRule.ONLY_SIMULATION, "items", EffectSpawningRule.ONLY_SIMULATION )); - public boolean wakesInRunningWater = false; // Behaviour public float wavePropagationFactor = 0.95f; diff --git a/src/main/java/com/goby56/wakes/config/YACLIntegration.java b/src/main/java/com/goby56/wakes/config/YACLIntegration.java index 8980ef7..e2d075c 100644 --- a/src/main/java/com/goby56/wakes/config/YACLIntegration.java +++ b/src/main/java/com/goby56/wakes/config/YACLIntegration.java @@ -44,9 +44,6 @@ public static Screen createScreen(Screen parent) { .option(effectSpawningRuleOption("other_players", EffectSpawningRule.ONLY_SIMULATION)) .option(effectSpawningRuleOption("mobs", EffectSpawningRule.ONLY_SIMULATION)) .option(effectSpawningRuleOption("items", EffectSpawningRule.ONLY_SIMULATION)) - .option(booleanOption("wakes_in_running_water", false) - .binding(false, () -> config.wakesInRunningWater, val -> config.wakesInRunningWater = val) - .build()) .option(booleanOption("spawn_particles", false) .binding(true, () -> config.spawnParticles, val -> config.spawnParticles = val) .build()) diff --git a/src/main/java/com/goby56/wakes/debug/DebugCommand.java b/src/main/java/com/goby56/wakes/debug/DebugCommand.java index 2562524..077855c 100644 --- a/src/main/java/com/goby56/wakes/debug/DebugCommand.java +++ b/src/main/java/com/goby56/wakes/debug/DebugCommand.java @@ -42,6 +42,7 @@ public static int spawnWakeNode(CommandContext cmdCtx if (!cmdCtx.getSource().getWorld().getFluidState(new BlockPos((int) pos.x, (int) Math.floor(pos.y), (int) pos.z)).isIn(FluidTags.WATER)) return 0; WakeNode node = new WakeNode(result.getPos(), 100); node.floodLevel = cmdCtx.getArgument("flood_level", Integer.class); + node.spawner = "Command"; WakeHandler.getInstance().insert(node); return 1; } diff --git a/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java b/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java index 9e2aba8..7e93ae8 100644 --- a/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java +++ b/src/main/java/com/goby56/wakes/debug/WakeDebugRenderer.java @@ -21,20 +21,15 @@ public class WakeDebugRenderer implements WorldRenderEvents.DebugRender { @Override public void beforeDebugRender(WorldRenderContext context) { WakeHandler wakeHandler = WakeHandler.getInstance(); - Map nodeHeights = new HashMap<>(); - Map brickHeights = new HashMap<>(); if (WakesClient.CONFIG_INSTANCE.drawDebugBoxes) { for (var node : wakeHandler.getVisible(context.frustum(), WakeNode.class)) { - nodeHeights.merge((int) node.height, 1, Integer::sum); - Box box = new Box(node.x, node.height - 0.1f, node.z, node.x + 1, node.height - 0.2f, node.z + 1); DebugRenderer.drawBox(context.matrixStack(), context.consumers(), - box.offset(context.camera().getPos().negate()), + node.toBox().offset(context.camera().getPos().negate()), 1, 0, 1, 0.5f); } for (var brick : wakeHandler.getVisible(context.frustum(), Brick.class)) { - brickHeights.merge((int) brick.pos.y, 1, Integer::sum); Vec3d pos = brick.pos; - Box box = new Box(pos.x, pos.y - 0.2f, pos.z, pos.x + brick.dim, pos.y - 0.3f, pos.z + brick.dim); + Box box = new Box(pos.x, pos.y - (1 - WakeNode.WATER_OFFSET), pos.z, pos.x + brick.dim, pos.y, pos.z + brick.dim); var col = Color.getHSBColor(new Random(pos.hashCode()).nextFloat(), 1f, 1f).getRGBColorComponents(null); DebugRenderer.drawBox(context.matrixStack(), context.consumers(), box.offset(context.camera().getPos().negate()), diff --git a/src/main/java/com/goby56/wakes/duck/ProducesWake.java b/src/main/java/com/goby56/wakes/duck/ProducesWake.java index 26eb644..b3d5e0e 100644 --- a/src/main/java/com/goby56/wakes/duck/ProducesWake.java +++ b/src/main/java/com/goby56/wakes/duck/ProducesWake.java @@ -5,8 +5,8 @@ public interface ProducesWake { boolean onWaterSurface(); - float producingHeight(); - void setProducingHeight(float h); + Integer producingWaterLevel(); + void setProducingHeight(int y); Vec3d getPrevPos(); void setPrevPos(Vec3d pos); Vec3d getNumericalVelocity(); diff --git a/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java b/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java index 6077fd6..9ff8929 100644 --- a/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java @@ -27,7 +27,7 @@ public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity ent EffectSpawningRule rule = WakesUtils.getEffectRuleFromSource(entity); ProducesWake wakeProducer = (ProducesWake) entity; if (rule.simulateWakes) { - wakeProducer.setProducingHeight(pos.getY() + world.getFluidState(pos).getHeight()); + wakeProducer.setProducingHeight(pos.getY()); WakesUtils.placeFallSplash(entity); } } diff --git a/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java b/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java index 357280d..b3e42fb 100644 --- a/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java @@ -34,7 +34,7 @@ public abstract class WakeSpawnerMixin implements ProducesWake { @Unique private Vec3d numericalVelocity = Vec3d.ZERO; @Unique private double horizontalNumericalVelocity = 0; @Unique private double verticalNumericalVelocity = 0; - @Unique private Float producingWaterLevel = null; + @Unique private Integer producingWaterLevel = null; @Unique private SplashPlaneParticle splashPlane; @Unique private boolean hasRecentlyTeleported = false; @@ -68,13 +68,13 @@ public void setPrevPos(Vec3d pos) { } @Override - public float producingHeight() { + public Integer producingWaterLevel() { return this.producingWaterLevel; } @Override - public void setProducingHeight(float h) { - this.producingWaterLevel = h; + public void setProducingHeight(int y) { + this.producingWaterLevel = y; } @Override @@ -114,7 +114,7 @@ private void tick(CallbackInfo info) { if (this.onWaterSurface && !this.hasRecentlyTeleported) { if (this.producingWaterLevel == null) - this.producingWaterLevel = WakesUtils.getWaterLevel(this.world, thisEntity); + this.producingWaterLevel = (int) Math.floor(WakesUtils.getWaterLevel(this.world, thisEntity)); Vec3d currPos = new Vec3d(thisEntity.getX(), this.producingWaterLevel, thisEntity.getZ()); @@ -138,7 +138,7 @@ private void onSwimmingStart(CallbackInfo ci) { EffectSpawningRule rule = WakesUtils.getEffectRuleFromSource(thisEntity); if (rule.simulateWakes) { if (this.producingWaterLevel == null) - this.producingWaterLevel = WakesUtils.getWaterLevel(this.world, thisEntity); + this.producingWaterLevel = (int) Math.floor(WakesUtils.getWaterLevel(this.world, thisEntity)); WakesUtils.placeFallSplash(((Entity) (Object) this)); } // TODO ADD WAKE WHEN GETTING OUT OF WATER diff --git a/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java b/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java index db292fa..f63245a 100644 --- a/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java +++ b/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java @@ -1,6 +1,5 @@ package com.goby56.wakes.particle.custom; -import com.goby56.wakes.WakesClient; import com.goby56.wakes.duck.ProducesWake; import com.goby56.wakes.particle.WithOwnerParticleType; import com.goby56.wakes.simulation.WakeNode; @@ -45,7 +44,7 @@ public void tick() { if (this.owner instanceof ProducesWake wake) { SplashPlaneParticle splashPlane = wake.getSplashPlane(); - if (splashPlane == null) { + if (splashPlane == null || wake.producingWaterLevel() == null) { this.markDead(); return; } @@ -56,7 +55,7 @@ public void tick() { Vec3d particleOffset = new Vec3d(-splashPlane.direction.z, 0f, splashPlane.direction.x).multiply(this.offset * this.owner.getWidth() / 2f); Vec3d pos = splashPlane.getPos().add(particleOffset).add(splashPlane.direction.multiply(-0.2f)); - this.setPos(pos.x, wake.producingHeight(), pos.z); + this.setPos(pos.x, wake.producingWaterLevel(), pos.z); } } diff --git a/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java b/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java index 2e3ff87..13a47c8 100644 --- a/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java +++ b/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java @@ -24,9 +24,6 @@ import net.minecraft.util.math.*; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Random; - public class SplashPlaneParticle extends Particle { Entity owner; float yaw; @@ -81,7 +78,7 @@ private void aliveTick(ProducesWake wakeProducer) { this.direction = Vec3d.fromPolar(0, -this.yaw); Vec3d planeOffset = direction.multiply(this.owner.getWidth() + WakesClient.CONFIG_INSTANCE.splashPlaneOffset); Vec3d planePos = this.owner.getPos().add(planeOffset); - this.setPos(planePos.x, wakeProducer.producingHeight(), planePos.z); + this.setPos(planePos.x, wakeProducer.producingWaterLevel(), planePos.z); } @Override diff --git a/src/main/java/com/goby56/wakes/render/WakeTexture.java b/src/main/java/com/goby56/wakes/render/WakeTexture.java index 1e416fa..b0b9383 100644 --- a/src/main/java/com/goby56/wakes/render/WakeTexture.java +++ b/src/main/java/com/goby56/wakes/render/WakeTexture.java @@ -3,6 +3,7 @@ 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.mojang.blaze3d.platform.GlConst; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.TextureUtil; @@ -48,7 +49,7 @@ public void render(Matrix4f matrix, Camera camera, Brick brick) { BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL); - Vector3f pos = brick.pos.add(camera.getPos().negate()).toVector3f(); + Vector3f pos = brick.pos.add(camera.getPos().negate()).toVector3f().add(0, WakeNode.WATER_OFFSET, 0); int light = LightmapTextureManager.MAX_LIGHT_COORDINATE; buffer.vertex(matrix, pos.x, pos.y, pos.z) .color(1f, 1f, 1f, 1f) diff --git a/src/main/java/com/goby56/wakes/simulation/Age.java b/src/main/java/com/goby56/wakes/simulation/Age.java deleted file mode 100644 index 8b2ab87..0000000 --- a/src/main/java/com/goby56/wakes/simulation/Age.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.goby56.wakes.simulation; - -public interface Age { - boolean isDead(); - void markDead(); - void revive(T newNode); - boolean tick(); -} diff --git a/src/main/java/com/goby56/wakes/simulation/Brick.java b/src/main/java/com/goby56/wakes/simulation/Brick.java index 024025d..c606ba6 100644 --- a/src/main/java/com/goby56/wakes/simulation/Brick.java +++ b/src/main/java/com/goby56/wakes/simulation/Brick.java @@ -113,7 +113,6 @@ public WakeNode get(int x, int z) { } public void insert(WakeNode node) { - if (Math.abs(node.height - this.pos.y) > 1f) System.out.printf("INSERTING %s IN WRONG BRICK (%f)\n", node, this.pos.y); int x = Math.floorMod(node.x, dim), z = Math.floorMod(node.z, dim); if (nodes[z][x] != null) { nodes[z][x].revive(node); diff --git a/src/main/java/com/goby56/wakes/simulation/Position.java b/src/main/java/com/goby56/wakes/simulation/Position.java deleted file mode 100644 index 7819ed5..0000000 --- a/src/main/java/com/goby56/wakes/simulation/Position.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.goby56.wakes.simulation; - -import net.minecraft.util.math.Box; - -public interface Position { - int x(); - int z(); - - boolean inValidPos(); - - Box toBox(); - - void updateAdjacency(T node); -} diff --git a/src/main/java/com/goby56/wakes/simulation/QuadTree.java b/src/main/java/com/goby56/wakes/simulation/QuadTree.java index de17362..40e3e55 100644 --- a/src/main/java/com/goby56/wakes/simulation/QuadTree.java +++ b/src/main/java/com/goby56/wakes/simulation/QuadTree.java @@ -19,7 +19,7 @@ public class QuadTree { private final DecentralizedBounds bounds; private final int depth; private Brick brick; - private final float yLevel; + public final float yLevel; public QuadTree(float y) { this(ROOT_X, y, ROOT_Z, ROOT_WIDTH, 0, null); @@ -97,7 +97,6 @@ public void query(Frustum frustum, ArrayList output, Class type) { return; } if (hasLeaf() && brick.occupied > 0) { - // TODO ADD VISIBLE NODES CHECK if (type.equals(Brick.class)) { output.add(type.cast(brick)); } diff --git a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java index b55dd37..4ce1a33 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java @@ -15,8 +15,8 @@ public class WakeHandler { private static WakeHandler INSTANCE; public World world; - private final ArrayList trees; - private final ArrayList> toBeInserted; + private QuadTree[] trees; + private QueueSet[] toBeInserted; public boolean resolutionResetScheduled = false; private final int minY; private final int maxY; @@ -27,11 +27,10 @@ private WakeHandler(ClientWorld world) { this.minY = world.getBottomY(); this.maxY = world.getTopY(); int worldHeight = this.maxY - this.minY; - this.trees = new ArrayList<>(worldHeight); - this.toBeInserted = new ArrayList<>(worldHeight); + this.trees = new QuadTree[worldHeight]; + this.toBeInserted = new QueueSet[worldHeight]; for (int i = 0; i < worldHeight; i++) { - this.trees.add(null); - this.toBeInserted.add(new QueueSet<>()); + toBeInserted[i] = new QueueSet<>(); } } @@ -47,16 +46,15 @@ public static WakeHandler getInstance() { public void tick() { for (int i = 0; i < this.maxY - this.minY; i++) { + Queue pendingNodes = this.toBeInserted[i]; if (this.resolutionResetScheduled) { - this.toBeInserted.get(i).clear(); + if (pendingNodes != null) pendingNodes.clear(); continue; } - QuadTree tree = this.trees.get(i); + QuadTree tree = this.trees[i]; if (tree != null) { tree.tick(); - long tInsertion = System.nanoTime(); - Queue pendingNodes = this.toBeInserted.get(i); while (pendingNodes.peek() != null) { tree.insert(pendingNodes.poll()); } @@ -70,31 +68,40 @@ public void tick() { public void insert(WakeNode node) { if (this.resolutionResetScheduled) return; - int i = this.getArrayIndex((int) node.height); + int i = this.getArrayIndex(node.y); if (i < 0) return; - if (this.trees.get(i) == null) { - this.trees.add(i, new QuadTree(node.height)); + if (this.trees[i] == null) { + this.trees[i] = new QuadTree(node.y); } - this.toBeInserted.get(i).add(node); + if (node.validPos()) { + this.toBeInserted[i].add(node); + } } 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, type); + if (this.trees[i] != null) { + this.trees[i].query(frustum, visibleQuads, type); } } return visibleQuads; } - private int getArrayIndex(int height) { - if (height < this.minY || height > this.maxY) { + private int getArrayIndex(int y) { + if (y < this.minY || y > this.maxY) { return -1; } - return height - this.minY; + return y - this.minY; + } + + private int getYLevel(int i) { + if (i < 0 || i > this.maxY - this.minY) { + throw new IndexOutOfBoundsException(); + } + return i + this.minY; } public static void scheduleResolutionChange(Resolution newRes) { @@ -114,10 +121,11 @@ private void changeResolution() { private void reset() { for (int i = 0; i < this.maxY - this.minY; i++) { - QuadTree tree = this.trees.get(i); + QuadTree tree = this.trees[i]; if (tree != null) { tree.prune(); } + toBeInserted[i].clear(); } } diff --git a/src/main/java/com/goby56/wakes/simulation/WakeNode.java b/src/main/java/com/goby56/wakes/simulation/WakeNode.java index 92b6159..05db054 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeNode.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeNode.java @@ -3,11 +3,10 @@ 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; +import net.minecraft.fluid.Fluids; import net.minecraft.registry.tag.FluidTags; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; @@ -15,9 +14,7 @@ import java.util.*; -public class WakeNode implements Position, Age { - // TODO MAKE SURE THIS WONT EVER BE NULL - +public class WakeNode { public static int res = WakesClient.CONFIG_INSTANCE.wakeResolution.res; private static float alpha; @@ -26,8 +23,9 @@ public class WakeNode implements Position, Age { public float[][] initialValues; public final int x; + public final int y; public final int z; - public float height; + public static final float WATER_OFFSET = 8 / 9f; public WakeNode NORTH = null; public WakeNode EAST = null; @@ -42,14 +40,14 @@ public class WakeNode implements Position, Age { public float t = 0; public int floodLevel; - public Entity spawner; + public String spawner = "Self"; //TODO MORE GENERALIZED CONSTRUCTOR public WakeNode(Vec3d position, int initialStrength) { this.initValues(); this.x = (int) Math.floor(position.x); + this.y = (int) Math.floor(position.y); this.z = (int) Math.floor(position.z); - this.height = (float) position.getY(); int sx = (int) Math.floor(res * (position.x - this.x)); int sz = (int) Math.floor(res * (position.z - this.z)); for (int z = -1; z < 2; z++) { @@ -60,20 +58,20 @@ public WakeNode(Vec3d position, int initialStrength) { this.floodLevel = WakesClient.CONFIG_INSTANCE.floodFillDistance; } - private WakeNode(int x, int z, float height, int floodLevel) { + private WakeNode(int x, int y, int z, int floodLevel) { this.initValues(); this.x = x; + this.y = y; this.z = z; - this.height = height; this.floodLevel = floodLevel; } - private WakeNode(long pos, float height) { + private WakeNode(long pos, int y) { this.initValues(); int[] xz = WakesUtils.longAsPos(pos); this.x = xz[0]; + this.y = y; this.z = xz[1]; - this.height = height; this.floodLevel = WakesClient.CONFIG_INSTANCE.floodFillDistance; } @@ -101,14 +99,13 @@ public static void calculateWaveDevelopmentFactors() { WakeNode.beta = (float) (Math.log(10 * WakesClient.CONFIG_INSTANCE.waveDecayFactor + 10) / Math.log(20)); // Logarithmic scale } - @Override public boolean tick() { if (this.isDead()) return false; - if (this.age++ >= this.maxAge || res != WakesClient.CONFIG_INSTANCE.wakeResolution.res) { + if (this.age++ >= WakeNode.maxAge || res != WakesClient.CONFIG_INSTANCE.wakeResolution.res) { this.markDead(); return false; } - this.t = this.age / (float) this.maxAge; + this.t = this.age / (float) WakeNode.maxAge; for (int i = 2; i >= 1; i--) { if (this.NORTH != null) this.u[i][0] = this.NORTH.u[i][res]; @@ -147,22 +144,22 @@ public void floodFill() { WakeHandler wh = WakeHandler.getInstance(); if (floodLevel > 0 && this.age > WakesClient.CONFIG_INSTANCE.ticksBeforeFill) { if (this.NORTH == null) { - wh.insert(new WakeNode(this.x, this.z - 1, this.height, floodLevel - 1)); + wh.insert(new WakeNode(this.x, this.y, this.z - 1, floodLevel - 1)); } else { this.NORTH.updateFloodLevel(floodLevel - 1); } if (this.EAST == null) { - wh.insert(new WakeNode(this.x + 1, this.z, this.height, floodLevel - 1)); + wh.insert(new WakeNode(this.x + 1, this.y, this.z, floodLevel - 1)); } else { this.EAST.updateFloodLevel(floodLevel - 1); } if (this.SOUTH == null) { - wh.insert(new WakeNode(this.x, this.z + 1, this.height, floodLevel - 1)); + wh.insert(new WakeNode(this.x, this.y, this.z + 1, floodLevel - 1)); } else { this.SOUTH.updateFloodLevel(floodLevel - 1); } if (this.WEST == null) { - wh.insert(new WakeNode(this.x - 1, this.z, this.height, floodLevel - 1)); + wh.insert(new WakeNode(this.x - 1, this.y, this.z, floodLevel - 1)); } else { this.WEST.updateFloodLevel(floodLevel - 1); } @@ -171,7 +168,6 @@ public void floodFill() { } } - @Override public void updateAdjacency(WakeNode node) { if (node.x == this.x && node.z == this.z - 1) { this.NORTH = node; @@ -201,80 +197,56 @@ public void updateFloodLevel(int newLevel) { } } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WakeNode wakeNode = (WakeNode) o; - return x == wakeNode.x && z == wakeNode.z; - } - - @Override - public int hashCode() { - return Objects.hash(x, z); - } - - @Override - public String toString() { - return "WakeNode{" + - "x=" + x + - ", z=" + z + - ", height=" + height + - '}'; + public boolean validPos() { + FluidState fluidState = MinecraftClient.getInstance().world.getFluidState(this.blockPos()); + FluidState fluidStateAbove = MinecraftClient.getInstance().world.getFluidState(this.blockPos().up()); + if (fluidState.isOf(Fluids.WATER) && fluidStateAbove.isEmpty()) { + return fluidState.isStill(); + } + return false; } - @Override public Box toBox() { - return new Box(this.x, Math.floor(this.height), this.z, this.x + 1, Math.ceil(this.height), this.z + 1); - } - - @Override - public int x() { - return this.x; + return new Box(this.x, this.y, this.z, this.x + 1, this.y + (1 - WakeNode.WATER_OFFSET), this.z + 1); } - @Override - public int z() { - return this.z; - } - - @Override public void revive(WakeNode node) { this.age = 0; this.floodLevel = WakesClient.CONFIG_INSTANCE.floodFillDistance; this.initialValues = node.initialValues; } - @Override public void markDead() { this.dead = true; } - @Override public boolean isDead() { return this.dead; } - @Override - public boolean inValidPos() { - FluidState fluidState = MinecraftClient.getInstance().world.getFluidState(this.blockPos()); - FluidState fluidStateAbove = MinecraftClient.getInstance().world.getFluidState(this.blockPos().up()); - if (fluidState.isIn(FluidTags.WATER) && !fluidStateAbove.isIn(FluidTags.WATER)) { - return fluidState.isStill() || WakesClient.CONFIG_INSTANCE.wakesInRunningWater; - } - return false; + public BlockPos blockPos() { + return new BlockPos(this.x, this.y, this.z); } - public Vec3d getPos() { - return new Vec3d(this.x, this.height, this.z); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WakeNode wakeNode = (WakeNode) o; + return x == wakeNode.x && z == wakeNode.z; } - public BlockPos blockPos() { - return new BlockPos(this.x, (int) Math.floor(this.height), this.z); + @Override + public int hashCode() { + return Objects.hash(x, z); } + @Override + public String toString() { + return String.format("WakeNode{%d, %d, %d}", x, y, z); + } public static class Factory { - public static Set splashNodes(Entity entity, float height) { + public static Set splashNodes(Entity entity, int y) { int res = WakeNode.res; int w = (int) (0.8 * entity.getWidth() * res / 2); int x = (int) (entity.getX() * res); @@ -288,10 +260,10 @@ public static Set splashNodes(Entity entity, float height) { } } } - return pixelsToNodes(pixelsAffected, height, WakesClient.CONFIG_INSTANCE.splashStrength, Math.abs(entity.getVelocity().y)); + return pixelsToNodes(pixelsAffected, y, WakesClient.CONFIG_INSTANCE.splashStrength, Math.abs(entity.getVelocity().y)); } - public static Set rowingNodes(BoatEntity boat, float height) { + public static Set rowingNodes(BoatEntity boat, int y) { Set nodesAffected = new HashSet<>(); double velocity = boat.getVelocity().horizontalLength(); for (int i = 0; i < 2; i++) { @@ -301,18 +273,18 @@ public static Set rowingNodes(BoatEntity boat, float height) { Vec3d rot = boat.getRotationVec(1.0f); double x = boat.getX() + (i == 1 ? -rot.z : rot.z); double z = boat.getZ() + (i == 1 ? rot.x : -rot.x); - Vec3d paddlePos = new Vec3d(x, height, z); + Vec3d paddlePos = new Vec3d(x, y, z); Vec3d dir = Vec3d.fromPolar(0, boat.getYaw()).multiply(velocity); Vec3d from = paddlePos; Vec3d to = paddlePos.add(dir.multiply(2)); - nodesAffected.addAll(nodeTrail(from.x, from.z, to.x, to.z, height, WakesClient.CONFIG_INSTANCE.paddleStrength, velocity)); + nodesAffected.addAll(nodeTrail(from.x, from.z, to.x, to.z, y, WakesClient.CONFIG_INSTANCE.paddleStrength, velocity)); } } } return nodesAffected; } - public static Set nodeTrail(double fromX, double fromZ, double toX, double toZ, float height, float waveStrength, double velocity) { + public static Set nodeTrail(double fromX, double fromZ, double toX, double toZ, int y, float waveStrength, double velocity) { int res = WakeNode.res; int x1 = (int) (fromX * res); int z1 = (int) (fromZ * res); @@ -321,10 +293,10 @@ public static Set nodeTrail(double fromX, double fromZ, double toX, do ArrayList pixelsAffected = new ArrayList<>(); WakesUtils.bresenhamLine(x1, z1, x2, z2, pixelsAffected); - return pixelsToNodes(pixelsAffected, height, waveStrength, velocity); + return pixelsToNodes(pixelsAffected, y, waveStrength, velocity); } - public static Set thickNodeTrail(double fromX, double fromZ, double toX, double toZ, float height, float waveStrength, double velocity, float width) { + public static Set thickNodeTrail(double fromX, double fromZ, double toX, double toZ, int y, float waveStrength, double velocity, float width) { int res = WakeNode.res; int x1 = (int) (fromX * res); int z1 = (int) (fromZ * res); @@ -340,10 +312,10 @@ public static Set thickNodeTrail(double fromX, double fromZ, double to for (int i = -w; i < w; i++) { WakesUtils.bresenhamLine((int) (x1 + nx * i), (int) (z1 + nz * i), (int) (x2 + nx * i), (int) (z2 + nz * i), pixelsAffected); } - return pixelsToNodes(pixelsAffected, height, waveStrength, velocity); + return pixelsToNodes(pixelsAffected, y, waveStrength, velocity); } - public static Set nodeLine(double x, double z, float height, float waveStrength, Vec3d velocity, float width) { + public static Set nodeLine(double x, int y, double z, float waveStrength, Vec3d velocity, float width) { int res = WakeNode.res; Vec3d dir = velocity.normalize(); double nx = -dir.z; @@ -357,10 +329,10 @@ public static Set nodeLine(double x, double z, float height, float wav ArrayList pixelsAffected = new ArrayList<>(); WakesUtils.bresenhamLine(x1, z1, x2, z2, pixelsAffected); - return pixelsToNodes(pixelsAffected, height, waveStrength, velocity.horizontalLength()); + return pixelsToNodes(pixelsAffected, y, waveStrength, velocity.horizontalLength()); } - private static Set pixelsToNodes(ArrayList pixelsAffected, float height, float waveStrength, double velocity) { + private static Set pixelsToNodes(ArrayList pixelsAffected, int y, float waveStrength, double velocity) { int res = WakeNode.res; int power = (int) (Math.log(res) / Math.log(2)); HashMap> pixelsInNodes = new HashMap<>(); @@ -380,7 +352,7 @@ private static Set pixelsToNodes(ArrayList pixelsAffected, float } Set nodesAffected = new HashSet<>(); for (Long nodePos : pixelsInNodes.keySet()) { - WakeNode node = new WakeNode(nodePos, height); + WakeNode node = new WakeNode(nodePos, y); for (Long subPos : pixelsInNodes.get(nodePos)) { node.setInitialValue(subPos, (int) (waveStrength * velocity)); } diff --git a/src/main/java/com/goby56/wakes/utils/WakesUtils.java b/src/main/java/com/goby56/wakes/utils/WakesUtils.java index 0fe92ef..79160fb 100644 --- a/src/main/java/com/goby56/wakes/utils/WakesUtils.java +++ b/src/main/java/com/goby56/wakes/utils/WakesUtils.java @@ -10,14 +10,13 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.OtherClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; import net.minecraft.registry.tag.FluidTags; import net.minecraft.text.MutableText; import net.minecraft.text.Text; @@ -39,7 +38,8 @@ public static void placeFallSplash(Entity entity) { return; } - for (WakeNode node : WakeNode.Factory.splashNodes(entity, ((ProducesWake) entity).producingHeight())) { + for (WakeNode node : WakeNode.Factory.splashNodes(entity, ((ProducesWake) entity).producingWaterLevel())) { + node.spawner = entity.getName().toString(); instance.insert(node); } } @@ -53,7 +53,7 @@ public static void spawnPaddleSplashCloudParticle(World world, BoatEntity boat) Vec3d rot = boat.getRotationVec(1.0f); double x = boat.getX() + (i == 1 ? -rot.z : rot.z); double z = boat.getZ() + (i == 1 ? rot.x : -rot.x); - Vec3d pos = new Vec3d(x, ((ProducesWake) boat).producingHeight(), z); + Vec3d pos = new Vec3d(x, ((ProducesWake) boat).producingWaterLevel(), z); world.addParticle(ModParticles.SPLASH_CLOUD, pos.x, pos.y, pos.z, 0, 0, 0); } } @@ -73,10 +73,11 @@ public static void placeWakeTrail(Entity entity) { } ProducesWake producer = (ProducesWake) entity; double velocity = producer.getHorizontalVelocity(); - float height = producer.producingHeight(); + int y = producer.producingWaterLevel(); if (entity instanceof BoatEntity boat) { - for (WakeNode node : WakeNode.Factory.rowingNodes(boat, height)) { + for (WakeNode node : WakeNode.Factory.rowingNodes(boat, y)) { + node.spawner = entity.getName().toString(); wakeHandler.insert(node); } if (WakesClient.CONFIG_INSTANCE.spawnParticles) { @@ -92,7 +93,8 @@ public static void placeWakeTrail(Entity entity) { if (prevPos == null) { return; } - for (WakeNode node : WakeNode.Factory.thickNodeTrail(prevPos.x, prevPos.z, entity.getX(), entity.getZ(), height, WakesClient.CONFIG_INSTANCE.initialStrength, velocity, entity.getWidth())) { + for (WakeNode node : WakeNode.Factory.thickNodeTrail(prevPos.x, prevPos.z, entity.getX(), entity.getZ(), y, WakesClient.CONFIG_INSTANCE.initialStrength, velocity, entity.getWidth())) { + node.spawner = entity.getName().toString(); wakeHandler.insert(node); } } @@ -228,6 +230,10 @@ public static int rgbaArr2abgrInt(int[] arr) { return n; } + public static BlockPos vecToBlockPos(Vec3d v) { + return new BlockPos((int) Math.floor(v.x), (int) Math.floor(v.y), (int) Math.floor(v.z)); + } + public static float getWaterLevel(World world, Entity entityInWater) { Box box = entityInWater.getBoundingBox(); return getWaterLevel(world, @@ -267,21 +273,12 @@ private static float getWaterLevel(World world, int minX, int maxX, int minY, in } - public static BlockPos vecToBlockPos(Vec3d pos) { - return new BlockPos((int) Math.floor(pos.x), (int) Math.floor(pos.y), (int) Math.floor(pos.z)); - } - - - public static MatrixStack getMatrixStackFromCamera(Camera camera, float tickDelta, Vec3d prevPos, Vec3d currPos) { - // Think it moves the matrix context smoothly to the camera - // https://github.com/Ladysnake/Effective/blob/main/src/main/java/ladysnake/effective/particle/SplashParticle.java - Vec3d cameraPos = camera.getPos(); - float x = (float) (MathHelper.lerp(tickDelta, prevPos.x, currPos.x) - cameraPos.getX()); - float y = (float) (MathHelper.lerp(tickDelta, prevPos.y, currPos.y) - cameraPos.getY()); - float z = (float) (MathHelper.lerp(tickDelta, prevPos.z, currPos.z) - cameraPos.getZ()); - - MatrixStack matrixStack = new MatrixStack(); - matrixStack.translate(x, y, z); - return matrixStack; + public static boolean validNodePos(World world, BlockPos pos) { + FluidState fluidState = world.getFluidState(pos); + FluidState fluidStateAbove = world.getFluidState(pos.up()); + if (fluidState.isOf(Fluids.WATER) && fluidStateAbove.isEmpty()) { + return fluidState.isStill(); + } + return false; } } diff --git a/src/main/resources/assets/wakes/lang/en_us.yml b/src/main/resources/assets/wakes/lang/en_us.yml index d5e4068..7949b1d 100644 --- a/src/main/resources/assets/wakes/lang/en_us.yml +++ b/src/main/resources/assets/wakes/lang/en_us.yml @@ -44,7 +44,6 @@ wakes: only_simulation: Only simulation only_planes: Only planes disabled: Disabled - wakes_in_running_water: Wakes in running water spawn_particles: Spawn particles wave_propagation_factor: Wave propagation factor wave_decay_factor: Wave decay factor From fb098a016e4e35b92a4f4ebc44a195ab468de100 Mon Sep 17 00:00:00 2001 From: Goby56 <60710855+Goby56@users.noreply.github.com> Date: Fri, 23 Aug 2024 17:51:45 +0200 Subject: [PATCH 3/4] okay now its height is correct --- .../com/goby56/wakes/debug/DebugCommand.java | 1 - .../com/goby56/wakes/duck/ProducesWake.java | 4 ++-- .../goby56/wakes/mixin/LilyPadFallMixin.java | 3 ++- .../goby56/wakes/mixin/WakeSpawnerMixin.java | 13 ++++++------ .../particle/custom/SplashCloudParticle.java | 4 ++-- .../particle/custom/SplashPlaneParticle.java | 3 +-- .../com/goby56/wakes/simulation/WakeNode.java | 2 -- .../com/goby56/wakes/utils/WakesUtils.java | 20 ++----------------- 8 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/goby56/wakes/debug/DebugCommand.java b/src/main/java/com/goby56/wakes/debug/DebugCommand.java index 077855c..2562524 100644 --- a/src/main/java/com/goby56/wakes/debug/DebugCommand.java +++ b/src/main/java/com/goby56/wakes/debug/DebugCommand.java @@ -42,7 +42,6 @@ public static int spawnWakeNode(CommandContext cmdCtx if (!cmdCtx.getSource().getWorld().getFluidState(new BlockPos((int) pos.x, (int) Math.floor(pos.y), (int) pos.z)).isIn(FluidTags.WATER)) return 0; WakeNode node = new WakeNode(result.getPos(), 100); node.floodLevel = cmdCtx.getArgument("flood_level", Integer.class); - node.spawner = "Command"; WakeHandler.getInstance().insert(node); return 1; } diff --git a/src/main/java/com/goby56/wakes/duck/ProducesWake.java b/src/main/java/com/goby56/wakes/duck/ProducesWake.java index b3d5e0e..b3921f3 100644 --- a/src/main/java/com/goby56/wakes/duck/ProducesWake.java +++ b/src/main/java/com/goby56/wakes/duck/ProducesWake.java @@ -5,8 +5,8 @@ public interface ProducesWake { boolean onWaterSurface(); - Integer producingWaterLevel(); - void setProducingHeight(int y); + Float producingWaterLevel(); + void setProducingHeight(float h); Vec3d getPrevPos(); void setPrevPos(Vec3d pos); Vec3d getNumericalVelocity(); diff --git a/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java b/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java index 9ff8929..680a84a 100644 --- a/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/LilyPadFallMixin.java @@ -3,6 +3,7 @@ import com.goby56.wakes.WakesClient; import com.goby56.wakes.config.enums.EffectSpawningRule; import com.goby56.wakes.duck.ProducesWake; +import com.goby56.wakes.simulation.WakeNode; import com.goby56.wakes.utils.WakesUtils; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -27,7 +28,7 @@ public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity ent EffectSpawningRule rule = WakesUtils.getEffectRuleFromSource(entity); ProducesWake wakeProducer = (ProducesWake) entity; if (rule.simulateWakes) { - wakeProducer.setProducingHeight(pos.getY()); + wakeProducer.setProducingHeight(pos.getY() + WakeNode.WATER_OFFSET); WakesUtils.placeFallSplash(entity); } } diff --git a/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java b/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java index b3e42fb..76ee3b0 100644 --- a/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/WakeSpawnerMixin.java @@ -34,7 +34,7 @@ public abstract class WakeSpawnerMixin implements ProducesWake { @Unique private Vec3d numericalVelocity = Vec3d.ZERO; @Unique private double horizontalNumericalVelocity = 0; @Unique private double verticalNumericalVelocity = 0; - @Unique private Integer producingWaterLevel = null; + @Unique private Float producingWaterLevel = null; @Unique private SplashPlaneParticle splashPlane; @Unique private boolean hasRecentlyTeleported = false; @@ -68,13 +68,13 @@ public void setPrevPos(Vec3d pos) { } @Override - public Integer producingWaterLevel() { + public Float producingWaterLevel() { return this.producingWaterLevel; } @Override - public void setProducingHeight(int y) { - this.producingWaterLevel = y; + public void setProducingHeight(float h) { + this.producingWaterLevel = h; } @Override @@ -113,8 +113,7 @@ private void tick(CallbackInfo info) { } if (this.onWaterSurface && !this.hasRecentlyTeleported) { - if (this.producingWaterLevel == null) - this.producingWaterLevel = (int) Math.floor(WakesUtils.getWaterLevel(this.world, thisEntity)); + this.producingWaterLevel = WakesUtils.getWaterLevel(this.world, thisEntity); Vec3d currPos = new Vec3d(thisEntity.getX(), this.producingWaterLevel, thisEntity.getZ()); @@ -138,7 +137,7 @@ private void onSwimmingStart(CallbackInfo ci) { EffectSpawningRule rule = WakesUtils.getEffectRuleFromSource(thisEntity); if (rule.simulateWakes) { if (this.producingWaterLevel == null) - this.producingWaterLevel = (int) Math.floor(WakesUtils.getWaterLevel(this.world, thisEntity)); + this.producingWaterLevel = WakesUtils.getWaterLevel(this.world, thisEntity); WakesUtils.placeFallSplash(((Entity) (Object) this)); } // TODO ADD WAKE WHEN GETTING OUT OF WATER diff --git a/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java b/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java index f63245a..20aa944 100644 --- a/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java +++ b/src/main/java/com/goby56/wakes/particle/custom/SplashCloudParticle.java @@ -44,7 +44,7 @@ public void tick() { if (this.owner instanceof ProducesWake wake) { SplashPlaneParticle splashPlane = wake.getSplashPlane(); - if (splashPlane == null || wake.producingWaterLevel() == null) { + if (splashPlane == null) { this.markDead(); return; } @@ -55,7 +55,7 @@ public void tick() { Vec3d particleOffset = new Vec3d(-splashPlane.direction.z, 0f, splashPlane.direction.x).multiply(this.offset * this.owner.getWidth() / 2f); Vec3d pos = splashPlane.getPos().add(particleOffset).add(splashPlane.direction.multiply(-0.2f)); - this.setPos(pos.x, wake.producingWaterLevel(), pos.z); + this.setPos(pos.x, pos.y, pos.z); } } diff --git a/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java b/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java index 13a47c8..c87d554 100644 --- a/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java +++ b/src/main/java/com/goby56/wakes/particle/custom/SplashPlaneParticle.java @@ -5,6 +5,7 @@ import com.goby56.wakes.particle.ModParticles; import com.goby56.wakes.particle.WithOwnerParticleType; import com.goby56.wakes.render.SplashPlaneRenderer; +import com.goby56.wakes.simulation.WakeNode; import com.goby56.wakes.utils.WakesUtils; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -28,7 +29,6 @@ public class SplashPlaneParticle extends Particle { Entity owner; float yaw; float prevYaw; - int ticksSinceSplash = 0; Vec3d direction = Vec3d.ZERO; @@ -68,7 +68,6 @@ public void tick() { } private void aliveTick(ProducesWake wakeProducer) { - this.ticksSinceSplash++; if (this.owner instanceof BoatEntity) { this.yaw = -this.owner.getYaw(); } else { diff --git a/src/main/java/com/goby56/wakes/simulation/WakeNode.java b/src/main/java/com/goby56/wakes/simulation/WakeNode.java index 05db054..4867c81 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeNode.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeNode.java @@ -40,8 +40,6 @@ public class WakeNode { public float t = 0; public int floodLevel; - public String spawner = "Self"; - //TODO MORE GENERALIZED CONSTRUCTOR public WakeNode(Vec3d position, int initialStrength) { this.initValues(); diff --git a/src/main/java/com/goby56/wakes/utils/WakesUtils.java b/src/main/java/com/goby56/wakes/utils/WakesUtils.java index 79160fb..fd7a8d4 100644 --- a/src/main/java/com/goby56/wakes/utils/WakesUtils.java +++ b/src/main/java/com/goby56/wakes/utils/WakesUtils.java @@ -38,8 +38,7 @@ public static void placeFallSplash(Entity entity) { return; } - for (WakeNode node : WakeNode.Factory.splashNodes(entity, ((ProducesWake) entity).producingWaterLevel())) { - node.spawner = entity.getName().toString(); + for (WakeNode node : WakeNode.Factory.splashNodes(entity, (int) Math.floor(((ProducesWake) entity).producingWaterLevel()))) { instance.insert(node); } } @@ -73,11 +72,10 @@ public static void placeWakeTrail(Entity entity) { } ProducesWake producer = (ProducesWake) entity; double velocity = producer.getHorizontalVelocity(); - int y = producer.producingWaterLevel(); + int y = (int) Math.floor(producer.producingWaterLevel()); if (entity instanceof BoatEntity boat) { for (WakeNode node : WakeNode.Factory.rowingNodes(boat, y)) { - node.spawner = entity.getName().toString(); wakeHandler.insert(node); } if (WakesClient.CONFIG_INSTANCE.spawnParticles) { @@ -94,7 +92,6 @@ public static void placeWakeTrail(Entity entity) { return; } for (WakeNode node : WakeNode.Factory.thickNodeTrail(prevPos.x, prevPos.z, entity.getX(), entity.getZ(), y, WakesClient.CONFIG_INSTANCE.initialStrength, velocity, entity.getWidth())) { - node.spawner = entity.getName().toString(); wakeHandler.insert(node); } } @@ -230,10 +227,6 @@ public static int rgbaArr2abgrInt(int[] arr) { return n; } - public static BlockPos vecToBlockPos(Vec3d v) { - return new BlockPos((int) Math.floor(v.x), (int) Math.floor(v.y), (int) Math.floor(v.z)); - } - public static float getWaterLevel(World world, Entity entityInWater) { Box box = entityInWater.getBoundingBox(); return getWaterLevel(world, @@ -272,13 +265,4 @@ private static float getWaterLevel(World world, int minX, int maxX, int minY, in return maxY + 1; } - - public static boolean validNodePos(World world, BlockPos pos) { - FluidState fluidState = world.getFluidState(pos); - FluidState fluidStateAbove = world.getFluidState(pos.up()); - if (fluidState.isOf(Fluids.WATER) && fluidStateAbove.isEmpty()) { - return fluidState.isStill(); - } - return false; - } } From eeb13e345ccc6e4415656064a467d24abc0eb963 Mon Sep 17 00:00:00 2001 From: Goby56 <60710855+Goby56@users.noreply.github.com> Date: Sat, 24 Aug 2024 10:02:50 +0200 Subject: [PATCH 4/4] cleanup + flood fill 2 flood fill 2 seems to work fine and cuts texturing time in half from what flood fill 3 did --- src/main/java/com/goby56/wakes/config/WakesConfig.java | 2 +- .../java/com/goby56/wakes/config/YACLIntegration.java | 2 +- src/main/java/com/goby56/wakes/debug/WakesDebugInfo.java | 9 +-------- src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java | 7 +++++-- .../com/goby56/wakes/render/SplashPlaneRenderer.java | 1 + src/main/java/com/goby56/wakes/render/WakeRenderer.java | 3 +-- .../java/com/goby56/wakes/simulation/WakeHandler.java | 2 -- 7 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/goby56/wakes/config/WakesConfig.java b/src/main/java/com/goby56/wakes/config/WakesConfig.java index 49358fe..bbcd790 100644 --- a/src/main/java/com/goby56/wakes/config/WakesConfig.java +++ b/src/main/java/com/goby56/wakes/config/WakesConfig.java @@ -37,7 +37,7 @@ public class WakesConfig { // Debug public boolean disableMod = false; - public int floodFillDistance = 3; + public int floodFillDistance = 2; public int ticksBeforeFill = 2; public boolean pickBoat = true; public RenderType renderType = RenderType.AUTO; diff --git a/src/main/java/com/goby56/wakes/config/YACLIntegration.java b/src/main/java/com/goby56/wakes/config/YACLIntegration.java index e2d075c..e5c2e97 100644 --- a/src/main/java/com/goby56/wakes/config/YACLIntegration.java +++ b/src/main/java/com/goby56/wakes/config/YACLIntegration.java @@ -117,7 +117,7 @@ public static Screen createScreen(Screen parent) { .enumClass(RenderType.class)) .build()) .option(optionOf(Integer.class, "flood_fill_distance", false) - .binding(3, () -> config.floodFillDistance, val -> config.floodFillDistance = val) + .binding(2, () -> config.floodFillDistance, val -> config.floodFillDistance = val) .controller(opt -> integerSlider(opt, 1, 5)) .build()) .option(optionOf(Integer.class, "ticks_before_fill", false) diff --git a/src/main/java/com/goby56/wakes/debug/WakesDebugInfo.java b/src/main/java/com/goby56/wakes/debug/WakesDebugInfo.java index 88e2fc9..a043668 100644 --- a/src/main/java/com/goby56/wakes/debug/WakesDebugInfo.java +++ b/src/main/java/com/goby56/wakes/debug/WakesDebugInfo.java @@ -7,9 +7,7 @@ public class WakesDebugInfo { public static double nodeLogicTime = 0; - public static double insertionTime = 0; public static double texturingTime = 0; - public static ArrayList cullingTime = new ArrayList<>(); public static ArrayList renderingTime = new ArrayList<>(); // Frames averaged each tick public static int quadsRendered = 0; public static int nodeCount = 0; @@ -17,19 +15,14 @@ public class WakesDebugInfo { public static void reset() { nodeCount = 0; nodeLogicTime = 0; - insertionTime = 0; texturingTime = 0; - cullingTime = new ArrayList<>(); renderingTime = new ArrayList<>(); } public static void show(CallbackInfoReturnable> info) { - int q = WakesDebugInfo.quadsRendered; - info.getReturnValue().add(String.format("[Wakes] Rendering %d quads for %d wake nodes", q, WakesDebugInfo.nodeCount)); + info.getReturnValue().add(String.format("[Wakes] Rendering %d quads for %d wake nodes", WakesDebugInfo.quadsRendered, WakesDebugInfo.nodeCount)); info.getReturnValue().add(String.format("[Wakes] Node logic: %.2fms/t", 10e-6 * WakesDebugInfo.nodeLogicTime)); - info.getReturnValue().add(String.format("[Wakes] Insertion: %.2fms/t", 10e-6 * WakesDebugInfo.insertionTime)); info.getReturnValue().add(String.format("[Wakes] Texturing: %.2fms/t", 10e-6 * WakesDebugInfo.texturingTime)); - info.getReturnValue().add(String.format("[Wakes] Culling: %.3fms/f", 10e-6 * WakesDebugInfo.cullingTime.stream().reduce(0L, Long::sum) / WakesDebugInfo.cullingTime.size())); info.getReturnValue().add(String.format("[Wakes] Rendering: %.3fms/f", 10e-6 * WakesDebugInfo.renderingTime.stream().reduce(0L, Long::sum) / WakesDebugInfo.renderingTime.size())); } } diff --git a/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java b/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java index f1f5e0c..cddc5cb 100644 --- a/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java +++ b/src/main/java/com/goby56/wakes/mixin/DebugHudMixin.java @@ -1,7 +1,6 @@ package com.goby56.wakes.mixin; import com.goby56.wakes.WakesClient; -import com.goby56.wakes.simulation.WakeHandler; import com.goby56.wakes.debug.WakesDebugInfo; import net.minecraft.client.gui.hud.DebugHud; import org.spongepowered.asm.mixin.Mixin; @@ -17,7 +16,11 @@ public abstract class DebugHudMixin { @Inject(at = @At("RETURN"), method = "getLeftText") protected void getLeftText(CallbackInfoReturnable> info) { if (WakesClient.CONFIG_INSTANCE.showDebugInfo) { - WakesDebugInfo.show(info); + if (WakesClient.CONFIG_INSTANCE.disableMod) { + info.getReturnValue().add("[Wakes] Mod disabled!"); + } else { + WakesDebugInfo.show(info); + } } } } \ No newline at end of file diff --git a/src/main/java/com/goby56/wakes/render/SplashPlaneRenderer.java b/src/main/java/com/goby56/wakes/render/SplashPlaneRenderer.java index e7f1eac..6f24b24 100644 --- a/src/main/java/com/goby56/wakes/render/SplashPlaneRenderer.java +++ b/src/main/java/com/goby56/wakes/render/SplashPlaneRenderer.java @@ -83,6 +83,7 @@ public static void render(T entity, float yaw, float tickDelt matrices.scale(scalar, scalar, scalar); Matrix4f matrix = matrices.peek().getPositionMatrix(); + // TODO MAKE SPLASH PLANE LOOK MORE LIKE WAKES (SIMULATE AND COLOR EACH PIXEL) Vector3f color = new Vector3f(); int waterCol = BiomeColors.getWaterColor(entity.getWorld(), entity.getBlockPos()); color.x = (float) (waterCol >> 16 & 0xFF) / 255f; diff --git a/src/main/java/com/goby56/wakes/render/WakeRenderer.java b/src/main/java/com/goby56/wakes/render/WakeRenderer.java index 835e5d6..c8c84ff 100644 --- a/src/main/java/com/goby56/wakes/render/WakeRenderer.java +++ b/src/main/java/com/goby56/wakes/render/WakeRenderer.java @@ -27,6 +27,7 @@ Resolution.THIRTYTWO, new WakeTexture(Resolution.THIRTYTWO.res) @Override public void afterTranslucent(WorldRenderContext context) { if (WakesClient.CONFIG_INSTANCE.disableMod) { + WakesDebugInfo.quadsRendered = 0; return; } @@ -35,9 +36,7 @@ public void afterTranslucent(WorldRenderContext context) { WakeHandler wakeHandler = WakeHandler.getInstance(); if (wakeHandler == null || wakeHandler.resolutionResetScheduled) return; - long tCulling = System.nanoTime(); ArrayList bricks = wakeHandler.getVisible(context.frustum(), Brick.class); - WakesDebugInfo.cullingTime.add(System.nanoTime() - tCulling); Matrix4f matrix = context.matrixStack().peek().getPositionMatrix(); RenderSystem.enableBlend(); diff --git a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java index 4ce1a33..dde8548 100644 --- a/src/main/java/com/goby56/wakes/simulation/WakeHandler.java +++ b/src/main/java/com/goby56/wakes/simulation/WakeHandler.java @@ -54,11 +54,9 @@ public void tick() { QuadTree tree = this.trees[i]; if (tree != null) { tree.tick(); - long tInsertion = System.nanoTime(); while (pendingNodes.peek() != null) { tree.insert(pendingNodes.poll()); } - WakesDebugInfo.insertionTime = System.nanoTime() - tInsertion; } } if (this.resolutionResetScheduled) {