Revert "gridded data cell improvements"
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 reverts commit da3ada73d0.
This commit is contained in:
parent
03035aa1fb
commit
cf9dceff42
@ -1988,8 +1988,6 @@ Performance improvements
|
||||
- Reduce bones on LOD human model
|
||||
Increase human move speed
|
||||
LOD components re-attach physics
|
||||
Memory improvements
|
||||
- Rely on vector pool more
|
||||
|
||||
|
||||
|
||||
|
||||
@ -72,112 +72,112 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
/**
|
||||
* The number of frames without players that must pass before a server data cell is unloaded
|
||||
*/
|
||||
private static final int UNLOAD_FRAME_THRESHOLD = 100;
|
||||
static final int UNLOAD_FRAME_THRESHOLD = 100;
|
||||
|
||||
/**
|
||||
* The distance at which simulation is queued
|
||||
*/
|
||||
private static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
||||
static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
||||
|
||||
/**
|
||||
* Big number used when scanning for a data cell to spawn a macro object within
|
||||
*/
|
||||
private static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
||||
static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
||||
|
||||
/**
|
||||
* Used for generating physics chunks
|
||||
*/
|
||||
private ExecutorService generationService = null;
|
||||
ExecutorService generationService = null;
|
||||
|
||||
/**
|
||||
* The service for loading data cells from disk
|
||||
*/
|
||||
private GriddedDataCellLoaderService loaderService;
|
||||
GriddedDataCellLoaderService loaderService;
|
||||
|
||||
/**
|
||||
* Tracks whether this manager has been flagged to unload cells or not
|
||||
*/
|
||||
private boolean unloadCells = true;
|
||||
boolean unloadCells = true;
|
||||
|
||||
/**
|
||||
* These are going to be the natural ground grid of data cells, but we're going to have more than this
|
||||
*/
|
||||
private Map<Long,ServerDataCell> groundDataCells = new HashMap<Long,ServerDataCell>();
|
||||
Map<Long,ServerDataCell> groundDataCells = new HashMap<Long,ServerDataCell>();
|
||||
|
||||
/**
|
||||
* Map of server cell to its world position
|
||||
*/
|
||||
private Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
|
||||
Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
|
||||
|
||||
/**
|
||||
* Map of server data cell to the number of frames said cell has had no players
|
||||
*/
|
||||
private Map<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>();
|
||||
Map<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>();
|
||||
|
||||
/**
|
||||
* A map of ServerDataCell->GriddedDataCellTrackingData
|
||||
*/
|
||||
private Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>();
|
||||
Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>();
|
||||
|
||||
/**
|
||||
* Loaded cells
|
||||
*/
|
||||
private ReentrantLock loadedCellsLock = new ReentrantLock();
|
||||
ReentrantLock loadedCellsLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Parent realm
|
||||
*/
|
||||
private Realm parent;
|
||||
Realm parent;
|
||||
|
||||
/**
|
||||
* The world data of the parent
|
||||
*/
|
||||
private ServerWorldData serverWorldData;
|
||||
ServerWorldData serverWorldData;
|
||||
|
||||
/**
|
||||
* Manager for terrain for this particular cell manager
|
||||
*/
|
||||
private ServerTerrainManager serverTerrainManager;
|
||||
ServerTerrainManager serverTerrainManager;
|
||||
|
||||
/**
|
||||
* Manager for fluids for this particular cell manager
|
||||
*/
|
||||
private ServerFluidManager serverFluidManager;
|
||||
ServerFluidManager serverFluidManager;
|
||||
|
||||
/**
|
||||
* Lock for terrain editing
|
||||
*/
|
||||
private Semaphore terrainEditLock = new Semaphore(1);
|
||||
Semaphore terrainEditLock = new Semaphore(1);
|
||||
|
||||
/**
|
||||
* Manager for getting entities to fill in a cell
|
||||
*/
|
||||
private ServerContentManager serverContentManager;
|
||||
ServerContentManager serverContentManager;
|
||||
|
||||
/**
|
||||
* Used for cleaning server data cells no longer in use from the realm
|
||||
*/
|
||||
private Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
||||
Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
||||
|
||||
/**
|
||||
* Map of world position key -> physics cell
|
||||
*/
|
||||
private Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
||||
Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
||||
|
||||
/**
|
||||
* Number of data cells cleaned up in the most recent frame
|
||||
*/
|
||||
private int numCleaned = 0;
|
||||
int numCleaned = 0;
|
||||
|
||||
/**
|
||||
* Queue of cells that need to have their physics regenerated (ie on block edits)
|
||||
*/
|
||||
private Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
||||
Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
||||
|
||||
/**
|
||||
* The pathfinder for the manager
|
||||
*/
|
||||
private VoxelPathfinder pathfinder;
|
||||
VoxelPathfinder pathfinder;
|
||||
|
||||
/**
|
||||
* Caches lookups for nearby entities between simulate() calls
|
||||
@ -359,7 +359,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
loadedCellsLock.lock();
|
||||
if(posPhysicsMap.containsKey(key)){
|
||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||
cell.destroyEntities();
|
||||
cell.retireCell();
|
||||
}
|
||||
loadedCellsLock.unlock();
|
||||
//get data to generate with
|
||||
@ -384,7 +384,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
//the server will not be able to synchronize it properly.
|
||||
ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos);
|
||||
ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos);
|
||||
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(terrainEntity, blockEntity);
|
||||
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
||||
cell.setTerrainChunk(terrainChunk);
|
||||
cell.setBlockChunk(blockChunkData);
|
||||
cell.generatePhysics();
|
||||
@ -545,8 +545,39 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
continue;
|
||||
}
|
||||
|
||||
this.unloadCell(cell);
|
||||
|
||||
|
||||
Vector3i worldPos = this.getCellWorldPosition(cell);
|
||||
Long key = this.getServerDataCellKey(worldPos);
|
||||
//entities are serialized before tracking is removed. This makes sure that any side effects from calling destroyEntity (ie if it looks up the chunk that we're deleting)
|
||||
//don't trigger the chunk to be re-created
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Serialize entities");
|
||||
ContentSerialization serializedEntities = ContentSerialization.constructContentSerialization(cell.getScene().getEntityList());
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Destroy entities");
|
||||
for(Entity entity : cell.getScene().getEntityList()){
|
||||
ServerEntityUtils.destroyEntity(entity);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//save terrain to disk
|
||||
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
||||
//don't trigger the chunk to be re-created
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
||||
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
||||
serverTerrainManager.savePositionToDisk(worldPos);
|
||||
});
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//deregister from all tracking structures
|
||||
parent.deregisterCell(cell);
|
||||
groundDataCells.remove(key);
|
||||
this.posPhysicsMap.remove(key);
|
||||
this.cellPositionMap.remove(cell);
|
||||
this.cellTrackingMap.remove(cell);
|
||||
this.cellPlayerlessFrameMap.remove(cell);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
loadedCellsLock.unlock();
|
||||
@ -567,55 +598,26 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
toCleanQueue.add(cell);
|
||||
}
|
||||
for(ServerDataCell cell : toCleanQueue){
|
||||
this.unloadCell(cell);
|
||||
parent.deregisterCell(cell);
|
||||
Vector3i worldPos = this.getCellWorldPosition(cell);
|
||||
Long key = getServerDataCellKey(worldPos);
|
||||
groundDataCells.remove(key);
|
||||
this.posPhysicsMap.remove(key);
|
||||
this.cellPositionMap.remove(cell);
|
||||
this.cellPlayerlessFrameMap.remove(cell);
|
||||
this.cellTrackingMap.remove(cell);
|
||||
//offload all entities in cell to chunk file
|
||||
serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList());
|
||||
//clear all entities in cell
|
||||
for(Entity entity : cell.getScene().getEntityList()){
|
||||
ServerEntityUtils.destroyEntity(entity);
|
||||
}
|
||||
}
|
||||
loadedCellsLock.unlock();
|
||||
this.serverTerrainManager.evictAll();
|
||||
toCleanQueue.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads a server data cell
|
||||
* @param cell The cell
|
||||
*/
|
||||
public void unloadCell(ServerDataCell cell){
|
||||
Vector3i worldPos = this.getCellWorldPosition(cell);
|
||||
Long key = this.getServerDataCellKey(worldPos);
|
||||
//entities are serialized before tracking is removed. This makes sure that any side effects from calling destroyEntity (ie if it looks up the chunk that we're deleting)
|
||||
//don't trigger the chunk to be re-created
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Serialize entities");
|
||||
ContentSerialization serializedEntities = ContentSerialization.constructContentSerialization(cell.getScene().getEntityList());
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Destroy entities");
|
||||
for(Entity entity : cell.getScene().getEntityList()){
|
||||
ServerEntityUtils.destroyEntity(entity);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//save terrain to disk
|
||||
//terrain is saved before tracking is removed. This makes sure that any side effects from calling savePositionToDisk (ie if it looks up the chunk that we're deleting)
|
||||
//don't trigger the chunk to be re-created
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
||||
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
||||
serverTerrainManager.savePositionToDisk(worldPos);
|
||||
});
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//deregister from all tracking structures
|
||||
this.parent.deregisterCell(cell);
|
||||
this.groundDataCells.remove(key);
|
||||
PhysicsDataCell releasedCell = this.posPhysicsMap.remove(key);
|
||||
if(releasedCell != null){
|
||||
releasedCell.destroyEntities();
|
||||
}
|
||||
this.cellPositionMap.remove(cell);
|
||||
this.cellTrackingMap.remove(cell);
|
||||
this.cellPlayerlessFrameMap.remove(cell);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data cell at a given real point in this realm
|
||||
* @param point The real point
|
||||
@ -817,7 +819,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos);
|
||||
ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos);
|
||||
|
||||
PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(terrainEntity, blockEntity);
|
||||
PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
||||
if(cell == null){
|
||||
posPhysicsMap.put(key, targetCell);
|
||||
} else {
|
||||
@ -845,7 +847,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
|
||||
//create physics entities
|
||||
if(cell != null){
|
||||
cell.destroyEntities();
|
||||
cell.retireCell();
|
||||
cell.generatePhysics();
|
||||
} else {
|
||||
targetCell.generatePhysics();
|
||||
@ -880,9 +882,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
Long cellKey = this.getServerDataCellKey(localWorldPos);
|
||||
|
||||
loadedCellsLock.lock();
|
||||
if(groundDataCells.containsKey(cellKey)){
|
||||
throw new Error("Creating server data cell at position that already has a cell! " + localWorldPos);
|
||||
}
|
||||
groundDataCells.put(cellKey,rVal);
|
||||
cellPlayerlessFrameMap.put(rVal,0);
|
||||
LoggerInterface.loggerEngine.DEBUG("Create server data cell with key " + cellKey);
|
||||
@ -1155,21 +1154,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
return cellPlayerlessFrameMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tracking data for a cell
|
||||
* @param cell The cell
|
||||
* @return The tracking data as a string
|
||||
*/
|
||||
public String getCellData(ServerDataCell cell){
|
||||
String message = "Failed to find position of cell!\n" +
|
||||
"groundDataCells: " + this.groundDataCells.values().contains(cell) + "\n" +
|
||||
"cellPositionMap: " + this.cellPositionMap.keySet().contains(cell) + "\n" +
|
||||
"cellPlayerlessFrameMap: " + this.cellPositionMap.keySet().contains(cell) + "\n" +
|
||||
"cellTrackingMap: " + this.cellTrackingMap.keySet().contains(cell) + "\n" +
|
||||
"";
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Vector3d> findPath(Vector3d start, Vector3d end){
|
||||
Vector3i startChunkPos = ServerWorldData.convertRealToChunkSpace(start);
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.server.datacell.physics;
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.data.TerrainChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.ServerEntityUtils;
|
||||
@ -10,54 +11,39 @@ import electrosphere.entity.types.terrain.BlockChunkEntity;
|
||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||
import electrosphere.renderer.meshgen.BlockMeshgen;
|
||||
import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
import org.ode4j.ode.DBody;
|
||||
|
||||
/**
|
||||
* An entity which contains physics for terrain for a given chunk on the server
|
||||
*/
|
||||
public class PhysicsDataCell {
|
||||
|
||||
Vector3i worldPos;
|
||||
|
||||
/**
|
||||
* The terrain physics entity
|
||||
*/
|
||||
private Entity physicsEntity;
|
||||
Entity physicsEntity;
|
||||
Entity blockPhysicsEntity;
|
||||
|
||||
/**
|
||||
* The block physics entity
|
||||
*/
|
||||
private Entity blockPhysicsEntity;
|
||||
ServerTerrainChunk terrainChunk;
|
||||
BlockChunkData blockChunk;
|
||||
|
||||
DBody physicsObject;
|
||||
|
||||
/**
|
||||
* The terrain chunk data
|
||||
*/
|
||||
private ServerTerrainChunk terrainChunk;
|
||||
|
||||
/**
|
||||
* The block chunk data
|
||||
*/
|
||||
private BlockChunkData blockChunk;
|
||||
|
||||
/**
|
||||
* The weight data
|
||||
*/
|
||||
private float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||
|
||||
/**
|
||||
* The type data
|
||||
*/
|
||||
private int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||
float[][][] weights = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||
int[][][] types = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||
|
||||
/**
|
||||
* The terrain vertex data
|
||||
*/
|
||||
private TerrainChunkData terrainChunkData;
|
||||
TerrainChunkData terrainChunkData;
|
||||
|
||||
/**
|
||||
* The block vertex data
|
||||
*/
|
||||
private BlockMeshData blockData;
|
||||
BlockMeshData blockData;
|
||||
|
||||
/**
|
||||
* Creates a physics cell
|
||||
@ -66,6 +52,7 @@ public class PhysicsDataCell {
|
||||
* @return The cell
|
||||
*/
|
||||
public static PhysicsDataCell createPhysicsCell(
|
||||
Vector3i worldPos,
|
||||
Entity physicsEntity,
|
||||
Entity blockPhysicsEntity
|
||||
|
||||
@ -73,47 +60,19 @@ public class PhysicsDataCell {
|
||||
PhysicsDataCell rVal = new PhysicsDataCell();
|
||||
rVal.physicsEntity = physicsEntity;
|
||||
rVal.blockPhysicsEntity = blockPhysicsEntity;
|
||||
rVal.worldPos = worldPos;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retires a physics data cell
|
||||
*/
|
||||
public void destroyEntities(){
|
||||
public void retireCell(){
|
||||
ServerEntityUtils.destroyEntity(physicsEntity);
|
||||
this.physicsEntity = null;
|
||||
ServerEntityUtils.destroyEntity(blockPhysicsEntity);
|
||||
this.blockPhysicsEntity = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the data in this cell
|
||||
*/
|
||||
public void free(){
|
||||
this.destroyEntities();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the physics data cell
|
||||
*/
|
||||
public void reset(
|
||||
Vector3i worldPos,
|
||||
Entity physicsEntity,
|
||||
Entity blockPhysicsEntity
|
||||
){
|
||||
if(this.physicsEntity != null){
|
||||
ServerEntityUtils.destroyEntity(this.physicsEntity);
|
||||
}
|
||||
if(this.blockPhysicsEntity != null){
|
||||
ServerEntityUtils.destroyEntity(this.blockPhysicsEntity);
|
||||
}
|
||||
this.physicsEntity = physicsEntity;
|
||||
this.blockPhysicsEntity = blockPhysicsEntity;
|
||||
this.terrainChunk = null;
|
||||
this.blockChunk = null;
|
||||
this.terrainChunkData = null;
|
||||
this.blockData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the physics entity for this chunk
|
||||
@ -146,6 +105,15 @@ public class PhysicsDataCell {
|
||||
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||
localBlockPhysicsEntity.putData(EntityDataStrings.BLOCK_ENTITY, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the physics for this data cell
|
||||
*/
|
||||
public void destroyPhysics(){
|
||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(physicsEntity);
|
||||
realm.getCollisionEngine().destroyPhysics(physicsEntity);
|
||||
realm.getCollisionEngine().destroyPhysics(blockPhysicsEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the internal arrays of data for generate terrain models
|
||||
|
||||
Loading…
Reference in New Issue
Block a user