fix prism meshgen + farm plot geom
This commit is contained in:
parent
732e0c51e9
commit
6b335310e8
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Wed May 28 11:59:04 EDT 2025
|
||||
buildNumber=639
|
||||
#Wed May 28 21:00:17 EDT 2025
|
||||
buildNumber=643
|
||||
|
||||
@ -2039,6 +2039,8 @@ Scaffolding for laying out farm plots around towns
|
||||
Region interface
|
||||
Town layout non-statically generates farm plots
|
||||
Y-aligned prism meshgen
|
||||
Rendering prism regions
|
||||
Utilities for turning mesh gen algos into renderable entities
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3,13 +3,20 @@ package electrosphere.entity;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import electrosphere.data.entity.graphics.NonproceduralModel;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.queue.QueuedModel;
|
||||
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||
import electrosphere.renderer.RenderUtils;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.renderer.model.Mesh;
|
||||
|
||||
/**
|
||||
* Utilities to manipulating drawable entities (eg making an entity transparent)
|
||||
@ -96,4 +103,26 @@ public class DrawableUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an entity drawable with a mesh to be generated via a callback
|
||||
* @param entity The entity
|
||||
* @param meshGenerator The callback to generate a mesh
|
||||
*/
|
||||
public static void makeEntityDrawable(Entity entity, Callable<Mesh> meshGenerator){
|
||||
QueuedModel model = new QueuedModel(() -> {
|
||||
Mesh mesh = meshGenerator.call();
|
||||
return RenderUtils.wrapMeshInModel(mesh);
|
||||
});
|
||||
String path = Globals.assetManager.queuedAsset(model);
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(path));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||
Globals.clientState.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
||||
Globals.clientState.clientScene.registerEntityToTag(entity, EntityTags.DRAW_VOLUMETIC_SOLIDS_PASS);
|
||||
Globals.clientState.clientScene.registerEntityToTag(entity, EntityTags.DRAW_CAST_SHADOW);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -630,6 +630,19 @@ public class RenderUtils {
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a mesh in a model
|
||||
* @param mesh The mesh
|
||||
* @return The model that wraps the mesh
|
||||
*/
|
||||
public static Model wrapMeshInModel(Mesh mesh){
|
||||
Model model = new Model();
|
||||
//setup extra structures
|
||||
mesh.setParent(model);
|
||||
model.getMeshes().add(mesh);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static Model createBitmapDisplay(){
|
||||
|
||||
@ -20,6 +20,11 @@ public class ActorUtils {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an actor from an already-loading path
|
||||
* @param modelPath The path
|
||||
* @return The actor
|
||||
*/
|
||||
public static Actor createActorOfLoadingModel(String modelPath){
|
||||
Actor rVal = new Actor(modelPath);
|
||||
return rVal;
|
||||
|
||||
@ -299,8 +299,8 @@ public class GeometryMeshGen {
|
||||
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);
|
||||
}
|
||||
centerpoint = centerpoint.mul(1.0f / (float)points.length);
|
||||
|
||||
|
||||
//allocate buffers
|
||||
@ -323,7 +323,7 @@ public class GeometryMeshGen {
|
||||
normalBuffer.put(-1f);
|
||||
normalBuffer.put(0f);
|
||||
normalBuffer.put(0f);
|
||||
normalBuffer.put(11f);
|
||||
normalBuffer.put(1f);
|
||||
normalBuffer.put(0f);
|
||||
uvBuffer.put(0);
|
||||
uvBuffer.put(0);
|
||||
@ -353,23 +353,31 @@ public class GeometryMeshGen {
|
||||
uvBuffer.put(1);
|
||||
uvBuffer.put(1);
|
||||
uvBuffer.put(1);
|
||||
int p1index = ((i + 0) * 2) + 2;
|
||||
int p2index = ((i + 0) * 2) + 3;
|
||||
int p3index = ((i + 1) * 2) + 2;
|
||||
int p4index = ((i + 1) * 2) + 3;
|
||||
//add face data
|
||||
//bottom triangle
|
||||
faceBuffer.put(0);
|
||||
faceBuffer.put(((i + 0) * 2) + 0);
|
||||
faceBuffer.put(((i + 1) * 2) + 0);
|
||||
faceBuffer.put(p1index);
|
||||
faceBuffer.put(p3index);
|
||||
//top triangle
|
||||
faceBuffer.put(1);
|
||||
faceBuffer.put(((i + 0) * 2) + 1);
|
||||
faceBuffer.put(((i + 1) * 2) + 1);
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p4index);
|
||||
//perimeter face 1
|
||||
faceBuffer.put(((i + 0) * 2) + 0);
|
||||
faceBuffer.put(((i + 1) * 2) + 0);
|
||||
faceBuffer.put(((i + 0) * 2) + 1);
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p1index);
|
||||
faceBuffer.put(p3index);
|
||||
//perimeter face 2
|
||||
faceBuffer.put(((i + 1) * 2) + 0);
|
||||
faceBuffer.put(((i + 0) * 2) + 1);
|
||||
faceBuffer.put(((i + 1) * 2) + 1);
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p3index);
|
||||
faceBuffer.put(p4index);
|
||||
// System.out.println(p2index + "--" + p4index);
|
||||
// System.out.println("|\\ |");
|
||||
// System.out.println("| \\|");
|
||||
// System.out.println(p1index + "--" + p3index);
|
||||
}
|
||||
|
||||
//
|
||||
@ -392,11 +400,31 @@ public class GeometryMeshGen {
|
||||
uvBuffer.put(1);
|
||||
uvBuffer.put(1);
|
||||
uvBuffer.put(1);
|
||||
//add face data
|
||||
int p1index = (3 * 2) + 2;
|
||||
int p2index = (3 * 2) + 3;
|
||||
int p3index = (0 * 2) + 2;
|
||||
int p4index = (0 * 2) + 3;
|
||||
//bottom triangle
|
||||
faceBuffer.put(0);
|
||||
faceBuffer.put(p1index);
|
||||
faceBuffer.put(p3index);
|
||||
//top triangle
|
||||
faceBuffer.put(1);
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p4index);
|
||||
//perimeter face 1
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p1index);
|
||||
faceBuffer.put(p3index);
|
||||
//perimeter face 2
|
||||
faceBuffer.put(p2index);
|
||||
faceBuffer.put(p3index);
|
||||
faceBuffer.put(p4index);
|
||||
|
||||
|
||||
|
||||
//actually store in mesh
|
||||
int elementCount = points.length * 12;
|
||||
try {
|
||||
//actually buffer vertices
|
||||
if(vertBuffer.position() > 0){
|
||||
@ -404,19 +432,19 @@ public class GeometryMeshGen {
|
||||
mesh.bufferVertices(vertBuffer, 3);
|
||||
}
|
||||
//actually buffer normals
|
||||
if(normalBuffer != null && normalBuffer.position() > 0){
|
||||
if(normalBuffer.position() > 0){
|
||||
normalBuffer.flip();
|
||||
mesh.bufferNormals(normalBuffer, 3);
|
||||
}
|
||||
//actually buffer UVs
|
||||
if(uvBuffer != null && uvBuffer.position() > 0){
|
||||
if(uvBuffer.position() > 0){
|
||||
uvBuffer.flip();
|
||||
mesh.bufferTextureCoords(uvBuffer, 2);
|
||||
}
|
||||
//buffer element indices
|
||||
if(faceBuffer.position() > 0){
|
||||
faceBuffer.flip();
|
||||
mesh.bufferFaces(faceBuffer, elementCount);
|
||||
mesh.bufferFaces(faceBuffer, faceBuffer.limit());
|
||||
}
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
|
||||
@ -456,6 +456,9 @@ public class Mesh {
|
||||
if(selectedProgram == null){
|
||||
selectedProgram = shader;
|
||||
}
|
||||
if(selectedProgram == null){
|
||||
selectedProgram = Globals.defaultMeshShader;
|
||||
}
|
||||
openGLState.setActiveShader(renderPipelineState, selectedProgram);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -29,7 +29,10 @@ import electrosphere.data.entity.common.CommonEntityType;
|
||||
import electrosphere.data.entity.grident.GridAlignedData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.DrawableUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
@ -39,6 +42,7 @@ import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.renderer.meshgen.GeometryMeshGen;
|
||||
import electrosphere.renderer.model.Model;
|
||||
import electrosphere.renderer.pipelines.RenderPipeline;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
@ -47,6 +51,8 @@ import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.macro.civilization.road.Road;
|
||||
import electrosphere.server.macro.structure.VirtualStructure;
|
||||
import electrosphere.util.math.SpatialMathUtils;
|
||||
import electrosphere.util.math.region.Region;
|
||||
import electrosphere.util.math.region.RegionPrism;
|
||||
|
||||
/**
|
||||
* Pipeline for rendering content to assist debugging
|
||||
@ -56,6 +62,11 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
//The bone debugging pipeline
|
||||
DebugBonesPipeline debugBonesPipeline = new DebugBonesPipeline();
|
||||
|
||||
/**
|
||||
* The farm plot macro data entities to draw
|
||||
*/
|
||||
private List<Entity> farmPlotEntities = new LinkedList<Entity>();
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("DebugContentPipeline.render");
|
||||
@ -210,6 +221,31 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
for(Road road : Globals.serverState.realmManager.first().getMacroData().getRoads()){
|
||||
DebugContentPipeline.renderTube(openGLState, renderPipelineState, modelTransformMatrix, road.getPoint1(), road.getPoint2(), road.getRadius(), AssetDataStrings.TEXTURE_BLUE_TRANSPARENT);
|
||||
}
|
||||
if(this.farmPlotEntities.isEmpty()){
|
||||
if(Globals.serverState.realmManager.first().getMacroData().getTown(0).getFarmPlots().size() > 0){
|
||||
for(Region region : Globals.serverState.realmManager.first().getMacroData().getTown(0).getFarmPlots()){
|
||||
if(region instanceof RegionPrism prism){
|
||||
Entity plotDebugEnt = EntityCreationUtils.createClientSpatialEntity();
|
||||
DrawableUtils.makeEntityDrawable(plotDebugEnt, () -> {
|
||||
Vector3d[] finalPoints = new Vector3d[prism.getPoints().length];
|
||||
for(int i = 0; i < finalPoints.length; i++){
|
||||
finalPoints[i] = new Vector3d(prism.getPoints()[i]).sub(prism.getAABB().minX,prism.getAABB().minY,prism.getAABB().minZ);
|
||||
}
|
||||
return GeometryMeshGen.genPrism(finalPoints, prism.getHeight());
|
||||
});
|
||||
EntityUtils.getPosition(plotDebugEnt).set(prism.getAABB().minX,prism.getAABB().minY,prism.getAABB().minZ);
|
||||
this.farmPlotEntities.add(plotDebugEnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(!this.farmPlotEntities.isEmpty()){
|
||||
for(Entity entity : this.farmPlotEntities){
|
||||
ClientEntityUtils.destroyEntity(entity);
|
||||
}
|
||||
this.farmPlotEntities.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@ -272,11 +272,11 @@ public class TownLayout {
|
||||
//this is +0,+0
|
||||
plotPoint1.set(currPoint);
|
||||
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * (x + 1),0,TOWN_LAYOUT_SCALER * (z + 0));
|
||||
plotPoint2.set(scanPoint);
|
||||
plotPoint2 = TownLayout.getTownCenter(realm, scanPoint);
|
||||
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * (x + 1),0,TOWN_LAYOUT_SCALER * (z + 1));
|
||||
plotPoint3.set(scanPoint);
|
||||
plotPoint3 = TownLayout.getTownCenter(realm, scanPoint);
|
||||
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * (x + 0),0,TOWN_LAYOUT_SCALER * (z + 1));
|
||||
plotPoint4.set(scanPoint);
|
||||
plotPoint4 = TownLayout.getTownCenter(realm, scanPoint);
|
||||
if(
|
||||
plotPoint1.distance(townCenter) > TOWN_CENTER_RADIUS &&
|
||||
plotPoint2.distance(townCenter) > TOWN_CENTER_RADIUS &&
|
||||
@ -284,6 +284,9 @@ public class TownLayout {
|
||||
plotPoint4.distance(townCenter) > TOWN_CENTER_RADIUS
|
||||
){
|
||||
plotPoint1.y = realm.getServerWorldData().getServerTerrainManager().getElevation(plotPoint1);
|
||||
plotPoint2.y = plotPoint1.y;
|
||||
plotPoint3.y = plotPoint1.y;
|
||||
plotPoint4.y = plotPoint1.y;
|
||||
//define a farm plot with these points
|
||||
TownLayout.generateFarmPlot(realm,town,plotPoint1,plotPoint2,plotPoint3,plotPoint4);
|
||||
}
|
||||
@ -413,10 +416,10 @@ public class TownLayout {
|
||||
*/
|
||||
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),
|
||||
new Vector3d(point1).sub(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0),
|
||||
new Vector3d(point2).sub(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0),
|
||||
new Vector3d(point3).sub(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0),
|
||||
new Vector3d(point4).sub(0,FARM_PLOT_DEFAULT_HEIGHT/2.0f,0),
|
||||
}, FARM_PLOT_DEFAULT_HEIGHT);
|
||||
town.addFarmPlot(region);
|
||||
}
|
||||
|
||||
@ -48,25 +48,37 @@ public class RegionPrism implements Region {
|
||||
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.minZ > points[i].z){
|
||||
rVal.aabb.minZ = 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;
|
||||
if(rVal.aabb.maxZ < points[i].z){
|
||||
rVal.aabb.maxZ = points[i].z;
|
||||
}
|
||||
}
|
||||
rVal.aabb.minY = points[0].y;
|
||||
rVal.aabb.maxY = points[0].y + height;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the prism
|
||||
* @return The height
|
||||
*/
|
||||
public double getHeight(){
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the points of the prism
|
||||
* @return The points of the prism
|
||||
*/
|
||||
public Vector3d[] getPoints(){
|
||||
return this.points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionType getType() {
|
||||
return RegionType.Y_ALIGNED_PRISM;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user