town layout work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-23 17:06:57 -04:00
parent 44e79171a8
commit b2bac5f540
2 changed files with 144 additions and 13 deletions

View File

@ -1945,6 +1945,9 @@ GriddedDataCellManager filtering optimization
StandardUniformManager implementation
Small fixes
(05/23/2025)
Town layout work

View File

@ -17,6 +17,7 @@ import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.race.Race;
import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.util.math.HashUtils;
import electrosphere.util.math.VoronoiUtils;
/**
@ -29,10 +30,34 @@ public class TownLayout {
*/
public static final double TOWN_LAYOUT_SCALER = 64;
/**
* The maximum radius of towns
*/
public static final double TOWN_MAX_RADIUS = 256;
/**
* Relaxation factor for regularizing placement of town center nodes
*/
public static final double VORONOI_RELAXATION_FACTOR = 0.4;
public static final double VORONOI_RELAXATION_FACTOR = 0.3;
/**
* Offset applied to breadth search hashing
*/
private static final int HASH_OFFSET = 1000;
/**
* Offset used to search for town centers
*/
static final int[] offsetX = new int[]{
-1,1,0,0
};
/**
* Offset used to search for town centers
*/
static final int[] offsetZ = new int[]{
0,0,-1,1
};
/**
* Lays out structures for a town
@ -67,6 +92,8 @@ public class TownLayout {
//find the nodes to connect
Vector3d townCenter = town.getPos();
Vector3d scanPoint = new Vector3d();
Vector3d currPoint = new Vector3d();
Vector3d nearPoint = null;
//get center loc
scanPoint.set(townCenter);
@ -88,23 +115,126 @@ public class TownLayout {
scanPoint.set(townCenter).add(0,0,-TOWN_LAYOUT_SCALER);
Vector3d downNodeLoc = TownLayout.getTownCenter(realm, scanPoint);
//
//generate roads
Road upRoad = Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
Road rightRoad = Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
Road leftRoad = Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
Road downRoad = Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
Road.createRoad(macroData, upNodeLoc, centerNodeLoc);
Road.createRoad(macroData, rightNodeLoc, centerNodeLoc);
Road.createRoad(macroData, leftNodeLoc, centerNodeLoc);
Road.createRoad(macroData, downNodeLoc, centerNodeLoc);
//
//place structures along roads
TownLayout.generateStructuresAlongRoad(realm, town, upRoad, allowedStructures);
TownLayout.generateStructuresAlongRoad(realm, town, rightRoad, allowedStructures);
TownLayout.generateStructuresAlongRoad(realm, town, leftRoad, allowedStructures);
TownLayout.generateStructuresAlongRoad(realm, town, downRoad, allowedStructures);
// TownLayout.generateStructuresAlongRoad(realm, town, upRoad, allowedStructures);
// TownLayout.generateStructuresAlongRoad(realm, town, rightRoad, allowedStructures);
// TownLayout.generateStructuresAlongRoad(realm, town, leftRoad, allowedStructures);
// TownLayout.generateStructuresAlongRoad(realm, town, downRoad, allowedStructures);
//
//Breadth search other nodes to branch outwards
//
//
//sets for breadth search
LinkedList<Long> openSet = new LinkedList<Long>();
LinkedList<Long> closedSet = new LinkedList<Long>();
closedSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET - 1, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET + 1, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET - 1));
openSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET + 1));
while(openSet.size() > 0){
long openHash = openSet.poll();
int x = HashUtils.unhashIVec(openHash, HashUtils.UNHASH_COMPONENT_X) - HASH_OFFSET;
int z = HashUtils.unhashIVec(openHash, HashUtils.UNHASH_COMPONENT_Z) - HASH_OFFSET;
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * x,0,TOWN_LAYOUT_SCALER * z);
currPoint = TownLayout.getTownCenter(realm, scanPoint);
//check below
for(int i = 0; i < 4; i++){
int oX = x + offsetX[i];
int oZ = z + offsetZ[i];
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * oX,0,TOWN_LAYOUT_SCALER * oZ);
nearPoint = TownLayout.getTownCenter(realm, scanPoint);
long newHash = HashUtils.hashIVec(HASH_OFFSET + oX, 0, HASH_OFFSET + oZ);
if(nearPoint.distance(townCenter) < TOWN_MAX_RADIUS){
if(!openSet.contains(newHash) && !closedSet.contains(newHash)){
openSet.add(newHash);
}
//build road and structures between curr and next node
if(closedSet.contains(newHash)){
Road.createRoad(macroData, nearPoint, currPoint);
// TownLayout.generateStructuresAlongRoad(realm, town, newRoad, allowedStructures);
}
}
}
closedSet.add(openHash);
}
//
//Breadth search other nodes to branch outwards
//
//
//sets for breadth search
openSet = new LinkedList<Long>();
closedSet = new LinkedList<Long>();
closedSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET - 1, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET + 1, 0, HASH_OFFSET));
openSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET - 1));
openSet.add(HashUtils.hashIVec(HASH_OFFSET, 0, HASH_OFFSET + 1));
while(openSet.size() > 0){
long openHash = openSet.poll();
int x = HashUtils.unhashIVec(openHash, HashUtils.UNHASH_COMPONENT_X) - HASH_OFFSET;
int z = HashUtils.unhashIVec(openHash, HashUtils.UNHASH_COMPONENT_Z) - HASH_OFFSET;
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * x,0,TOWN_LAYOUT_SCALER * z);
currPoint = TownLayout.getTownCenter(realm, scanPoint);
//check below
for(int i = 0; i < 4; i++){
int oX = x + offsetX[i];
int oZ = z + offsetZ[i];
scanPoint.set(townCenter).add(TOWN_LAYOUT_SCALER * oX,0,TOWN_LAYOUT_SCALER * oZ);
nearPoint = TownLayout.getTownCenter(realm, scanPoint);
long newHash = HashUtils.hashIVec(HASH_OFFSET + oX, 0, HASH_OFFSET + oZ);
if(nearPoint.distance(townCenter) < TOWN_MAX_RADIUS){
if(!openSet.contains(newHash) && !closedSet.contains(newHash)){
openSet.add(newHash);
}
//build road and structures between curr and next node
if(closedSet.contains(newHash)){
// Road newRoad = Road.createRoad(macroData, nearPoint, currPoint);
TownLayout.generateStructuresAlongRoad(realm, town, nearPoint, currPoint, Road.DEFAULT_RADIUS, allowedStructures);
}
}
}
closedSet.add(openHash);
}
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){
// TownLayout.generateStructuresAlongRoad(realm, town, road.getPoint1(), road.getPoint2(), road.getRadius(), allowedStructures);
// }
/**
* Generates structures along a road
* @param realm The realm
@ -112,12 +242,10 @@ public class TownLayout {
* @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){
private static void generateStructuresAlongRoad(Realm realm, Town town, Vector3d startPoint, Vector3d endPoint, double radius, 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);
@ -129,7 +257,7 @@ public class TownLayout {
isNorthSouth = true;
}
int roadRadiusOffsetRaw = (int)(road.getRadius() + 3);
int roadRadiusOffsetRaw = (int)(radius + 4);
//offset applied to the scan location to not place it on top of the road
Vector3d roadOffset = null;