place buildings along roads
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-20 16:21:04 -04:00
parent a4d2f7d72a
commit 488ce9fd21
7 changed files with 108 additions and 20 deletions

View File

@ -5,9 +5,9 @@
"displayName" : "Default House",
"fabPath" : "Data/fab/defaultHouse.fab",
"dimensions" : {
"x" : 100,
"y" : 100,
"z" : 100
"x" : 5,
"y" : 5,
"z" : 5
},
"placementOffset" : {
"x" : 0,

View File

@ -1922,6 +1922,7 @@ Roads block content generation
Properly layout roads along town points in TownLayout
Town generates a structure -- scaffolding for doing it across roads
Structures create foundations in terrain voxels
Place buildings along roads

View File

@ -40,6 +40,7 @@ import electrosphere.server.datacell.interfaces.VoxelCellManager;
import electrosphere.server.datacell.physics.PhysicsDataCell;
import electrosphere.server.entity.ServerContentManager;
import electrosphere.server.entity.serialization.ContentSerialization;
import electrosphere.server.macro.MacroDataUpdater;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.pathfinding.recast.PathingProgressiveData;
import electrosphere.server.pathfinding.voxel.VoxelPathfinder;
@ -362,6 +363,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
);
MacroDataUpdater.update(parent, parent.getMacroData(), realPos);
BlockChunkData blockChunkData = parent.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
ServerTerrainChunk terrainChunk = parent.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES);
@ -813,6 +815,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
ServerEntityUtils.destroyEntity(blockEntity);
}
MacroDataUpdater.update(parent, parent.getMacroData(), realPos);
this.generationService.submit(() -> {
try {
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);

View File

@ -288,6 +288,7 @@ public class MacroData {
* @param structure The structure
*/
public void addStructure(VirtualStructure structure){
structure.setId(structures.size());
structures.add(structure);
}

View File

@ -138,6 +138,14 @@ public class VirtualStructure implements MacroAreaObject {
public int getId(){
return id;
}
/**
* Sets the id of this structure
* @param id The id
*/
public void setId(int id){
this.id = id;
}
}

View File

@ -88,33 +88,103 @@ public class TownLayout {
scanPoint.set(townCenter).add(0,0,-TOWN_LAYOUT_SCALER);
Vector3d downNodeLoc = TownLayout.getTownCenter(realm, scanPoint);
//
//generate roads
Road newRoad;
//up-facing road
Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
//generate structures along the road
StructureData structureData = allowedStructures.get(0);
Vector3d pos = new Vector3d(centerNodeLoc).add(10,0,10);
pos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(pos);
AABBd aabb = new AABBd();
aabb.setMin(pos);
aabb.setMax(new Vector3d(pos).add(structureData.getDimensions()));
if(!macroData.intersectsStruct(aabb)){
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, pos);
town.addStructure(struct);
}
newRoad = Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
//right-facing road
Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
newRoad = Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
//left-facing road
Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
newRoad = Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
//down-facing road
Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
newRoad = Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
town.setResolution(Town.TOWN_RES_MAX);
}
/**
* Generates structures along a road
* @param realm The realm
* @param town The town
* @param road The road
* @param allowedStructures The list of allowed structure types
*/
private static void generateStructuresAlongRoad(Realm realm, Town town, Road road, List<StructureData> allowedStructures){
MacroData macroData = realm.getMacroData();
//get values to scan along
Vector3d startPoint = road.getPoint1();
Vector3d endPoint = road.getPoint2();
Vector3d dir = new Vector3d(endPoint).sub(startPoint).normalize();
int len = (int)startPoint.distance(endPoint);
//determine if it's primarily north-south or east-west
boolean isNorthSouth = true;
if(Math.abs(endPoint.x - startPoint.x) > Math.abs(endPoint.z - startPoint.z)){
isNorthSouth = false;
} else {
isNorthSouth = true;
}
//offset applied to the scan location to not place it on top of the road
Vector3d placementOffset = null;
if(isNorthSouth){
placementOffset = new Vector3d(road.getRadius() + 10,0,0);
} else {
placementOffset = new Vector3d(0,0,road.getRadius() + 10);
}
//the position to try at
Vector3d currPos = new Vector3d();
AABBd aabb = new AABBd();
//the type of structure to place
StructureData structureData = allowedStructures.get(0);
//scan along the length of the road
for(int i = 0; i < len; i++){
//solve terrain position to place
currPos.set(dir).mul(i).add(startPoint).add(placementOffset);
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
//apply structure placement offset
currPos.add(structureData.getPlacementOffset());
//update aabb
aabb.setMin(currPos);
aabb.setMax(new Vector3d(currPos).add(structureData.getDimensions()));
if(!macroData.intersectsStruct(aabb)){
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos);
town.addStructure(struct);
//TODO: once have successfully placed this structure type, pick a new one to place
}
}
//scan along the length of the road
for(int i = 0; i < len; i++){
//solve terrain position to place
currPos.set(dir).mul(i).add(startPoint).sub(placementOffset).sub(structureData.getDimensions().x,0,structureData.getDimensions().z);
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
//apply structure placement offset
currPos.add(structureData.getPlacementOffset());
//update aabb
aabb.setMin(currPos);
aabb.setMax(new Vector3d(currPos).add(structureData.getDimensions()));
if(!macroData.intersectsStruct(aabb)){
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos);
town.addStructure(struct);
//TODO: once have successfully placed this structure type, pick a new one to place
}
}
}
/**
* Clamps the scan point to the closest town center point
* @param realm The realm

View File

@ -57,6 +57,11 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
*/
public static final int SURFACE_VOXEL_WIDTH = 2;
/**
* The width of the foundation generated underneath structures
*/
public static final int VIRTUAL_STRUCTURE_FOUNDATION_WIDTH = 2;
/**
* Tag for the test generator
*/
@ -291,7 +296,7 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
if(realX >= aabb.minX && realX <= aabb.maxX && realZ >= aabb.minZ && realZ <= aabb.maxZ){
//check if within foundation range
double vertDist = aabb.minY - realY;
if(vertDist > 0 && vertDist < 2){
if(vertDist > 0 && vertDist < VIRTUAL_STRUCTURE_FOUNDATION_WIDTH){
voxel.type = 1;
voxel.weight = 1;
rVal = true;