fix block mesh ray cast bug
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
355abd0991
commit
fcd2f1e0a7
@ -1353,6 +1353,7 @@ Fix TextureInstancedActor packing data texture incorrectly (column major instead
|
|||||||
|
|
||||||
(03/28/2025)
|
(03/28/2025)
|
||||||
Grass height variance with control from ui + file
|
Grass height variance with control from ui + file
|
||||||
|
Fix block mesh ray casting bug due to trimesh overlap
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -23,7 +23,12 @@ import electrosphere.renderer.meshgen.BlockMeshgen.BlockMeshData;
|
|||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles networking for block-related messages on client
|
||||||
|
*/
|
||||||
public class ClientBlockManager {
|
public class ClientBlockManager {
|
||||||
|
|
||||||
//queues messages from server
|
//queues messages from server
|
||||||
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +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.state.collidable.MultiShapeTriGeomData;
|
||||||
import electrosphere.entity.state.collidable.TriGeomData;
|
import electrosphere.entity.state.collidable.TriGeomData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,6 +271,35 @@ public class CollisionBodyCreation {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an ode DBody from a mesh data set containing multiple shapes
|
||||||
|
* @param data The mesh data data
|
||||||
|
* @return The DBody
|
||||||
|
*/
|
||||||
|
public static DBody generateBodyFromMultiShapeMeshData(CollisionEngine collisionEngine, MultiShapeTriGeomData data, long categoryBits){
|
||||||
|
DBody body = null;
|
||||||
|
|
||||||
|
DGeom[] geoms = new DGeom[data.getData().size()];
|
||||||
|
|
||||||
|
//create trimeshes
|
||||||
|
int i = 0;
|
||||||
|
for(TriGeomData shapeData : data.getData()){
|
||||||
|
if(shapeData.getFaceElements().length > 0){
|
||||||
|
DTriMesh triMesh = collisionEngine.createTrimeshGeom(shapeData.getVertices(),shapeData.getFaceElements(),categoryBits);
|
||||||
|
geoms[i] = triMesh;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create body from shapes
|
||||||
|
body = collisionEngine.createDBody(geoms);
|
||||||
|
collisionEngine.setKinematic(body);
|
||||||
|
collisionEngine.setGravityMode(body, false);
|
||||||
|
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a body from an AIScene
|
* Generates a body from an AIScene
|
||||||
* @param scene The AIScene to generate a rigid body off of
|
* @param scene The AIScene to generate a rigid body off of
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import electrosphere.entity.EntityTags;
|
|||||||
import electrosphere.entity.EntityUtils;
|
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.MultiShapeTriGeomData;
|
||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.collidable.TriGeomData;
|
import electrosphere.entity.state.collidable.TriGeomData;
|
||||||
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
|
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
|
||||||
@ -504,6 +505,21 @@ public class PhysicsEntityUtils {
|
|||||||
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [CLIENT ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity
|
||||||
|
* @param terrain The entity
|
||||||
|
* @param data The trimesh description
|
||||||
|
* @return The rigid body created (note, attachment has already been performed)
|
||||||
|
*/
|
||||||
|
public static void clientAttachMultiShapeTriGeomRigidBody(Entity terrain, MultiShapeTriGeomData data){
|
||||||
|
DBody terrainBody = CollisionBodyCreation.generateBodyFromMultiShapeMeshData(Globals.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
||||||
|
CollisionBodyCreation.setAutoDisable(Globals.clientSceneWrapper.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||||
|
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
||||||
|
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
|
||||||
|
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||||
|
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [SERVER ONLY] Given an entity and a terrain chunk description, create physics for the chunk and attach it to the entity
|
* [SERVER ONLY] Given an entity and a terrain chunk description, create physics for the chunk and attach it to the entity
|
||||||
@ -522,6 +538,23 @@ public class PhysicsEntityUtils {
|
|||||||
return terrainBody;
|
return terrainBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [SERVER ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity
|
||||||
|
* @param terrain The entity
|
||||||
|
* @param data The trimesh description
|
||||||
|
* @return The rigid body created (note, attachment has already been performed)
|
||||||
|
*/
|
||||||
|
public static DBody serverAttachMultiShapeTriGeomRigidBody(Entity terrain, MultiShapeTriGeomData data){
|
||||||
|
Realm realm = Globals.realmManager.getEntityRealm(terrain);
|
||||||
|
DBody terrainBody = CollisionBodyCreation.generateBodyFromMultiShapeMeshData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT);
|
||||||
|
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||||
|
|
||||||
|
realm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_STATIC, false));
|
||||||
|
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||||
|
|
||||||
|
return terrainBody;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repositions all active physics-scoped entities on a given realm
|
* Repositions all active physics-scoped entities on a given realm
|
||||||
* @param collisionEngine The realm's collision engine
|
* @param collisionEngine The realm's collision engine
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
package electrosphere.entity.state.collidable;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tri geom data set that contains multiple shapes
|
||||||
|
*/
|
||||||
|
public interface MultiShapeTriGeomData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the data for the tri geom shapes
|
||||||
|
* @return The data
|
||||||
|
*/
|
||||||
|
public Collection<TriGeomData> getData();
|
||||||
|
|
||||||
|
}
|
||||||
@ -67,7 +67,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.clientAttachTriGeomRigidBody(rVal, data);
|
PhysicsEntityUtils.clientAttachMultiShapeTriGeomRigidBody(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);
|
||||||
@ -112,7 +112,7 @@ public class BlockChunkEntity {
|
|||||||
*/
|
*/
|
||||||
public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){
|
public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){
|
||||||
if(blockChunkData.getVertices().length > 0){
|
if(blockChunkData.getVertices().length > 0){
|
||||||
PhysicsEntityUtils.serverAttachTriGeomRigidBody(entity, blockChunkData);
|
PhysicsEntityUtils.serverAttachMultiShapeTriGeomRigidBody(entity, blockChunkData);
|
||||||
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
Realm realm = Globals.realmManager.getEntityRealm(entity);
|
||||||
DBody terrainBody = PhysicsEntityUtils.getDBody(entity);
|
DBody terrainBody = PhysicsEntityUtils.getDBody(entity);
|
||||||
Vector3d entityPos = EntityUtils.getPosition(entity);
|
Vector3d entityPos = EntityUtils.getPosition(entity);
|
||||||
|
|||||||
@ -208,6 +208,7 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
|||||||
if(Globals.clientBlockManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE)){
|
if(Globals.clientBlockManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE)){
|
||||||
BlockChunkData data = Globals.clientBlockManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE);
|
BlockChunkData data = Globals.clientBlockManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE);
|
||||||
if(data != null){
|
if(data != null){
|
||||||
|
System.out.println("Set " + message.getvoxelX() + " " + message.getvoxelY() + " " + message.getvoxelZ() + " to " + message.getblockType());
|
||||||
data.setType(
|
data.setType(
|
||||||
message.getvoxelX(),
|
message.getvoxelX(),
|
||||||
message.getvoxelY(),
|
message.getvoxelY(),
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.renderer.meshgen;
|
|||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -13,6 +14,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.MultiShapeTriGeomData;
|
||||||
import electrosphere.entity.state.collidable.TriGeomData;
|
import electrosphere.entity.state.collidable.TriGeomData;
|
||||||
import electrosphere.renderer.model.Material;
|
import electrosphere.renderer.model.Material;
|
||||||
import electrosphere.renderer.model.Mesh;
|
import electrosphere.renderer.model.Mesh;
|
||||||
@ -311,6 +313,9 @@ public class BlockMeshgen {
|
|||||||
//sort
|
//sort
|
||||||
Collections.sort(quadMeshes);
|
Collections.sort(quadMeshes);
|
||||||
|
|
||||||
|
int lastVertexCount = 0;
|
||||||
|
int lastFaceCount = 0;
|
||||||
|
|
||||||
//generate volumes
|
//generate volumes
|
||||||
QuadMesh quad1 = null;
|
QuadMesh quad1 = null;
|
||||||
QuadMesh quad2 = null;
|
QuadMesh quad2 = null;
|
||||||
@ -325,6 +330,11 @@ public class BlockMeshgen {
|
|||||||
} else {
|
} else {
|
||||||
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
|
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
|
||||||
quad1 = quad2;
|
quad1 = quad2;
|
||||||
|
|
||||||
|
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount);
|
||||||
|
lastVertexCount = verts.size();
|
||||||
|
lastFaceCount = indices.size();
|
||||||
|
rVal.shapeData.add(blockSingleShape);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,6 +342,10 @@ public class BlockMeshgen {
|
|||||||
}
|
}
|
||||||
if(quad1 != null){
|
if(quad1 != null){
|
||||||
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
|
BlockMeshgen.meshifyBox(verts,normals,uvs,indices,samplers,quad1,zEnd,quad1.type,verts.size());
|
||||||
|
BlockSingleShape blockSingleShape = BlockMeshgen.copyDataToShape(verts,indices,lastVertexCount,lastFaceCount);
|
||||||
|
lastVertexCount = verts.size();
|
||||||
|
lastFaceCount = indices.size();
|
||||||
|
rVal.shapeData.add(blockSingleShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -389,6 +403,28 @@ public class BlockMeshgen {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies vertex and index data from the combined array into a single shape
|
||||||
|
* @param verts The list of vertices
|
||||||
|
* @param indices The list of indices
|
||||||
|
* @param lastVertCount The last vertex position that was copied
|
||||||
|
* @param lastFaceCount The last index position that was copied
|
||||||
|
* @return The data containing a single shape's worth of geometry data
|
||||||
|
*/
|
||||||
|
private static BlockSingleShape copyDataToShape(List<Vector3f> verts, List<Integer> indices, int lastVertCount, int lastFaceCount){
|
||||||
|
BlockSingleShape blockSingleShape = new BlockSingleShape((verts.size() - lastVertCount),(indices.size() - lastFaceCount));
|
||||||
|
for(int i = lastVertCount; i < verts.size(); i++){
|
||||||
|
Vector3f vert = verts.get(i);
|
||||||
|
blockSingleShape.vertices[(i - lastVertCount) * 3 + 0] = vert.x;
|
||||||
|
blockSingleShape.vertices[(i - lastVertCount) * 3 + 1] = vert.y;
|
||||||
|
blockSingleShape.vertices[(i - lastVertCount) * 3 + 2] = vert.z;
|
||||||
|
}
|
||||||
|
for(int i = lastFaceCount; i < indices.size(); i++){
|
||||||
|
blockSingleShape.faceElements[i - lastFaceCount] = indices.get(i) - lastVertCount;
|
||||||
|
}
|
||||||
|
return blockSingleShape;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a mesh based on a block mesh data object
|
* Generates a mesh based on a block mesh data object
|
||||||
* @param data The block mesh data object
|
* @param data The block mesh data object
|
||||||
@ -492,36 +528,117 @@ public class BlockMeshgen {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the geom data for a single shape in the block mesh
|
||||||
|
*/
|
||||||
|
public static class BlockSingleShape implements TriGeomData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The verts
|
||||||
|
*/
|
||||||
|
float[] vertices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The faces
|
||||||
|
*/
|
||||||
|
int[] faceElements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param vertCount The number of verts
|
||||||
|
* @param faceCount The number of faces
|
||||||
|
*/
|
||||||
|
public BlockSingleShape(int vertCount, int faceCount){
|
||||||
|
vertices = new float[vertCount * 3];
|
||||||
|
faceElements = new int[faceCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float[] getVertices() {
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getFaceElements() {
|
||||||
|
return faceElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The final rasterization data that is emitted
|
* The final rasterization data that is emitted
|
||||||
*/
|
*/
|
||||||
public static class BlockMeshData implements TriGeomData {
|
public static class BlockMeshData implements TriGeomData, MultiShapeTriGeomData {
|
||||||
//the verts
|
|
||||||
|
/**
|
||||||
|
* Vertex data in array form
|
||||||
|
*/
|
||||||
float[] vertices;
|
float[] vertices;
|
||||||
//normals
|
|
||||||
|
/**
|
||||||
|
* Normal data in array form
|
||||||
|
*/
|
||||||
float[] normals;
|
float[] normals;
|
||||||
//faces
|
|
||||||
|
/**
|
||||||
|
* Face data in array form
|
||||||
|
*/
|
||||||
int[] faceElements;
|
int[] faceElements;
|
||||||
//UVs
|
|
||||||
|
/**
|
||||||
|
* UV data in array form
|
||||||
|
*/
|
||||||
float[] uvs;
|
float[] uvs;
|
||||||
//The samplers for each quad
|
|
||||||
|
/**
|
||||||
|
* Sampler data in array form
|
||||||
|
*/
|
||||||
int[] samplers;
|
int[] samplers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data broken out by each shape
|
||||||
|
*/
|
||||||
|
List<TriGeomData> shapeData = new LinkedList<TriGeomData>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of vertex data
|
||||||
|
*/
|
||||||
FloatBuffer vertBuffer;
|
FloatBuffer vertBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of normal data
|
||||||
|
*/
|
||||||
FloatBuffer normalBuffer;
|
FloatBuffer normalBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of face data
|
||||||
|
*/
|
||||||
IntBuffer faceBuffer;
|
IntBuffer faceBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of UV data
|
||||||
|
*/
|
||||||
FloatBuffer uvBuffer;
|
FloatBuffer uvBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of sampler data
|
||||||
|
*/
|
||||||
IntBuffer samplerBuffer;
|
IntBuffer samplerBuffer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] getVertices() {
|
public float[] getVertices() {
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getFaceElements() {
|
public int[] getFaceElements() {
|
||||||
return faceElements;
|
return faceElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<TriGeomData> getData() {
|
||||||
|
return shapeData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user