From 4116336cd69a7b4e8c4d745b1986cf27b7bfb295 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 28 May 2025 19:02:01 -0400 Subject: [PATCH] region interface --- docs/src/progress/renderertodo.md | 1 + .../util/math/region/Region.java | 59 ++++++++++++ .../util/math/region/RegionPrism.java | 96 +++++++++++++++++++ .../util/math/region/RegionRectangular.java | 71 ++++++++++++++ 4 files changed, 227 insertions(+) create mode 100644 src/main/java/electrosphere/util/math/region/Region.java create mode 100644 src/main/java/electrosphere/util/math/region/RegionPrism.java create mode 100644 src/main/java/electrosphere/util/math/region/RegionRectangular.java diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d5322f1c..bd122b7d 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -2036,6 +2036,7 @@ Fix jobs data, simplify block chunk gen algo Convex y-aligned prism intersection checking Fix block LOD chunk rendering (scaling not applying) Scaffolding for laying out farm plots around towns +Region interface diff --git a/src/main/java/electrosphere/util/math/region/Region.java b/src/main/java/electrosphere/util/math/region/Region.java new file mode 100644 index 00000000..04fbcba9 --- /dev/null +++ b/src/main/java/electrosphere/util/math/region/Region.java @@ -0,0 +1,59 @@ +package electrosphere.util.math.region; + +import org.joml.AABBd; +import org.joml.Sphered; +import org.joml.Vector3d; + +/** + * A region of 3d space + */ +public interface Region { + + /** + * The type of selection + */ + public static enum RegionType { + /** + * A rectangle + */ + RECTANGULAR, + /** + * A y-aligned prism + */ + Y_ALIGNED_PRISM, + } + + /** + * Gets the type of region + * @return The type of region + */ + public RegionType getType(); + + /** + * Checks if the region contains a point + * @param point The point + * @return true if it contains the point, false otherwise + */ + public boolean intersects(Vector3d point); + + /** + * Checks if this region intersects another region + * @param other The other region + * @return true if one intersects another, false otherwise + */ + public boolean intersects(Region other); + + /** + * Checks if this region intersects a sphere + * @param sphere The sphere to check + * @return true if intersects the sphere, false otherwise + */ + public boolean intersects(Sphered sphere); + + /** + * Gets the axis-aligned bounding box for the region + * @return The axis-aligned bounding box + */ + public AABBd getAABB(); + +} diff --git a/src/main/java/electrosphere/util/math/region/RegionPrism.java b/src/main/java/electrosphere/util/math/region/RegionPrism.java new file mode 100644 index 00000000..c9285bb3 --- /dev/null +++ b/src/main/java/electrosphere/util/math/region/RegionPrism.java @@ -0,0 +1,96 @@ +package electrosphere.util.math.region; + +import org.joml.AABBd; +import org.joml.Sphered; +import org.joml.Vector3d; + +import electrosphere.util.math.GeomUtils; + +/** + * A prism region + */ +public class RegionPrism implements Region { + + + /** + * The height of the prism + */ + private double height; + + /** + * The points that make up the base polygon of the prism + */ + private Vector3d[] points; + + /** + * The aabb for the prism + */ + private AABBd aabb; + + /** + * Private constructor + */ + private RegionPrism(){ } + + /** + * Creates a prism region + * @param points The points that define the base polygon of the prism + * @param height The height of the prism + * @return The region + */ + public static RegionPrism create(Vector3d[] points, double height){ + RegionPrism rVal = new RegionPrism(); + rVal.height = height; + rVal.points = points; + //compute aabb + rVal.aabb = new AABBd(points[0].x,points[0].y,points[0].z,points[0].x,points[0].y,points[0].z); + for(int i = 1; i < points.length; i++){ + if(rVal.aabb.minX > points[i].x){ + rVal.aabb.minX = points[i].x; + } + if(rVal.aabb.minX > points[i].y){ + rVal.aabb.minX = points[i].y; + } + if(rVal.aabb.minX > points[i].z){ + rVal.aabb.minX = points[i].z; + } + if(rVal.aabb.maxX < points[i].x){ + rVal.aabb.maxX = points[i].x; + } + if(rVal.aabb.maxX < points[i].y){ + rVal.aabb.maxX = points[i].y; + } + if(rVal.aabb.maxX < points[i].z){ + rVal.aabb.maxX = points[i].z; + } + } + return rVal; + } + + @Override + public RegionType getType() { + return RegionType.Y_ALIGNED_PRISM; + } + + @Override + public boolean intersects(Vector3d point) { + return GeomUtils.pointIntersectsConvexPrism(point,points,height); + } + + @Override + public boolean intersects(Region other) { + throw new UnsupportedOperationException("Unimplemented method 'intersects'"); + } + + @Override + public boolean intersects(Sphered sphere) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'intersects'"); + } + + @Override + public AABBd getAABB() { + return this.aabb; + } + +} diff --git a/src/main/java/electrosphere/util/math/region/RegionRectangular.java b/src/main/java/electrosphere/util/math/region/RegionRectangular.java new file mode 100644 index 00000000..4aaf5582 --- /dev/null +++ b/src/main/java/electrosphere/util/math/region/RegionRectangular.java @@ -0,0 +1,71 @@ +package electrosphere.util.math.region; + +import org.joml.AABBd; +import org.joml.Sphered; +import org.joml.Vector3d; + +/** + * A rectangular region + */ +public class RegionRectangular implements Region { + + /** + * The AABB of the area selection + */ + private AABBd aabb; + + /** + * Private constructor + */ + private RegionRectangular(){ } + + /** + * Creates a rectangular selection + * @param start The start point + * @param end The end point + * @return The selection + */ + public static RegionRectangular create(Vector3d start, Vector3d end){ + if(start.x > end.x){ + throw new Error("Start x is less than end x! " + start.x + " " + end.x); + } + if(start.y > end.y){ + throw new Error("Start y is less than end y! " + start.y + " " + end.y); + } + if(start.z > end.z){ + throw new Error("Start y is less than end y! " + start.z + " " + end.z); + } + RegionRectangular rVal = new RegionRectangular(); + rVal.aabb = new AABBd(start, end); + return rVal; + } + + @Override + public RegionType getType() { + return RegionType.RECTANGULAR; + } + + @Override + public boolean intersects(Vector3d point) { + return aabb.testPoint(point); + } + + @Override + public boolean intersects(Region other) { + if(other.getType() != RegionType.RECTANGULAR){ + throw new Error("One of the areas to test is not rectangular! " + other.getType()); + } + return aabb.testAABB(other.getAABB()); + } + + @Override + public boolean intersects(Sphered sphere) { + return aabb.testSphere(sphere.x, sphere.y, sphere.z, sphere.r); + } + + @Override + public AABBd getAABB() { + return this.aabb; + } + +}