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 commit is contained in:
parent
d812393d4c
commit
da3ada73d0
@ -1988,6 +1988,8 @@ Performance improvements
|
|||||||
- Reduce bones on LOD human model
|
- Reduce bones on LOD human model
|
||||||
Increase human move speed
|
Increase human move speed
|
||||||
LOD components re-attach physics
|
LOD components re-attach physics
|
||||||
|
Memory improvements
|
||||||
|
- Gridded data cell physics cell pooling
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -72,112 +72,117 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
/**
|
/**
|
||||||
* The number of frames without players that must pass before a server data cell is unloaded
|
* The number of frames without players that must pass before a server data cell is unloaded
|
||||||
*/
|
*/
|
||||||
static final int UNLOAD_FRAME_THRESHOLD = 100;
|
private static final int UNLOAD_FRAME_THRESHOLD = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The distance at which simulation is queued
|
* The distance at which simulation is queued
|
||||||
*/
|
*/
|
||||||
static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
private static final double SIMULATION_DISTANCE_CUTOFF = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Big number used when scanning for a data cell to spawn a macro object within
|
* Big number used when scanning for a data cell to spawn a macro object within
|
||||||
*/
|
*/
|
||||||
static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
private static final double MACRO_SCANNING_BIG_NUMBER = 10000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for generating physics chunks
|
* Used for generating physics chunks
|
||||||
*/
|
*/
|
||||||
ExecutorService generationService = null;
|
private ExecutorService generationService = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service for loading data cells from disk
|
* The service for loading data cells from disk
|
||||||
*/
|
*/
|
||||||
GriddedDataCellLoaderService loaderService;
|
private GriddedDataCellLoaderService loaderService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether this manager has been flagged to unload cells or not
|
* Tracks whether this manager has been flagged to unload cells or not
|
||||||
*/
|
*/
|
||||||
boolean unloadCells = true;
|
private boolean unloadCells = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These are going to be the natural ground grid of data cells, but we're going to have more than this
|
* These are going to be the natural ground grid of data cells, but we're going to have more than this
|
||||||
*/
|
*/
|
||||||
Map<Long,ServerDataCell> groundDataCells = new HashMap<Long,ServerDataCell>();
|
private Map<Long,ServerDataCell> groundDataCells = new HashMap<Long,ServerDataCell>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of server cell to its world position
|
* Map of server cell to its world position
|
||||||
*/
|
*/
|
||||||
Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
|
private Map<ServerDataCell,Vector3i> cellPositionMap = new HashMap<ServerDataCell,Vector3i>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of server data cell to the number of frames said cell has had no players
|
* Map of server data cell to the number of frames said cell has had no players
|
||||||
*/
|
*/
|
||||||
Map<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>();
|
private Map<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of ServerDataCell->GriddedDataCellTrackingData
|
* A map of ServerDataCell->GriddedDataCellTrackingData
|
||||||
*/
|
*/
|
||||||
Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>();
|
private Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loaded cells
|
* Loaded cells
|
||||||
*/
|
*/
|
||||||
ReentrantLock loadedCellsLock = new ReentrantLock();
|
private ReentrantLock loadedCellsLock = new ReentrantLock();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parent realm
|
* Parent realm
|
||||||
*/
|
*/
|
||||||
Realm parent;
|
private Realm parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The world data of the parent
|
* The world data of the parent
|
||||||
*/
|
*/
|
||||||
ServerWorldData serverWorldData;
|
private ServerWorldData serverWorldData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for terrain for this particular cell manager
|
* Manager for terrain for this particular cell manager
|
||||||
*/
|
*/
|
||||||
ServerTerrainManager serverTerrainManager;
|
private ServerTerrainManager serverTerrainManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for fluids for this particular cell manager
|
* Manager for fluids for this particular cell manager
|
||||||
*/
|
*/
|
||||||
ServerFluidManager serverFluidManager;
|
private ServerFluidManager serverFluidManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock for terrain editing
|
* Lock for terrain editing
|
||||||
*/
|
*/
|
||||||
Semaphore terrainEditLock = new Semaphore(1);
|
private Semaphore terrainEditLock = new Semaphore(1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for getting entities to fill in a cell
|
* Manager for getting entities to fill in a cell
|
||||||
*/
|
*/
|
||||||
ServerContentManager serverContentManager;
|
private ServerContentManager serverContentManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for cleaning server data cells no longer in use from the realm
|
* Used for cleaning server data cells no longer in use from the realm
|
||||||
*/
|
*/
|
||||||
Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
private Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of world position key -> physics cell
|
* Map of world position key -> physics cell
|
||||||
*/
|
*/
|
||||||
Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
private Map<Long,PhysicsDataCell> posPhysicsMap = new HashMap<Long,PhysicsDataCell>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pooling for physics data cells
|
||||||
|
*/
|
||||||
|
private LinkedList<PhysicsDataCell> cellPool = new LinkedList<PhysicsDataCell>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of data cells cleaned up in the most recent frame
|
* Number of data cells cleaned up in the most recent frame
|
||||||
*/
|
*/
|
||||||
int numCleaned = 0;
|
private int numCleaned = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue of cells that need to have their physics regenerated (ie on block edits)
|
* Queue of cells that need to have their physics regenerated (ie on block edits)
|
||||||
*/
|
*/
|
||||||
Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
private Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pathfinder for the manager
|
* The pathfinder for the manager
|
||||||
*/
|
*/
|
||||||
VoxelPathfinder pathfinder;
|
private VoxelPathfinder pathfinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches lookups for nearby entities between simulate() calls
|
* Caches lookups for nearby entities between simulate() calls
|
||||||
@ -359,7 +364,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
if(posPhysicsMap.containsKey(key)){
|
if(posPhysicsMap.containsKey(key)){
|
||||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||||
cell.retireCell();
|
cell.destroyEntities();
|
||||||
}
|
}
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
//get data to generate with
|
//get data to generate with
|
||||||
@ -384,7 +389,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//the server will not be able to synchronize it properly.
|
//the server will not be able to synchronize it properly.
|
||||||
ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos);
|
||||||
ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos);
|
||||||
PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
PhysicsDataCell cell = this.getPhysicsDataCell(worldPos, terrainEntity, blockEntity);
|
||||||
cell.setTerrainChunk(terrainChunk);
|
cell.setTerrainChunk(terrainChunk);
|
||||||
cell.setBlockChunk(blockChunkData);
|
cell.setBlockChunk(blockChunkData);
|
||||||
cell.generatePhysics();
|
cell.generatePhysics();
|
||||||
@ -545,39 +550,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
continue;
|
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();
|
Globals.profiler.endCpuSample();
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
@ -598,26 +572,73 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
toCleanQueue.add(cell);
|
toCleanQueue.add(cell);
|
||||||
}
|
}
|
||||||
for(ServerDataCell cell : toCleanQueue){
|
for(ServerDataCell cell : toCleanQueue){
|
||||||
parent.deregisterCell(cell);
|
this.unloadCell(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();
|
loadedCellsLock.unlock();
|
||||||
this.serverTerrainManager.evictAll();
|
this.serverTerrainManager.evictAll();
|
||||||
toCleanQueue.clear();
|
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){
|
||||||
|
this.cellPool.add(releasedCell);
|
||||||
|
releasedCell.destroyEntities();
|
||||||
|
}
|
||||||
|
this.cellPositionMap.remove(cell);
|
||||||
|
this.cellTrackingMap.remove(cell);
|
||||||
|
this.cellPlayerlessFrameMap.remove(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a physics data cell from the pool
|
||||||
|
* @return The physics data cell
|
||||||
|
*/
|
||||||
|
private PhysicsDataCell getPhysicsDataCell(Vector3i worldPos, Entity physicsEntity, Entity blockPhysicsEntity){
|
||||||
|
PhysicsDataCell rVal = null;
|
||||||
|
loadedCellsLock.lock();
|
||||||
|
if(cellPool.size() > 0){
|
||||||
|
rVal = this.cellPool.poll();
|
||||||
|
rVal.reset(worldPos, physicsEntity, blockPhysicsEntity);
|
||||||
|
} else {
|
||||||
|
rVal = PhysicsDataCell.createPhysicsCell(physicsEntity, blockPhysicsEntity);
|
||||||
|
}
|
||||||
|
loadedCellsLock.unlock();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get data cell at a given real point in this realm
|
* Get data cell at a given real point in this realm
|
||||||
* @param point The real point
|
* @param point The real point
|
||||||
@ -819,7 +840,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos);
|
||||||
ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos);
|
ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos);
|
||||||
|
|
||||||
PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity);
|
PhysicsDataCell targetCell = this.getPhysicsDataCell(worldPos, terrainEntity, blockEntity);
|
||||||
if(cell == null){
|
if(cell == null){
|
||||||
posPhysicsMap.put(key, targetCell);
|
posPhysicsMap.put(key, targetCell);
|
||||||
} else {
|
} else {
|
||||||
@ -847,7 +868,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
|
|
||||||
//create physics entities
|
//create physics entities
|
||||||
if(cell != null){
|
if(cell != null){
|
||||||
cell.retireCell();
|
cell.destroyEntities();
|
||||||
cell.generatePhysics();
|
cell.generatePhysics();
|
||||||
} else {
|
} else {
|
||||||
targetCell.generatePhysics();
|
targetCell.generatePhysics();
|
||||||
@ -882,6 +903,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
Long cellKey = this.getServerDataCellKey(localWorldPos);
|
Long cellKey = this.getServerDataCellKey(localWorldPos);
|
||||||
|
|
||||||
loadedCellsLock.lock();
|
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);
|
groundDataCells.put(cellKey,rVal);
|
||||||
cellPlayerlessFrameMap.put(rVal,0);
|
cellPlayerlessFrameMap.put(rVal,0);
|
||||||
LoggerInterface.loggerEngine.DEBUG("Create server data cell with key " + cellKey);
|
LoggerInterface.loggerEngine.DEBUG("Create server data cell with key " + cellKey);
|
||||||
@ -1154,6 +1178,21 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
return cellPlayerlessFrameMap;
|
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
|
@Override
|
||||||
public List<Vector3d> findPath(Vector3d start, Vector3d end){
|
public List<Vector3d> findPath(Vector3d start, Vector3d end){
|
||||||
Vector3i startChunkPos = ServerWorldData.convertRealToChunkSpace(start);
|
Vector3i startChunkPos = ServerWorldData.convertRealToChunkSpace(start);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package electrosphere.server.datacell.physics;
|
|||||||
import electrosphere.client.block.BlockChunkData;
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
import electrosphere.client.terrain.cache.ChunkData;
|
||||||
import electrosphere.client.terrain.data.TerrainChunkData;
|
import electrosphere.client.terrain.data.TerrainChunkData;
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
@ -11,39 +10,54 @@ import electrosphere.entity.types.terrain.BlockChunkEntity;
|
|||||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||||
import electrosphere.renderer.meshgen.BlockMeshgen;
|
import electrosphere.renderer.meshgen.BlockMeshgen;
|
||||||
import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
|
import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
import org.ode4j.ode.DBody;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entity which contains physics for terrain for a given chunk on the server
|
* An entity which contains physics for terrain for a given chunk on the server
|
||||||
*/
|
*/
|
||||||
public class PhysicsDataCell {
|
public class PhysicsDataCell {
|
||||||
|
|
||||||
Vector3i worldPos;
|
|
||||||
|
|
||||||
Entity physicsEntity;
|
/**
|
||||||
Entity blockPhysicsEntity;
|
* The terrain physics entity
|
||||||
|
*/
|
||||||
|
private Entity physicsEntity;
|
||||||
|
|
||||||
ServerTerrainChunk terrainChunk;
|
/**
|
||||||
BlockChunkData blockChunk;
|
* The block physics entity
|
||||||
|
*/
|
||||||
DBody physicsObject;
|
private Entity blockPhysicsEntity;
|
||||||
|
|
||||||
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 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];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The terrain vertex data
|
* The terrain vertex data
|
||||||
*/
|
*/
|
||||||
TerrainChunkData terrainChunkData;
|
private TerrainChunkData terrainChunkData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block vertex data
|
* The block vertex data
|
||||||
*/
|
*/
|
||||||
BlockMeshData blockData;
|
private BlockMeshData blockData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a physics cell
|
* Creates a physics cell
|
||||||
@ -52,7 +66,6 @@ public class PhysicsDataCell {
|
|||||||
* @return The cell
|
* @return The cell
|
||||||
*/
|
*/
|
||||||
public static PhysicsDataCell createPhysicsCell(
|
public static PhysicsDataCell createPhysicsCell(
|
||||||
Vector3i worldPos,
|
|
||||||
Entity physicsEntity,
|
Entity physicsEntity,
|
||||||
Entity blockPhysicsEntity
|
Entity blockPhysicsEntity
|
||||||
|
|
||||||
@ -60,19 +73,40 @@ public class PhysicsDataCell {
|
|||||||
PhysicsDataCell rVal = new PhysicsDataCell();
|
PhysicsDataCell rVal = new PhysicsDataCell();
|
||||||
rVal.physicsEntity = physicsEntity;
|
rVal.physicsEntity = physicsEntity;
|
||||||
rVal.blockPhysicsEntity = blockPhysicsEntity;
|
rVal.blockPhysicsEntity = blockPhysicsEntity;
|
||||||
rVal.worldPos = worldPos;
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retires a physics data cell
|
* Retires a physics data cell
|
||||||
*/
|
*/
|
||||||
public void retireCell(){
|
public void destroyEntities(){
|
||||||
ServerEntityUtils.destroyEntity(physicsEntity);
|
ServerEntityUtils.destroyEntity(physicsEntity);
|
||||||
this.physicsEntity = null;
|
this.physicsEntity = null;
|
||||||
ServerEntityUtils.destroyEntity(blockPhysicsEntity);
|
ServerEntityUtils.destroyEntity(blockPhysicsEntity);
|
||||||
this.blockPhysicsEntity = null;
|
this.blockPhysicsEntity = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Generates the physics entity for this chunk
|
||||||
@ -105,15 +139,6 @@ public class PhysicsDataCell {
|
|||||||
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
localBlockPhysicsEntity.putData(EntityDataStrings.BLOCK_ENTITY, 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
|
* Fills in the internal arrays of data for generate terrain models
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user