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 | ||||
| Increase human move speed | ||||
| 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 | ||||
|      */ | ||||
|     static final int UNLOAD_FRAME_THRESHOLD = 100; | ||||
|     private static final int UNLOAD_FRAME_THRESHOLD = 100; | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     static final double MACRO_SCANNING_BIG_NUMBER = 10000; | ||||
|     private static final double MACRO_SCANNING_BIG_NUMBER = 10000; | ||||
| 
 | ||||
|     /** | ||||
|      * Used for generating physics chunks | ||||
|      */ | ||||
|     ExecutorService generationService = null; | ||||
|     private ExecutorService generationService = null; | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     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 | ||||
|      */ | ||||
|     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<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<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>(); | ||||
|     private Map<ServerDataCell,Integer> cellPlayerlessFrameMap = new HashMap<ServerDataCell,Integer>(); | ||||
| 
 | ||||
|     /** | ||||
|      * A map of ServerDataCell->GriddedDataCellTrackingData | ||||
|      */ | ||||
|     Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>(); | ||||
|     private Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap = new HashMap<ServerDataCell,GriddedDataCellTrackingData>(); | ||||
| 
 | ||||
|     /** | ||||
|      * Loaded cells | ||||
|      */ | ||||
|     ReentrantLock loadedCellsLock = new ReentrantLock(); | ||||
|     private ReentrantLock loadedCellsLock = new ReentrantLock(); | ||||
| 
 | ||||
|     /** | ||||
|      * Parent realm | ||||
|      */ | ||||
|     Realm parent; | ||||
|     private Realm parent; | ||||
| 
 | ||||
|     /** | ||||
|      * The world data of the parent | ||||
|      */ | ||||
|     ServerWorldData serverWorldData; | ||||
|     private ServerWorldData serverWorldData; | ||||
| 
 | ||||
|     /** | ||||
|      * Manager for terrain for this particular cell manager | ||||
|      */ | ||||
|     ServerTerrainManager serverTerrainManager; | ||||
|     private ServerTerrainManager serverTerrainManager; | ||||
| 
 | ||||
|     /** | ||||
|      * Manager for fluids for this particular cell manager | ||||
|      */ | ||||
|     ServerFluidManager serverFluidManager; | ||||
|     private ServerFluidManager serverFluidManager; | ||||
| 
 | ||||
|     /** | ||||
|      * Lock for terrain editing | ||||
|      */ | ||||
|     Semaphore terrainEditLock = new Semaphore(1); | ||||
|     private Semaphore terrainEditLock = new Semaphore(1); | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>(); | ||||
|     private Set<ServerDataCell> toCleanQueue = new HashSet<ServerDataCell>(); | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     int numCleaned = 0; | ||||
|     private int numCleaned = 0; | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     VoxelPathfinder pathfinder; | ||||
|     private VoxelPathfinder pathfinder; | ||||
| 
 | ||||
|     /** | ||||
|      * Caches lookups for nearby entities between simulate() calls | ||||
| @ -359,7 +364,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager | ||||
|         loadedCellsLock.lock(); | ||||
|         if(posPhysicsMap.containsKey(key)){ | ||||
|             PhysicsDataCell cell = posPhysicsMap.get(key); | ||||
|             cell.retireCell(); | ||||
|             cell.destroyEntities(); | ||||
|         } | ||||
|         loadedCellsLock.unlock(); | ||||
|         //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. | ||||
|         ServerEntityUtils.initiallyPositionEntity(parent,blockEntity,realPos); | ||||
|         ServerEntityUtils.initiallyPositionEntity(parent,terrainEntity,realPos); | ||||
|         PhysicsDataCell cell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity); | ||||
|         PhysicsDataCell cell = this.getPhysicsDataCell(worldPos, terrainEntity, blockEntity); | ||||
|         cell.setTerrainChunk(terrainChunk); | ||||
|         cell.setBlockChunk(blockChunkData); | ||||
|         cell.generatePhysics(); | ||||
| @ -545,39 +550,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 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); | ||||
|                 this.unloadCell(cell); | ||||
|                  | ||||
|             } | ||||
|             Globals.profiler.endCpuSample(); | ||||
|             loadedCellsLock.unlock(); | ||||
| @ -598,26 +572,73 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager | ||||
|             toCleanQueue.add(cell); | ||||
|         } | ||||
|         for(ServerDataCell cell : toCleanQueue){ | ||||
|             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); | ||||
|             } | ||||
|             this.unloadCell(cell); | ||||
|         } | ||||
|         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){ | ||||
|             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 | ||||
|      * @param point The real point | ||||
| @ -819,7 +840,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager | ||||
|         ServerEntityUtils.initiallyPositionEntity(realm,blockEntity,realPos); | ||||
|         ServerEntityUtils.initiallyPositionEntity(realm,terrainEntity,realPos); | ||||
| 
 | ||||
|         PhysicsDataCell targetCell = PhysicsDataCell.createPhysicsCell(worldPos, terrainEntity, blockEntity); | ||||
|         PhysicsDataCell targetCell = this.getPhysicsDataCell(worldPos, terrainEntity, blockEntity); | ||||
|         if(cell == null){ | ||||
|             posPhysicsMap.put(key, targetCell); | ||||
|         } else { | ||||
| @ -847,7 +868,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager | ||||
| 
 | ||||
|                 //create physics entities | ||||
|                 if(cell != null){ | ||||
|                     cell.retireCell(); | ||||
|                     cell.destroyEntities(); | ||||
|                     cell.generatePhysics(); | ||||
|                 } else { | ||||
|                     targetCell.generatePhysics(); | ||||
| @ -882,6 +903,9 @@ 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); | ||||
| @ -1154,6 +1178,21 @@ 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,7 +3,6 @@ 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; | ||||
| @ -11,39 +10,54 @@ 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; | ||||
|      | ||||
|     Entity physicsEntity; | ||||
|     Entity blockPhysicsEntity; | ||||
|     /** | ||||
|      * The terrain physics entity | ||||
|      */ | ||||
|     private Entity physicsEntity; | ||||
| 
 | ||||
|     ServerTerrainChunk terrainChunk; | ||||
|     BlockChunkData blockChunk; | ||||
|      | ||||
|     DBody physicsObject; | ||||
|     /** | ||||
|      * The block physics entity | ||||
|      */ | ||||
|     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 | ||||
|      */ | ||||
|     TerrainChunkData terrainChunkData; | ||||
|     private TerrainChunkData terrainChunkData; | ||||
| 
 | ||||
|     /** | ||||
|      * The block vertex data | ||||
|      */ | ||||
|     BlockMeshData blockData; | ||||
|     private BlockMeshData blockData; | ||||
|      | ||||
|     /** | ||||
|      * Creates a physics cell | ||||
| @ -52,7 +66,6 @@ public class PhysicsDataCell { | ||||
|      * @return The cell | ||||
|      */ | ||||
|     public static PhysicsDataCell createPhysicsCell( | ||||
|         Vector3i worldPos, | ||||
|         Entity physicsEntity, | ||||
|         Entity blockPhysicsEntity | ||||
| 
 | ||||
| @ -60,19 +73,40 @@ 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 retireCell(){ | ||||
|     public void destroyEntities(){ | ||||
|         ServerEntityUtils.destroyEntity(physicsEntity); | ||||
|         this.physicsEntity = null; | ||||
|         ServerEntityUtils.destroyEntity(blockPhysicsEntity); | ||||
|         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 | ||||
| @ -105,15 +139,6 @@ 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