246 lines
11 KiB
Java
246 lines
11 KiB
Java
package electrosphere.server.datacell.physics;
|
|
|
|
import electrosphere.client.terrain.cache.ChunkData;
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.entity.Entity;
|
|
import electrosphere.entity.EntityDataStrings;
|
|
import electrosphere.entity.ServerEntityUtils;
|
|
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.terrain.manager.ServerTerrainChunk;
|
|
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
|
|
|
import org.joml.Vector3d;
|
|
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;
|
|
|
|
DBody physicsObject;
|
|
|
|
Realm realm;
|
|
ServerTerrainManager serverTerrainManager;
|
|
|
|
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];
|
|
|
|
|
|
PhysicsDataCell(){
|
|
|
|
}
|
|
|
|
/**
|
|
* Creates a physics cell
|
|
* @param realm The realm to create it in
|
|
* @param worldPos The world position of the cell
|
|
* @return The cell
|
|
*/
|
|
public static PhysicsDataCell createPhysicsCell(
|
|
Realm realm,
|
|
Vector3i worldPos
|
|
){
|
|
PhysicsDataCell rVal = new PhysicsDataCell();
|
|
rVal.realm = realm;
|
|
rVal.serverTerrainManager = realm.getServerWorldData().getServerTerrainManager();
|
|
rVal.worldPos = worldPos;
|
|
return rVal;
|
|
}
|
|
|
|
/**
|
|
* Retires a physics data cell
|
|
*/
|
|
public void retireCell(){
|
|
ServerEntityUtils.destroyEntity(physicsEntity);
|
|
this.physicsEntity = null;
|
|
ServerEntityUtils.destroyEntity(blockPhysicsEntity);
|
|
this.blockPhysicsEntity = null;
|
|
}
|
|
|
|
/**
|
|
* Generates the physics entity for this chunk
|
|
*/
|
|
public void generatePhysics(){
|
|
//if the entity hasn't already been created for some reason, need to create it
|
|
if(physicsEntity == null){
|
|
|
|
//
|
|
//fill in weights and types maps
|
|
//
|
|
this.fillInData();
|
|
|
|
Vector3d realPos = new Vector3d(
|
|
worldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
|
worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
|
worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
|
|
);
|
|
physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types);
|
|
physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
|
}
|
|
if(blockPhysicsEntity == null){
|
|
Vector3d realPos = new Vector3d(
|
|
worldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
|
worldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
|
|
worldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
|
|
);
|
|
BlockMeshData meshData = BlockMeshgen.rasterize(realm.getServerWorldData().getServerBlockManager().getChunk(worldPos.x, worldPos.y, worldPos.z));
|
|
blockPhysicsEntity = BlockChunkEntity.serverCreateBlockChunkEntity(realm, realPos, meshData);
|
|
blockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
|
}
|
|
// //then actually perform the attach
|
|
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
|
|
// Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
|
|
// realm.getCollisionEngine().registerPhysicsEntity(physicsEntity);
|
|
}
|
|
|
|
/**
|
|
* Destroys the physics for this data cell
|
|
*/
|
|
public void destroyPhysics(){
|
|
Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
|
|
realm.getCollisionEngine().destroyPhysics(physicsEntity);
|
|
realm.getCollisionEngine().destroyPhysics(blockPhysicsEntity);
|
|
}
|
|
|
|
/**
|
|
* Fills in the internal arrays of data for generate terrain models
|
|
*/
|
|
private void fillInData(){
|
|
//
|
|
//fill in data
|
|
//
|
|
//main chunk
|
|
ServerTerrainChunk currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z);
|
|
for(int x = 0; x < ChunkData.CHUNK_DATA_SIZE; x++){
|
|
for(int y = 0; y < ChunkData.CHUNK_DATA_SIZE; y++){
|
|
for(int z = 0; z < ChunkData.CHUNK_DATA_SIZE; z++){
|
|
weights[x][y][z] = currentChunk.getWeight(x,y,z);
|
|
types[x][y][z] = currentChunk.getType(x,y,z);
|
|
}
|
|
}
|
|
}
|
|
// //face X
|
|
// if(worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
|
|
// types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j);
|
|
// }
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[ChunkData.CHUNK_SIZE][i][j] = 0;
|
|
// types[ChunkData.CHUNK_SIZE][i][j] = 0;
|
|
// }
|
|
// }
|
|
// }
|
|
// //face Y
|
|
// if(worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getWeight(i, 0, j);
|
|
// types[i][ChunkData.CHUNK_SIZE][j] = currentChunk.getType(i, 0, j);
|
|
// }
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[i][ChunkData.CHUNK_SIZE][j] = 0;
|
|
// types[i][ChunkData.CHUNK_SIZE][j] = 0;
|
|
// }
|
|
// }
|
|
// }
|
|
// //face Z
|
|
// if(worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y, worldPos.z + 1);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, j, 0);
|
|
// types[i][j][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, j, 0);
|
|
// }
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
|
// weights[i][j][ChunkData.CHUNK_SIZE] = 0;
|
|
// types[i][j][ChunkData.CHUNK_SIZE] = 0;
|
|
// }
|
|
// }
|
|
// }
|
|
//edge X-Y
|
|
// if(
|
|
// worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
|
|
// worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
|
|
// ){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getWeight(0, 0, i);
|
|
// types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = currentChunk.getType(0, 0, i);
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
|
|
// types [ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][i] = 0;
|
|
// }
|
|
// }
|
|
// //edge X-Z
|
|
// if(
|
|
// worldPos.x + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
|
|
// worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
|
|
// ){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y, worldPos.z + 1);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, i, 0);
|
|
// types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, i, 0);
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
|
|
// types [ChunkData.CHUNK_SIZE][i][ChunkData.CHUNK_SIZE] = 0;
|
|
// }
|
|
// }
|
|
// //edge Y-Z
|
|
// if(
|
|
// worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
|
|
// worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
|
|
// ){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x, worldPos.y + 1, worldPos.z + 1);
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(i, 0, 0);
|
|
// types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(i, 0, 0);
|
|
// }
|
|
// } else {
|
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
|
// weights[i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
|
// types [i][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
|
// }
|
|
// }
|
|
// if(
|
|
// worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
|
|
// worldPos.y + 1 < realm.getServerWorldData().getWorldSizeDiscrete() &&
|
|
// worldPos.z + 1 < realm.getServerWorldData().getWorldSizeDiscrete()
|
|
// ){
|
|
// currentChunk = serverTerrainManager.getChunk(worldPos.x + 1, worldPos.y + 1, worldPos.z + 1);
|
|
// weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getWeight(0, 0, 0);
|
|
// types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = currentChunk.getType(0, 0, 0);
|
|
// } else {
|
|
// weights[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
|
// types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
|
// }
|
|
}
|
|
|
|
}
|