fix block meshes
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-24 11:16:31 -05:00
parent 21e2ec7b06
commit e8c38584fa
11 changed files with 132 additions and 43 deletions

View File

@ -1150,6 +1150,10 @@ Add server manager for block chunk data & management
Add endpoint to request strided block data Add endpoint to request strided block data
Add client side handling of block endpoint Add client side handling of block endpoint
Add server-driven block rasterizer with LOD Add server-driven block rasterizer with LOD
Convert PhysicsEntityUtils to use generic interface to load tri geom rigid bodies
(11/24/2024)
Fix winding order on block meshes
# TODO # TODO

View File

@ -7,7 +7,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock;
import io.github.studiorailgun.HashUtils; import io.github.studiorailgun.HashUtils;
@ -64,16 +64,16 @@ public class BlockChunkCache {
/** /**
* The lock for thread safety * The lock for thread safety
*/ */
Semaphore lock = new Semaphore(1); ReentrantLock lock = new ReentrantLock();
/** /**
* Gets the collection of server block chunks that are cached * Gets the collection of server block chunks that are cached
* @return The collection of chunks * @return The collection of chunks
*/ */
public Collection<BlockChunkData> getContents(){ public Collection<BlockChunkData> getContents(){
lock.acquireUninterruptibly(); lock.lock();
Collection<BlockChunkData> rVal = Collections.unmodifiableCollection(cacheMapFullRes.values()); Collection<BlockChunkData> rVal = Collections.unmodifiableCollection(cacheMapFullRes.values());
lock.release(); lock.unlock();
return rVal; return rVal;
} }
@ -81,13 +81,13 @@ public class BlockChunkCache {
* Evicts all chunks in the cache * Evicts all chunks in the cache
*/ */
public void clear(){ public void clear(){
lock.acquireUninterruptibly(); lock.lock();
cacheMapFullRes.clear(); cacheMapFullRes.clear();
cacheMapHalfRes.clear(); cacheMapHalfRes.clear();
cacheMapQuarterRes.clear(); cacheMapQuarterRes.clear();
cacheMapEighthRes.clear(); cacheMapEighthRes.clear();
cacheMapSixteenthRes.clear(); cacheMapSixteenthRes.clear();
lock.release(); lock.unlock();
} }
/** /**
@ -101,12 +101,12 @@ public class BlockChunkCache {
public BlockChunkData get(int worldX, int worldY, int worldZ, int stride){ public BlockChunkData get(int worldX, int worldY, int worldZ, int stride){
BlockChunkData rVal = null; BlockChunkData rVal = null;
Long key = this.getKey(worldX, worldY, worldZ); Long key = this.getKey(worldX, worldY, worldZ);
lock.acquireUninterruptibly(); lock.lock();
queryRecencyQueue.remove(key); queryRecencyQueue.remove(key);
queryRecencyQueue.add(0, key); queryRecencyQueue.add(0, key);
Map<Long,BlockChunkData> cache = this.getCache(stride); Map<Long,BlockChunkData> cache = this.getCache(stride);
rVal = cache.get(key); rVal = cache.get(key);
lock.release(); lock.unlock();
return rVal; return rVal;
} }
@ -120,7 +120,7 @@ public class BlockChunkCache {
*/ */
public void add(int worldX, int worldY, int worldZ, int stride, BlockChunkData chunk){ public void add(int worldX, int worldY, int worldZ, int stride, BlockChunkData chunk){
Long key = this.getKey(worldX, worldY, worldZ); Long key = this.getKey(worldX, worldY, worldZ);
lock.acquireUninterruptibly(); lock.lock();
queryRecencyQueue.add(0, key); queryRecencyQueue.add(0, key);
Map<Long,BlockChunkData> cache = this.getCache(stride); Map<Long,BlockChunkData> cache = this.getCache(stride);
cache.put(key, chunk); cache.put(key, chunk);
@ -132,7 +132,7 @@ public class BlockChunkCache {
cacheMapEighthRes.remove(oldKey); cacheMapEighthRes.remove(oldKey);
cacheMapSixteenthRes.remove(oldKey); cacheMapSixteenthRes.remove(oldKey);
} }
lock.release(); lock.unlock();
} }
/** /**
@ -145,10 +145,10 @@ public class BlockChunkCache {
*/ */
public boolean containsChunk(int worldX, int worldY, int worldZ, int stride){ public boolean containsChunk(int worldX, int worldY, int worldZ, int stride){
Long key = this.getKey(worldX,worldY,worldZ); Long key = this.getKey(worldX,worldY,worldZ);
lock.acquireUninterruptibly(); lock.lock();
Map<Long,BlockChunkData> cache = this.getCache(stride); Map<Long,BlockChunkData> cache = this.getCache(stride);
boolean rVal = cache.containsKey(key); boolean rVal = cache.containsKey(key);
lock.release(); lock.unlock();
return rVal; return rVal;
} }
@ -172,9 +172,9 @@ public class BlockChunkCache {
*/ */
public boolean chunkIsQueued(int worldX, int worldY, int worldZ){ public boolean chunkIsQueued(int worldX, int worldY, int worldZ){
Long key = this.getKey(worldX,worldY,worldZ); Long key = this.getKey(worldX,worldY,worldZ);
lock.acquireUninterruptibly(); lock.lock();
boolean rVal = this.queuedChunkMap.containsKey(key); boolean rVal = this.queuedChunkMap.containsKey(key);
lock.release(); lock.unlock();
return rVal; return rVal;
} }
@ -186,9 +186,9 @@ public class BlockChunkCache {
*/ */
public void queueChunk(int worldX, int worldY, int worldZ){ public void queueChunk(int worldX, int worldY, int worldZ){
Long key = this.getKey(worldX,worldY,worldZ); Long key = this.getKey(worldX,worldY,worldZ);
lock.acquireUninterruptibly(); lock.lock();
this.queuedChunkMap.put(key,true); this.queuedChunkMap.put(key,true);
lock.release(); lock.unlock();
} }
/** /**
@ -200,9 +200,9 @@ public class BlockChunkCache {
*/ */
public void unqueueChunk(int worldX, int worldY, int worldZ, int stride){ public void unqueueChunk(int worldX, int worldY, int worldZ, int stride){
Long key = this.getKey(worldX,worldY,worldZ); Long key = this.getKey(worldX,worldY,worldZ);
lock.acquireUninterruptibly(); lock.lock();
this.queuedChunkMap.remove(key); this.queuedChunkMap.remove(key);
lock.release(); lock.unlock();
} }
/** /**

View File

@ -19,7 +19,7 @@ import org.ode4j.ode.DMass;
import org.ode4j.ode.DSphere; import org.ode4j.ode.DSphere;
import org.ode4j.ode.DTriMesh; import org.ode4j.ode.DTriMesh;
import electrosphere.entity.types.terrain.TerrainChunkData; import electrosphere.entity.state.collidable.TriGeomData;
/** /**
* Utilities for creating types of rigid bodies * Utilities for creating types of rigid bodies
@ -256,7 +256,7 @@ public class CollisionBodyCreation {
* @param data The terrain data * @param data The terrain data
* @return The DBody * @return The DBody
*/ */
public static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TerrainChunkData data, long categoryBits){ public static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TriGeomData data, long categoryBits){
DBody body = null; DBody body = null;
//create trimesh //create trimesh

View File

@ -18,9 +18,9 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.collidable.ClientCollidableTree; import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree; import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.collidable.TriGeomData;
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree; import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
import electrosphere.entity.state.physicssync.ServerPhysicsSyncTree; import electrosphere.entity.state.physicssync.ServerPhysicsSyncTree;
import electrosphere.entity.types.terrain.TerrainChunkData;
import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.collidable.CollidableTemplate;
import electrosphere.game.server.world.ServerWorldData; import electrosphere.game.server.world.ServerWorldData;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
@ -487,7 +487,7 @@ public class PhysicsEntityUtils {
* @param data The terrain description * @param data The terrain description
* @return The rigid body created (note, attachment has already been performed) * @return The rigid body created (note, attachment has already been performed)
*/ */
public static void clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ public static void clientAttachTriGeomRigidBody(Entity terrain, TriGeomData data){
DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(Globals.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT); DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(Globals.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
Collidable collidable = new Collidable(terrain,Collidable.TYPE_TERRAIN, false); Collidable collidable = new Collidable(terrain,Collidable.TYPE_TERRAIN, false);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
@ -502,7 +502,7 @@ public class PhysicsEntityUtils {
* @param data The terrain description * @param data The terrain description
* @return The rigid body created (note, attachment has already been performed) * @return The rigid body created (note, attachment has already been performed)
*/ */
public static DBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ public static DBody serverAttachTriGeomRigidBody(Entity terrain, TriGeomData data){
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain); Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(terrainRealm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT); DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(terrainRealm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT);

View File

@ -0,0 +1,20 @@
package electrosphere.entity.state.collidable;
/**
* A data object that can be used to generate a collidable with arbitrary geometry
*/
public interface TriGeomData {
/**
* Gets the vertex data
* @return the vertex data
*/
public float[] getVertices();
/**
* Gets the face element data
* @return the face element data
*/
public int[] getFaceElements();
}

View File

@ -9,6 +9,7 @@ import org.joml.Vector3d;
import electrosphere.client.block.BlockChunkData; import electrosphere.client.block.BlockChunkData;
import electrosphere.client.block.cells.BlockDrawCell; import electrosphere.client.block.cells.BlockDrawCell;
import electrosphere.client.block.cells.BlockTextureAtlas; import electrosphere.client.block.cells.BlockTextureAtlas;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.queue.QueuedModel; import electrosphere.engine.assetmanager.queue.QueuedModel;
import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.ClientEntityUtils;
@ -16,10 +17,12 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
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;
/** /**
* Generates block chunk entities * Generates block chunk entities
@ -63,7 +66,7 @@ public class BlockChunkEntity {
})); }));
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){ if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
// PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); PhysicsEntityUtils.clientAttachTriGeomRigidBody(rVal, data);
CollisionObjUtils.clientPositionCharacter(rVal, new Vector3d(EntityUtils.getPosition(rVal)), new Quaterniond()); CollisionObjUtils.clientPositionCharacter(rVal, new Vector3d(EntityUtils.getPosition(rVal)), new Quaterniond());
} else { } else {
EntityCreationUtils.bypassShadowPass(rVal); EntityCreationUtils.bypassShadowPass(rVal);
@ -99,6 +102,34 @@ public class BlockChunkEntity {
return rVal; return rVal;
} }
/**
* Creates a block chunk entity on the server
* @param realm The realm
* @param position The position of the chunk
* @param weights The weights for the block chunk
* @param values The values of each voxel in the chunk
* @return The block entity
*/
public static Entity serverCreateBlockChunkEntity(Realm realm, Vector3d position, BlockMeshData blockChunkData){
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
if(blockChunkData.getVertices().length > 0){
PhysicsEntityUtils.serverAttachTriGeomRigidBody(rVal, blockChunkData);
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
}
//position entity
//this needs to be called at the end of this function.
//Burried underneath this is function call to initialize a server side entity.
//The server initialization logic checks what type of entity this is, if this function is called prior to its type being stored
//the server will not be able to synchronize it properly.
ServerEntityUtils.initiallyPositionEntity(realm,rVal,position);
return rVal;
}
/** /**
* Halts all running generation threads * Halts all running generation threads
*/ */

View File

@ -6,6 +6,7 @@ import java.util.concurrent.Executors;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.client.block.BlockChunkData;
import electrosphere.client.terrain.cells.ClientDrawCellManager; import electrosphere.client.terrain.cells.ClientDrawCellManager;
import electrosphere.client.terrain.cells.DrawCell; import electrosphere.client.terrain.cells.DrawCell;
import electrosphere.client.terrain.cells.VoxelTextureAtlas; import electrosphere.client.terrain.cells.VoxelTextureAtlas;
@ -64,8 +65,8 @@ public class TerrainChunk {
if(Globals.clientScene.containsEntity(rVal)){ if(Globals.clientScene.containsEntity(rVal)){
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete); String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete);
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
if(levelOfDetail == ClientDrawCellManager.FULL_RES_LOD && data.faceElements.length > 0){ if(levelOfDetail == BlockChunkData.LOD_FULL_RES && data.faceElements.length > 0){
PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); PhysicsEntityUtils.clientAttachTriGeomRigidBody(rVal, data);
CollisionObjUtils.clientPositionCharacter(rVal, new Vector3d(EntityUtils.getPosition(rVal)), new Quaterniond()); CollisionObjUtils.clientPositionCharacter(rVal, new Vector3d(EntityUtils.getPosition(rVal)), new Quaterniond());
} else { } else {
EntityCreationUtils.bypassShadowPass(rVal); EntityCreationUtils.bypassShadowPass(rVal);
@ -116,7 +117,7 @@ public class TerrainChunk {
Entity rVal = EntityCreationUtils.createServerEntity(realm, position); Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
if(data.vertices.length > 0){ if(data.vertices.length > 0){
PhysicsEntityUtils.serverAttachTerrainChunkRigidBody(rVal, data); PhysicsEntityUtils.serverAttachTriGeomRigidBody(rVal, data);
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
// ServerEntityUtils.initiallyPositionEntity(realm, rVal, position); // ServerEntityUtils.initiallyPositionEntity(realm, rVal, position);
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);

View File

@ -5,10 +5,12 @@ import java.nio.IntBuffer;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import electrosphere.entity.state.collidable.TriGeomData;
/** /**
* The data required to generate a texture * The data required to generate a texture
*/ */
public class TerrainChunkData { public class TerrainChunkData implements TriGeomData {
//the verts //the verts
float[] vertices; float[] vertices;
@ -81,10 +83,7 @@ public class TerrainChunkData {
ratioBuffer.put(this.textureRatioVectors); ratioBuffer.put(this.textureRatioVectors);
} }
/** @Override
* Gets the vertex data
* @return the vertex data
*/
public float[] getVertices(){ public float[] getVertices(){
return vertices; return vertices;
} }
@ -97,10 +96,7 @@ public class TerrainChunkData {
return normals; return normals;
} }
/** @Override
* Gets the face element data
* @return the face element data
*/
public int[] getFaceElements(){ public int[] getFaceElements(){
return faceElements; return faceElements;
} }

View File

@ -13,6 +13,7 @@ import org.lwjgl.opengl.GL40;
import electrosphere.client.block.BlockChunkData; import electrosphere.client.block.BlockChunkData;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.collidable.TriGeomData;
import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Mesh;
import electrosphere.renderer.model.Model; import electrosphere.renderer.model.Model;
@ -120,8 +121,8 @@ public class BlockMeshgen {
indices.add(2); indices.add(2);
indices.add(3); indices.add(3);
indices.add(0); indices.add(0);
indices.add(1);
indices.add(3); indices.add(3);
indices.add(1);
//normals //normals
normals.add(new Vector3f(0,0,-1)); normals.add(new Vector3f(0,0,-1));
normals.add(new Vector3f(0,0,-1)); normals.add(new Vector3f(0,0,-1));
@ -144,8 +145,8 @@ public class BlockMeshgen {
verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER)); verts.add(new Vector3f(quad.x, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices //indices
indices.add(4); indices.add(4);
indices.add(6);
indices.add(7); indices.add(7);
indices.add(6);
indices.add(4); indices.add(4);
indices.add(5); indices.add(5);
indices.add(7); indices.add(7);
@ -173,8 +174,8 @@ public class BlockMeshgen {
indices.add( 8); indices.add( 8);
indices.add(10); indices.add(10);
indices.add(11); indices.add(11);
indices.add( 8);
indices.add( 9); indices.add( 9);
indices.add( 8);
indices.add(11); indices.add(11);
//normals //normals
normals.add(new Vector3f(0,-1,0)); normals.add(new Vector3f(0,-1,0));
@ -198,8 +199,8 @@ public class BlockMeshgen {
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER)); verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices //indices
indices.add(12); indices.add(12);
indices.add(14);
indices.add(15); indices.add(15);
indices.add(14);
indices.add(12); indices.add(12);
indices.add(13); indices.add(13);
indices.add(15); indices.add(15);
@ -229,8 +230,8 @@ public class BlockMeshgen {
indices.add(18); indices.add(18);
indices.add(19); indices.add(19);
indices.add(16); indices.add(16);
indices.add(17);
indices.add(19); indices.add(19);
indices.add(17);
//normals //normals
normals.add(new Vector3f(1,0,0)); normals.add(new Vector3f(1,0,0));
normals.add(new Vector3f(1,0,0)); normals.add(new Vector3f(1,0,0));
@ -254,8 +255,8 @@ public class BlockMeshgen {
verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER)); verts.add(new Vector3f(quad.x + quad.w, quad.y + quad.h, quad.z + depth).mul(BlockChunkData.BLOCK_SIZE_MULTIPLIER));
//indices //indices
indices.add(20); indices.add(20);
indices.add(22);
indices.add(23); indices.add(23);
indices.add(22);
indices.add(20); indices.add(20);
indices.add(21); indices.add(21);
indices.add(23); indices.add(23);
@ -466,7 +467,7 @@ public class BlockMeshgen {
/** /**
* The final rasterization data that is emitted * The final rasterization data that is emitted
*/ */
public static class BlockMeshData { public static class BlockMeshData implements TriGeomData {
//the verts //the verts
float[] vertices; float[] vertices;
//normals //normals
@ -480,6 +481,15 @@ public class BlockMeshgen {
FloatBuffer normalBuffer; FloatBuffer normalBuffer;
IntBuffer faceBuffer; IntBuffer faceBuffer;
FloatBuffer uvBuffer; FloatBuffer uvBuffer;
@Override
public float[] getVertices() {
return vertices;
}
@Override
public int[] getFaceElements() {
return faceElements;
}
} }
/** /**

View File

@ -121,6 +121,16 @@ public class ServerBlockManager {
returnedChunk.setWorldY(worldY); returnedChunk.setWorldY(worldY);
returnedChunk.setWorldZ(worldZ); returnedChunk.setWorldZ(worldZ);
returnedChunk.setHomogenousValue(0); returnedChunk.setHomogenousValue(0);
if(worldX == 0 && worldY == 0 && worldZ == 0){
returnedChunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
for(int x = 3; x < 16; x++){
for(int y = 8; y < 16; y++){
for(int z = 3; z < 16; z++){
returnedChunk.setType(x, y, z, 1);
}
}
}
}
} }
this.chunkCache.add(worldX, worldY, worldZ, BlockChunkData.LOD_FULL_RES, returnedChunk); this.chunkCache.add(worldX, worldY, worldZ, BlockChunkData.LOD_FULL_RES, returnedChunk);
} }

View File

@ -5,7 +5,10 @@ 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;
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.BlockMeshData;
import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.Realm;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
@ -22,6 +25,7 @@ public class PhysicsDataCell {
Vector3i worldPos; Vector3i worldPos;
Entity physicsEntity; Entity physicsEntity;
Entity blockPhysicsEntity;
DBody physicsObject; DBody physicsObject;
@ -59,6 +63,8 @@ public class PhysicsDataCell {
public void retireCell(){ public void retireCell(){
ServerEntityUtils.destroyEntity(physicsEntity); ServerEntityUtils.destroyEntity(physicsEntity);
this.physicsEntity = null; this.physicsEntity = null;
ServerEntityUtils.destroyEntity(blockPhysicsEntity);
this.blockPhysicsEntity = null;
} }
/** /**
@ -81,6 +87,16 @@ public class PhysicsDataCell {
physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types); physicsEntity = TerrainChunk.serverCreateTerrainChunkEntity(realm, realPos, weights, types);
physicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); 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 // //then actually perform the attach
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);
// Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); // Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
@ -93,6 +109,7 @@ public class PhysicsDataCell {
public void destroyPhysics(){ public void destroyPhysics(){
Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
realm.getCollisionEngine().destroyPhysics(physicsEntity); realm.getCollisionEngine().destroyPhysics(physicsEntity);
realm.getCollisionEngine().destroyPhysics(blockPhysicsEntity);
} }
/** /**