farm plots properly save/load to/from disk
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-28 21:50:51 -04:00
parent 8bffe711ae
commit 81f79232e1
12 changed files with 205 additions and 39 deletions

View File

@ -2042,6 +2042,7 @@ Y-aligned prism meshgen
Rendering prism regions
Utilities for turning mesh gen algos into renderable entities
Back off farm plots from roads by road radius
Farm plots properly save/load to/from disk

View File

@ -48,10 +48,11 @@ import electrosphere.renderer.pipelines.RenderPipeline;
import electrosphere.renderer.texture.Texture;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.region.MacroRegion;
import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.util.math.SpatialMathUtils;
import electrosphere.util.math.region.Region;
import electrosphere.util.math.region.RegionPrism;
/**
@ -222,9 +223,11 @@ public class DebugContentPipeline implements RenderPipeline {
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){
MacroData macroData = Globals.serverState.realmManager.first().getMacroData();
List<MacroRegion> farmPlots = macroData.getTown(0).getFarmPlots(macroData);
if(farmPlots.size() > 0){
for(MacroRegion region : farmPlots){
if(region.getRegion() instanceof RegionPrism prism){
Entity plotDebugEnt = EntityCreationUtils.createClientSpatialEntity();
DrawableUtils.makeEntityDrawable(plotDebugEnt, () -> {
Vector3d[] finalPoints = new Vector3d[prism.getPoints().length];

View File

@ -15,6 +15,7 @@ import electrosphere.server.macro.civilization.CivilizationGenerator;
import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.race.Race;
import electrosphere.server.macro.race.RaceMap;
import electrosphere.server.macro.region.MacroRegion;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.macro.structure.VirtualStructure;
@ -58,12 +59,23 @@ public class MacroData {
*/
List<VirtualStructure> structures = new LinkedList<VirtualStructure>();
/**
* The list of all regions
*/
List<MacroRegion> regions = new LinkedList<MacroRegion>();
/**
* Maps structure id -> structure
*/
@Exclude
private Map<Integer,VirtualStructure> idStructMap = new HashMap<Integer,VirtualStructure>();
/**
* Maps region id -> region
*/
@Exclude
private Map<Long,MacroRegion> idRegionMap = new HashMap<Long,MacroRegion>();
/**
* List of roads
*/
@ -173,6 +185,9 @@ public class MacroData {
for(VirtualStructure struct : this.structures){
this.idStructMap.put(struct.getId(),struct);
}
for(MacroRegion region : this.regions){
this.idRegionMap.put(region.getId(),region);
}
}
/**
@ -280,6 +295,25 @@ public class MacroData {
return this.roads;
}
/**
* Registers a macro region
* @param region The macro region
*/
public void registerRegion(MacroRegion region){
region.setId(regions.size());
regions.add(region);
idRegionMap.put(region.getId(),region);
}
/**
* Gets a macro region by its id
* @param id The id
* @return The macro region if it exists, null otherwise
*/
public MacroRegion getRegion(long id){
return idRegionMap.get(id);
}
/**
* Gets the list of structures
* @return The list of structures

View File

@ -0,0 +1,69 @@
package electrosphere.server.macro.region;
import electrosphere.server.macro.MacroData;
import electrosphere.util.math.region.Region;
/**
* A macro data spatial region
*/
public class MacroRegion {
/**
* The id of the region
*/
private long id;
/**
* The region
*/
private Region region;
/**
* Creates a macro region
* @param macroData The macro data
* @param region The region
* @return The macro region
*/
public static MacroRegion create(MacroData macroData, Region region){
MacroRegion rVal = new MacroRegion();
rVal.region = region;
macroData.registerRegion(rVal);
return rVal;
}
/**
* Gets the id of the region
* @return The id of the region
*/
public long getId() {
return id;
}
/**
* Sets the id of the region
* @param id The id of the region
*/
public void setId(long id) {
this.id = id;
}
/**
* Gets the spatial data of the region
* @return The spatial data
*/
public Region getRegion() {
return region;
}
/**
* Sets the spatial data of the region
* @param region The spatial data of the region
*/
public void setRegion(Region region) {
this.region = region;
}
}

View File

@ -1,5 +0,0 @@
package electrosphere.server.macro.settlement;
public class Settlement {
}

View File

@ -4,10 +4,10 @@ import electrosphere.engine.Globals;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.region.MacroRegion;
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;
@ -72,9 +72,9 @@ public class Town implements MacroAreaObject, MacroLODObject {
private List<TownJob> jobs = new LinkedList<TownJob>();
/**
* The list of farm plot regions
* The list of farm plot region idss
*/
private List<Region> farmPlots = new LinkedList<Region>();
private List<Long> farmPlotRegions = new LinkedList<Long>();
/**
* The id of the parent civilization
@ -139,18 +139,20 @@ public class Town implements MacroAreaObject, MacroLODObject {
/**
* Gets the farm plots in the town
* @param macroData The macro data
* @return The list of farm plots
*/
public List<Region> getFarmPlots(){
return farmPlots;
public List<MacroRegion> getFarmPlots(MacroData macroData){
List<MacroRegion> regions = this.farmPlotRegions.stream().map((Long id) -> macroData.getRegion(id)).collect(Collectors.toList());
return regions;
}
/**
* Adds a farm plot region
* @param farmPlotRegion The region for the farm plot
*/
public void addFarmPlot(Region farmPlotRegion){
this.farmPlots.add(farmPlotRegion);
public void addFarmPlot(MacroRegion farmPlotRegion){
this.farmPlotRegions.add(farmPlotRegion.getId());
}
/**

View File

@ -18,6 +18,7 @@ import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.race.Race;
import electrosphere.server.macro.region.MacroRegion;
import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.util.math.HashUtils;
import electrosphere.util.math.VoronoiUtils;
@ -288,7 +289,7 @@ public class TownLayout {
plotPoint3.y = plotPoint1.y;
plotPoint4.y = plotPoint1.y;
//define a farm plot with these points
TownLayout.generateFarmPlot(realm,town,plotPoint1,plotPoint2,plotPoint3,plotPoint4);
TownLayout.generateFarmPlot(realm,macroData,town,plotPoint1,plotPoint2,plotPoint3,plotPoint4);
}
closedSet.add(openHash);
@ -408,20 +409,22 @@ public class TownLayout {
/**
* Creates a farm plot in the town at a given set of points
* @param realm The realm the town is in
* @param macroData The macro data
* @param town The town
* @param point1 The first point
* @param point2 The second point
* @param point3 The third point
* @param point4 The fourth point
*/
private static void generateFarmPlot(Realm realm, Town town, Vector3d point1, Vector3d point2, Vector3d point3, Vector3d point4){
private static void generateFarmPlot(Realm realm, MacroData macroData, Town town, Vector3d point1, Vector3d point2, Vector3d point3, Vector3d point4){
RegionPrism region = RegionPrism.create(new Vector3d[]{
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);
MacroRegion macroRegion = MacroRegion.create(macroData, region);
town.addFarmPlot(macroRegion);
}
/**

View File

@ -13,6 +13,8 @@ import electrosphere.server.macro.character.data.CharacterDataSerializer;
import electrosphere.server.physics.terrain.generation.noise.NoiseModuleSerializer;
import electrosphere.server.physics.terrain.generation.noise.NoiseSampler;
import electrosphere.util.annotation.AnnotationExclusionStrategy;
import electrosphere.util.math.region.Region;
import electrosphere.util.math.region.RegionSerializer;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
@ -56,6 +58,7 @@ public class FileUtils {
gsonBuilder.registerTypeAdapter(AITreeData.class, new AITreeDataSerializer());
gsonBuilder.registerTypeAdapter(NoiseSampler.class, new NoiseModuleSerializer());
gsonBuilder.registerTypeAdapter(CharacterData.class, new CharacterDataSerializer());
gsonBuilder.registerTypeAdapter(Region.class, new RegionSerializer());
gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
gson = gsonBuilder.create();

View File

@ -9,25 +9,11 @@ import org.joml.Vector3d;
*/
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();
public String getType();
/**
* Checks if the region contains a point

View File

@ -11,6 +11,16 @@ import electrosphere.util.math.GeomUtils;
*/
public class RegionPrism implements Region {
/**
* The prism region type
*/
public static final String TYPE_STRING = "Y_ALIGNED_PRISM";
/**
* The type of region
*/
private final String type = TYPE_STRING;
/**
* The height of the prism
@ -80,8 +90,8 @@ public class RegionPrism implements Region {
}
@Override
public RegionType getType() {
return RegionType.Y_ALIGNED_PRISM;
public String getType() {
return type;
}
@Override

View File

@ -9,6 +9,16 @@ import org.joml.Vector3d;
*/
public class RegionRectangular implements Region {
/**
* The prism region type
*/
public static final String TYPE_STRING = "RECTANGULAR";
/**
* The type of region
*/
private final String type = RegionRectangular.TYPE_STRING;
/**
* The AABB of the area selection
*/
@ -41,8 +51,8 @@ public class RegionRectangular implements Region {
}
@Override
public RegionType getType() {
return RegionType.RECTANGULAR;
public String getType() {
return type;
}
@Override
@ -52,7 +62,7 @@ public class RegionRectangular implements Region {
@Override
public boolean intersects(Region other) {
if(other.getType() != RegionType.RECTANGULAR){
if(other.getType() != RegionRectangular.TYPE_STRING){
throw new Error("One of the areas to test is not rectangular! " + other.getType());
}
return aabb.testAABB(other.getAABB());

View File

@ -0,0 +1,50 @@
package electrosphere.util.math.region;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class RegionSerializer implements JsonSerializer<Region>, JsonDeserializer<Region> {
@Override
public Region deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
switch(json.getAsJsonObject().get("type").getAsString()){
case RegionRectangular.TYPE_STRING: {
return context.deserialize(json, RegionRectangular.class);
}
case RegionPrism.TYPE_STRING: {
return context.deserialize(json, RegionPrism.class);
}
default: {
throw new Error("Failed to serialize datatype: " + json.getAsJsonObject().get("type").getAsString());
}
}
}
@Override
public JsonElement serialize(Region src, Type typeOfSrc, JsonSerializationContext context) {
switch(src.getType()){
//race
case RegionPrism.TYPE_STRING: {
return context.serialize((RegionPrism)src);
}
//diety data
case RegionRectangular.TYPE_STRING: {
return context.serialize((RegionRectangular)src);
}
default: {
throw new Error("Failed to serialize datatype: " + src.getType());
}
}
}
}