macro data blocks terrain and block gen
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-20 12:50:51 -04:00
parent 3685eb1c92
commit 27330797e9
10 changed files with 67 additions and 11 deletions

View File

@ -1916,6 +1916,7 @@ Place roads using line segments instead of splines
Town layout tries to connect intersection nodes with roads Town layout tries to connect intersection nodes with roads
Macro area objects don't store start/end bounds separate from aabb anymore Macro area objects don't store start/end bounds separate from aabb anymore
Unify functions to fetch/generate chunks on server Unify functions to fetch/generate chunks on server
Macro data blocks terrain and block generation until it is ready

View File

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import org.joml.Vector3d; import org.joml.Vector3d;
@ -816,6 +817,14 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
try { try {
BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z); BlockChunkData blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES); ServerTerrainChunk terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES);
while(terrainChunk == null){
TimeUnit.MILLISECONDS.sleep(1);
terrainChunk = realm.getServerWorldData().getServerTerrainManager().getChunk(worldPos.x, worldPos.y, worldPos.z, ServerChunkCache.STRIDE_FULL_RES);
}
while(blockChunkData == null){
TimeUnit.MILLISECONDS.sleep(1);
blockChunkData = realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z);
}
targetCell.setTerrainChunk(terrainChunk); targetCell.setTerrainChunk(terrainChunk);
targetCell.setBlockChunk(blockChunkData); targetCell.setBlockChunk(blockChunkData);

View File

@ -85,16 +85,22 @@ public class PhysicsDataCell {
// //
this.fillInData(); this.fillInData();
//grab local reference to this cell's entities
Entity localPhysicsEnt = this.physicsEntity;
Entity localBlockPhysicsEntity = this.blockPhysicsEntity;
//check if cell has already been retired
if(localBlockPhysicsEntity == null || localPhysicsEnt == null){
return;
}
//generate
this.terrainChunkData = TerrainChunk.serverGenerateTerrainChunkData(weights, types); this.terrainChunkData = TerrainChunk.serverGenerateTerrainChunkData(weights, types);
TerrainChunk.serverCreateTerrainChunkEntity(this.physicsEntity, this.terrainChunkData); TerrainChunk.serverCreateTerrainChunkEntity(localPhysicsEnt, this.terrainChunkData);
this.physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); localPhysicsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
this.blockData = BlockMeshgen.rasterize(this.blockChunk); this.blockData = BlockMeshgen.rasterize(this.blockChunk);
BlockChunkEntity.serverCreateBlockChunkEntity(this.blockPhysicsEntity, this.blockData); BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData);
this.blockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
// //then actually perform the attach
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
// Realm realm = Globals.serverState.realmManager.getEntityRealm(physicsEntity);
// realm.getCollisionEngine().registerPhysicsEntity(physicsEntity);
} }
/** /**

View File

@ -298,6 +298,7 @@ public class MacroData {
public List<MacroObject> getNearbyObjects(Vector3d position){ public List<MacroObject> getNearbyObjects(Vector3d position){
List<MacroObject> rVal = new LinkedList<MacroObject>(); List<MacroObject> rVal = new LinkedList<MacroObject>();
rVal.addAll(this.roads); rVal.addAll(this.roads);
rVal.addAll(this.towns);
return rVal; return rVal;
} }

View File

@ -0,0 +1,14 @@
package electrosphere.server.macro.spatial;
/**
* A macro object that can be simulated at different resolutions
*/
public interface MacroLODObject {
/**
* Checks if this macro object is full resolution or not
* @return true if it is full resolution, false otherwise
*/
public boolean isFullRes();
}

View File

@ -5,6 +5,7 @@ import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.civilization.Civilization; import electrosphere.server.macro.civilization.Civilization;
import electrosphere.server.macro.spatial.MacroAreaObject; import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.spatial.MacroLODObject;
import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.structure.VirtualStructure;
import java.util.LinkedList; import java.util.LinkedList;
@ -17,7 +18,7 @@ import org.joml.Vector3d;
/** /**
* Server representation of a town * Server representation of a town
*/ */
public class Town implements MacroAreaObject { public class Town implements MacroAreaObject, MacroLODObject {
/** /**
* Minimum data resolution town (ie hasn't generated structures or residents) * Minimum data resolution town (ie hasn't generated structures or residents)
@ -209,5 +210,10 @@ public class Town implements MacroAreaObject {
public Civilization getParent(MacroData macroData){ public Civilization getParent(MacroData macroData){
return macroData.getCivilization(this.parentCivId); return macroData.getCivilization(this.parentCivId);
} }
@Override
public boolean isFullRes() {
return this.resolution == TOWN_RES_MAX;
}
} }

View File

@ -15,6 +15,8 @@ import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroLODObject;
import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.server.physics.block.diskmap.ServerBlockChunkDiskMap; import electrosphere.server.physics.block.diskmap.ServerBlockChunkDiskMap;
@ -146,6 +148,17 @@ public class ServerBlockChunkGenerationThread implements Runnable {
ServerBlockChunkDiskMap chunkDiskMap, ServerBlockChunkDiskMap chunkDiskMap,
BlockChunkCache chunkCache BlockChunkCache chunkCache
){ ){
//get the macro data that affects this chunk
List<MacroObject> objects = null;
if(macroData != null){
objects = macroData.getNearbyObjects(ServerWorldData.convertChunkToRealSpace(worldX, worldY, worldZ));
}
//if any of this macro data isn't ready, return a null chunk
long notFullResCount = objects.stream().filter((MacroObject macroObj) -> macroObj instanceof MacroLODObject).map((MacroObject oldView) -> (MacroLODObject)oldView).filter((MacroLODObject lodObj) -> !lodObj.isFullRes()).count();
if(notFullResCount > 0){
return null;
}
BlockChunkData chunk = null; BlockChunkData chunk = null;
if(chunkCache.containsChunk(worldX, worldY, worldZ, stride)){ if(chunkCache.containsChunk(worldX, worldY, worldZ, stride)){
chunk = chunkCache.get(worldX, worldY, worldZ, stride); chunk = chunkCache.get(worldX, worldY, worldZ, stride);

View File

@ -14,6 +14,7 @@ import electrosphere.engine.Globals;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.civilization.road.Road; import electrosphere.server.macro.civilization.road.Road;
import electrosphere.server.macro.spatial.MacroObject; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.macro.town.Town;
import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen; import electrosphere.server.physics.terrain.generation.heightmap.EmptySkyGen;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator; import electrosphere.server.physics.terrain.generation.heightmap.HeightmapGenerator;
import electrosphere.server.physics.terrain.generation.heightmap.HeightmapNoiseGen; import electrosphere.server.physics.terrain.generation.heightmap.HeightmapNoiseGen;
@ -281,6 +282,7 @@ public class ProceduralChunkGenerator implements ChunkGenerator {
} }
} }
} }
} else if(object instanceof Town){
} else { } else {
throw new Error("Unsupported object type " + object); throw new Error("Unsupported object type " + object);
} }

View File

@ -8,6 +8,7 @@ import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.ServerWorldData;
import electrosphere.server.macro.MacroData; import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroLODObject;
import electrosphere.server.macro.spatial.MacroObject; import electrosphere.server.macro.spatial.MacroObject;
import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap; import electrosphere.server.physics.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.physics.terrain.generation.interfaces.ChunkGenerator;
@ -158,7 +159,10 @@ public class ChunkGenerationThread implements Runnable {
objects = macroData.getNearbyObjects(ServerWorldData.convertChunkToRealSpace(worldX, worldY, worldZ)); objects = macroData.getNearbyObjects(ServerWorldData.convertChunkToRealSpace(worldX, worldY, worldZ));
} }
//if any of this macro data isn't ready, return a null chunk //if any of this macro data isn't ready, return a null chunk
long notFullResCount = objects.stream().filter((MacroObject macroObj) -> macroObj instanceof MacroLODObject).map((MacroObject oldView) -> (MacroLODObject)oldView).filter((MacroLODObject lodObj) -> !lodObj.isFullRes()).count();
if(notFullResCount > 0){
return null;
}
if(chunkCache.containsChunk(worldX, worldY, worldZ, stride)){ if(chunkCache.containsChunk(worldX, worldY, worldZ, stride)){
rVal = chunkCache.get(worldX, worldY, worldZ, stride); rVal = chunkCache.get(worldX, worldY, worldZ, stride);

View File

@ -291,7 +291,7 @@ public class ServerTerrainManager {
//THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING //THIS FIRES IF THERE IS A MAIN GAME WORLD RUNNING
ServerTerrainChunk returnedChunk = ChunkGenerationThread.getChunk(macroData, worldX, worldY, worldZ, stride, chunkDiskMap, chunkCache, chunkGenerator); ServerTerrainChunk returnedChunk = ChunkGenerationThread.getChunk(macroData, worldX, worldY, worldZ, stride, chunkDiskMap, chunkCache, chunkGenerator);
if(returnedChunk == null){ if(returnedChunk == null){
LoggerInterface.loggerEngine.WARNING("Failed to generate chunk at " + worldX + " " + worldY + " " + worldZ + " asynchronously"); LoggerInterface.loggerEngine.WARNING("Failed to generate chunk at " + worldX + " " + worldY + " " + worldZ + " synchronously");
} }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
return returnedChunk; return returnedChunk;