town layout work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
44e79171a8
commit
b2bac5f540
@ -1945,6 +1945,9 @@ GriddedDataCellManager filtering optimization
|
||||
StandardUniformManager implementation
|
||||
Small fixes
|
||||
|
||||
(05/23/2025)
|
||||
Town layout work
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user