From 732e0c51e9700b655e1e6a97d5aa05f54e098b23 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 28 May 2025 19:26:35 -0400 Subject: [PATCH] prism meshgen + farmplot gen --- docs/src/progress/renderertodo.md | 2 + .../renderer/meshgen/GeometryMeshGen.java | 148 ++++++++++++++++++ .../electrosphere/server/macro/town/Town.java | 22 +++ .../server/macro/town/TownLayout.java | 14 +- 4 files changed, 185 insertions(+), 1 deletion(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index bd122b7d..789da4bb 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -2037,6 +2037,8 @@ Convex y-aligned prism intersection checking Fix block LOD chunk rendering (scaling not applying) Scaffolding for laying out farm plots around towns Region interface +Town layout non-statically generates farm plots +Y-aligned prism meshgen diff --git a/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java index c9de67a1..e61c89de 100644 --- a/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java +++ b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java @@ -6,6 +6,7 @@ import java.util.LinkedList; import java.util.List; import org.joml.Vector2f; +import org.joml.Vector3d; import org.joml.Vector3f; import org.lwjgl.BufferUtils; @@ -277,4 +278,151 @@ public class GeometryMeshGen { return mesh; } + /** + * Generates a prism mesh + * @param points The points of the base of the prism + * @param height The height of the prism + * @return The mesh of the prism + */ + public static Mesh genPrism(Vector3d[] points, double height){ + //error check + if(points.length < 3){ + throw new Error("Invalid number of points! " + points.length); + } + + //allocate top level objects + Mesh mesh = new Mesh("prism"); + OpenGLState openGLState = Globals.renderingEngine.getOpenGLState(); + mesh.generateVAO(openGLState); + + //calculate centerpoint + Vector3d centerpoint = new Vector3d(points[0]); + for(int i = 1; i < points.length; i++){ + centerpoint = centerpoint.add(points[i]); + centerpoint = centerpoint.mul(1.0f / (float)points.length); + } + + + //allocate buffers + FloatBuffer vertBuffer = BufferUtils.createFloatBuffer((points.length + 2) * 2 * 3); + FloatBuffer normalBuffer = BufferUtils.createFloatBuffer((points.length + 2) * 2 * 3); + FloatBuffer uvBuffer = BufferUtils.createFloatBuffer((points.length + 2) * 2 * 2); + IntBuffer faceBuffer = BufferUtils.createIntBuffer(points.length * 12); + + + // + //add data for center point + // + vertBuffer.put((float)centerpoint.x); + vertBuffer.put((float)centerpoint.y); + vertBuffer.put((float)centerpoint.z); + vertBuffer.put((float)centerpoint.x); + vertBuffer.put((float)(centerpoint.y + height)); + vertBuffer.put((float)centerpoint.z); + normalBuffer.put(0f); + normalBuffer.put(-1f); + normalBuffer.put(0f); + normalBuffer.put(0f); + normalBuffer.put(11f); + normalBuffer.put(0f); + uvBuffer.put(0); + uvBuffer.put(0); + uvBuffer.put(0); + uvBuffer.put(0); + + + // + //iterate along points + // + for(int i = 0; i < points.length - 1; i++){ + Vector3d point1 = points[i]; + //add vert data + vertBuffer.put((float)point1.x); + vertBuffer.put((float)point1.y); + vertBuffer.put((float)point1.z); + vertBuffer.put((float)point1.x); + vertBuffer.put((float)(point1.y + height)); + vertBuffer.put((float)point1.z); + normalBuffer.put(0f); + normalBuffer.put(-1f); + normalBuffer.put(0f); + normalBuffer.put(0f); + normalBuffer.put(11f); + normalBuffer.put(0f); + uvBuffer.put(1); + uvBuffer.put(1); + uvBuffer.put(1); + uvBuffer.put(1); + //add face data + //bottom triangle + faceBuffer.put(0); + faceBuffer.put(((i + 0) * 2) + 0); + faceBuffer.put(((i + 1) * 2) + 0); + //top triangle + faceBuffer.put(1); + faceBuffer.put(((i + 0) * 2) + 1); + faceBuffer.put(((i + 1) * 2) + 1); + //perimeter face 1 + faceBuffer.put(((i + 0) * 2) + 0); + faceBuffer.put(((i + 1) * 2) + 0); + faceBuffer.put(((i + 0) * 2) + 1); + //perimeter face 2 + faceBuffer.put(((i + 1) * 2) + 0); + faceBuffer.put(((i + 0) * 2) + 1); + faceBuffer.put(((i + 1) * 2) + 1); + } + + // + //Handle wrap-around + // + Vector3d lastPoint = points[points.length - 1]; + vertBuffer.put((float)lastPoint.x); + vertBuffer.put((float)lastPoint.y); + vertBuffer.put((float)lastPoint.z); + vertBuffer.put((float)lastPoint.x); + vertBuffer.put((float)(lastPoint.y + height)); + vertBuffer.put((float)lastPoint.z); + normalBuffer.put(0f); + normalBuffer.put(-1f); + normalBuffer.put(0f); + normalBuffer.put(0f); + normalBuffer.put(11f); + normalBuffer.put(0f); + uvBuffer.put(1); + uvBuffer.put(1); + uvBuffer.put(1); + uvBuffer.put(1); + + + + //actually store in mesh + int elementCount = points.length * 12; + try { + //actually buffer vertices + if(vertBuffer.position() > 0){ + vertBuffer.flip(); + mesh.bufferVertices(vertBuffer, 3); + } + //actually buffer normals + if(normalBuffer != null && normalBuffer.position() > 0){ + normalBuffer.flip(); + mesh.bufferNormals(normalBuffer, 3); + } + //actually buffer UVs + if(uvBuffer != null && uvBuffer.position() > 0){ + uvBuffer.flip(); + mesh.bufferTextureCoords(uvBuffer, 2); + } + //buffer element indices + if(faceBuffer.position() > 0){ + faceBuffer.flip(); + mesh.bufferFaces(faceBuffer, elementCount); + } + } catch (NullPointerException ex){ + ex.printStackTrace(); + } + + return mesh; + } + } diff --git a/src/main/java/electrosphere/server/macro/town/Town.java b/src/main/java/electrosphere/server/macro/town/Town.java index 1aac1e85..13fc4213 100644 --- a/src/main/java/electrosphere/server/macro/town/Town.java +++ b/src/main/java/electrosphere/server/macro/town/Town.java @@ -7,6 +7,7 @@ import electrosphere.server.macro.civilization.Civilization; import electrosphere.server.macro.spatial.MacroAreaObject; import electrosphere.server.macro.spatial.MacroLODObject; import electrosphere.server.macro.structure.VirtualStructure; +import electrosphere.util.math.region.Region; import java.util.LinkedList; import java.util.List; @@ -70,6 +71,11 @@ public class Town implements MacroAreaObject, MacroLODObject { */ private List jobs = new LinkedList(); + /** + * The list of farm plot regions + */ + private List farmPlots = new LinkedList(); + /** * The id of the parent civilization */ @@ -131,6 +137,22 @@ public class Town implements MacroAreaObject, MacroLODObject { return residents.stream().map((Integer id) -> Globals.serverState.characterService.getCharacter(id)).filter((Character chara) -> chara != null).collect(Collectors.toList()); } + /** + * Gets the farm plots in the town + * @return The list of farm plots + */ + public List getFarmPlots(){ + return farmPlots; + } + + /** + * Adds a farm plot region + * @param farmPlotRegion The region for the farm plot + */ + public void addFarmPlot(Region farmPlotRegion){ + this.farmPlots.add(farmPlotRegion); + } + /** * Adds a job to the town * @param job The job diff --git a/src/main/java/electrosphere/server/macro/town/TownLayout.java b/src/main/java/electrosphere/server/macro/town/TownLayout.java index 46b2a4f6..a02c6cca 100644 --- a/src/main/java/electrosphere/server/macro/town/TownLayout.java +++ b/src/main/java/electrosphere/server/macro/town/TownLayout.java @@ -21,6 +21,7 @@ import electrosphere.server.macro.race.Race; import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.util.math.HashUtils; import electrosphere.util.math.VoronoiUtils; +import electrosphere.util.math.region.RegionPrism; /** * Lays out town objects @@ -52,6 +53,11 @@ public class TownLayout { */ private static final int HASH_OFFSET = 1000; + /** + * Default height of a farm plot + */ + private static final float FARM_PLOT_DEFAULT_HEIGHT = 20.0f; + /** * Offset used to search for town centers */ @@ -406,7 +412,13 @@ public class TownLayout { * @param point4 The fourth point */ private static void generateFarmPlot(Realm realm, Town town, Vector3d point1, Vector3d point2, Vector3d point3, Vector3d point4){ - + RegionPrism region = RegionPrism.create(new Vector3d[]{ + new Vector3d(point1).add(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0), + new Vector3d(point2).add(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0), + new Vector3d(point3).add(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0), + new Vector3d(point4).add(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0), + }, FARM_PLOT_DEFAULT_HEIGHT); + town.addFarmPlot(region); } /**