From b5ad377147c59405d3dd27607ef0e75af6e36659 Mon Sep 17 00:00:00 2001 From: OreCruncher Date: Fri, 20 Dec 2024 09:35:05 -0800 Subject: [PATCH] Cuboid => BlockBox --- .../lib/scanner/ComplementsPointIterator.java | 11 ++- .../dsurround/lib/scanner/Cuboid.java | 96 ++++++------------- .../lib/scanner/CuboidPointIterator.java | 30 ------ .../dsurround/lib/scanner/CuboidScanner.java | 25 ++--- 4 files changed, 48 insertions(+), 114 deletions(-) diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/ComplementsPointIterator.java b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/ComplementsPointIterator.java index b2ce735b..de18481e 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/ComplementsPointIterator.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/ComplementsPointIterator.java @@ -1,5 +1,6 @@ package org.orecruncher.dsurround.lib.scanner; +import net.minecraft.core.BlockBox; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.Nullable; @@ -9,7 +10,7 @@ public class ComplementsPointIterator implements IPointIterator { protected int activeSegment = 0; protected BlockPos peeked = null; - public ComplementsPointIterator(final Cuboid volume, final Cuboid intersect) { + public ComplementsPointIterator(final BlockBox volume, final BlockBox intersect) { // This function makes some important assumptions about volume and // intersect: // 1) Intersect is completely contained within volume @@ -28,10 +29,10 @@ public ComplementsPointIterator(final Cuboid volume, final Cuboid intersect) { // ComplementsPointIterator(newVolume,intersect); // - final BlockPos vmax = volume.maximum(); - final BlockPos imax = intersect.maximum(); - final BlockPos vmin = volume.minimum(); - final BlockPos imin = intersect.minimum(); + final BlockPos vmax = volume.max(); + final BlockPos imax = intersect.max(); + final BlockPos vmin = volume.min(); + final BlockPos imin = intersect.min(); if (vmax.getX() != imax.getX() || vmin.getX() != imin.getX()) { if (vmax.getX() > imax.getX()) diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/Cuboid.java b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/Cuboid.java index cccf4b58..8fa5d0a3 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/Cuboid.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/Cuboid.java @@ -1,85 +1,47 @@ package org.orecruncher.dsurround.lib.scanner; +import net.minecraft.core.BlockBox; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.Nullable; public final class Cuboid { - private final int minX; - private final int minY; - private final int minZ; - private final int maxX; - private final int maxY; - private final int maxZ; - - public Cuboid(final BlockPos[] points) { - this(points[0], points[1]); - } - - public Cuboid(final BlockPos vx1, final BlockPos vx2) { - this(Math.min(vx1.getX(), vx2.getX()), - Math.min(vx1.getY(), vx2.getY()), - Math.min(vx1.getZ(), vx2.getZ()), - Math.max(vx1.getX(), vx2.getX()), - Math.max(vx1.getY(), vx2.getY()), - Math.max(vx1.getZ(), vx2.getZ())); - } - - public Cuboid(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - this.minX = minX; - this.minY = minY; - this.minZ = minZ; - this.maxX = maxX; - this.maxY = maxY; - this.maxZ = maxZ; - } - - public boolean contains(final BlockPos p) { - return p.getX() >= this.minX && p.getX() <= this.maxX - && p.getY() >= this.minY && p.getY() <= this.maxY - && p.getZ() >= this.minZ && p.getZ() <= this.maxZ; + public static BlockBox of(BlockPos[] points) { + return of(points[0], points[1]); } - public BlockPos maximum() { - return new BlockPos(this.maxX, this.maxY, this.maxZ); + public static BlockBox of(BlockPos pos1, BlockPos pos2) { + return BlockBox.of(pos1, pos2); } - public BlockPos minimum() { - return new BlockPos(this.minX, this.minY, this.minZ); - } - - public long volume() { - var x = Math.abs(this.maxX - this.minX); - var y = Math.abs(this.maxY - this.minY); - var z = Math.abs(this.maxZ - this.minZ); - return (long) x * y * z; - } - - public boolean intersects(Cuboid o) { - return this.minX <= o.maxX - && this.maxX >= o.minX - && this.minY <= o.maxY - && this.maxY >= o.minY - && this.minZ <= o.maxZ - && this.maxZ >= o.minZ; + public static boolean intersects(BlockBox box1, BlockBox box2) { + var meMin = box1.min(); + var meMax = box1.max(); + var oMin = box2.min(); + var oMax = box2.max(); + return meMin.getX() <= oMax.getX() + && meMax.getX() >= oMin.getX() + && meMin.getY() <= oMax.getY() + && meMax.getY() >= oMin.getY() + && meMin.getZ() <= oMax.getZ() + && meMax.getZ() >= oMin.getZ(); } @Nullable - public Cuboid intersection(Cuboid o) { - if (this.intersects(o)) { - int minX = Math.max(this.minX, o.minX); - int minY = Math.max(this.minY, o.minY); - int minZ = Math.max(this.minZ, o.minZ); - int maxX = Math.min(this.maxX, o.maxX); - int maxY = Math.min(this.maxY, o.maxY); - int maxZ = Math.min(this.maxZ, o.maxZ); - return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ); + public static BlockBox intersection(BlockBox box1, BlockBox box2) { + if (intersects(box1, box2)) { + var meMin = box1.min(); + var meMax = box1.max(); + var oMin = box2.min(); + var oMax = box2.max(); + int minX = Math.max(meMin.getX(), oMin.getX()); + int minY = Math.max(meMin.getY(), oMin.getY()); + int minZ = Math.max(meMin.getZ(), oMin.getZ()); + int maxX = Math.min(meMax.getX(), oMax.getX()); + int maxY = Math.min(meMax.getY(), oMax.getY()); + int maxZ = Math.min(meMax.getZ(), oMax.getZ()); + return new BlockBox(new BlockPos(minX, minY, minZ), new BlockPos(maxX, maxY, maxZ)); } return null; } - - @Override - public String toString() { - return "Cuboid{min=(%d,%d,%d),max=(%d,%d,%d),volume=%d}".formatted(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ, this.volume()); - } } \ No newline at end of file diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidPointIterator.java b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidPointIterator.java index 22eec7cb..8d34a4ec 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidPointIterator.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidPointIterator.java @@ -1,6 +1,5 @@ package org.orecruncher.dsurround.lib.scanner; -import com.google.common.collect.AbstractIterator; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.Nullable; @@ -35,7 +34,6 @@ public CuboidPointIterator(final BlockPos[] points) { public CuboidPointIterator(final BlockPos p1, final BlockPos p2) { this.itr = BlockPos.betweenClosed(p1, p2).iterator(); - //this.itr = iterateCuboid(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ()).iterator(); this.peeked = this.itr.next(); } @@ -52,32 +50,4 @@ public BlockPos next() { public BlockPos peek() { return this.peeked; } - - /** - * Customized cube iterator that favors iterating x, z, and then y as to maximize on CPU cache hits when - * traversing the cube. - */ - private static Iterable iterateCuboid(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - int length = maxX - minX + 1; - int height = maxY - minY + 1; - int width = maxZ - minZ + 1; - int volume = length * height * width; - return () -> new AbstractIterator<>() { - private final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); - private int index; - - protected BlockPos computeNext() { - if (this.index == volume) { - return this.endOfData(); - } else { - int dX = this.index % length; - int jx = this.index / length; - int dZ = jx % width; - int dY = jx / width; - ++this.index; - return this.pos.set(minX + dX, minY + dY, minZ + dZ); - } - } - }; - } } \ No newline at end of file diff --git a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidScanner.java b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidScanner.java index 6d283cde..e2137ca6 100644 --- a/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidScanner.java +++ b/common/src/main/java/org/orecruncher/dsurround/lib/scanner/CuboidScanner.java @@ -1,5 +1,6 @@ package org.orecruncher.dsurround.lib.scanner; +import net.minecraft.core.BlockBox; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; @@ -14,7 +15,7 @@ public abstract class CuboidScanner extends Scanner { // Iteration variables protected boolean scanFinished = false; - protected Cuboid activeCuboid; + protected BlockBox activeCuboid; protected CuboidPointIterator fullRange; // State of last tick @@ -39,9 +40,9 @@ protected BlockPos[] getMinMaxPointsForVolume(final BlockPos pos) { return new BlockPos[]{min, max}; } - protected Cuboid getVolumeFor(final BlockPos pos) { + protected BlockBox getVolumeFor(final BlockPos pos) { final BlockPos[] points = getMinMaxPointsForVolume(pos); - return new Cuboid(points); + return Cuboid.of(points); } @Override @@ -59,7 +60,7 @@ public void resetFullScan() { this.scanFinished = false; final BlockPos[] points = getMinMaxPointsForVolume(this.lastPos); - this.activeCuboid = new Cuboid(points); + this.activeCuboid = Cuboid.of(points); this.fullRange = new CuboidPointIterator(points); } @@ -83,14 +84,14 @@ public void tick() { super.tick(); } else { // The player moved. - final Cuboid oldVolume = this.activeCuboid != null ? this.activeCuboid : getVolumeFor(this.lastPos); - final Cuboid newVolume = getVolumeFor(playerPos); - final Cuboid intersect = oldVolume.intersection(newVolume); + final BlockBox oldVolume = this.activeCuboid != null ? this.activeCuboid : getVolumeFor(this.lastPos); + final BlockBox newVolume = getVolumeFor(playerPos); + final BlockBox intersect = Cuboid.intersection(oldVolume, newVolume); // If there is no intersection, it means the player moved // enough of a distance in the last tick to make it a new - // area. Otherwise, if there is a sufficiently large - // change to the scan area dump and restart. + // area, otherwise, if there is a large enough change to + // the scan area dump and restart. if (intersect == null) { this.locus.getLogger().debug("[%s] no intersection: %s, %s", this.name, oldVolume.toString(), newVolume.toString()); resetFullScan(); @@ -107,7 +108,7 @@ public void tick() { // The existing scan hasn't completed, but now we // have a delta set. Finish out scanning the // old volume, and once that is locked, then a - // subsequent tick will do a delta update to get + // later tick will do a delta update to get // the new blocks. super.tick(); } @@ -130,8 +131,8 @@ public void blockUnscan(final Level world, final BlockState state, final BlockPo } - protected void updateScan(final Cuboid newVolume, final Cuboid oldVolume, - final Cuboid intersect) { + protected void updateScan(final BlockBox newVolume, final BlockBox oldVolume, + final BlockBox intersect) { var provider = this.locus.getWorld();