fix geom-body collision
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-22 18:38:18 -04:00
parent 90031765a9
commit 90e9492c18
11 changed files with 122 additions and 19 deletions

View File

@ -1936,6 +1936,7 @@ Scene view debug window
Debug view of entity colliders Debug view of entity colliders
Fix lookup bug in debug physics ui Fix lookup bug in debug physics ui
Floating point starting to play nice with engine Floating point starting to play nice with engine
Fix geom-body collision sending wrong vector to body

View File

@ -7,8 +7,10 @@ import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros; import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.entity.state.server.ServerPlayerViewDirTree;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
@ -95,6 +97,17 @@ public class ImGuiPlayerEntity {
ImGuiEntityMacros.showEntity(serverPlayerEntity); ImGuiEntityMacros.showEntity(serverPlayerEntity);
} }
//
//teleport to camera
if(ImGui.button("TP to Cam")){
Globals.engineState.signalSystem.post(SignalType.ENGINE_SYNCHRONOUS_CODE, () -> {
Vector3d camPos = CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera);
int serverIdForClientEntity = Globals.clientState.clientSceneWrapper.mapClientToServerId(Globals.clientState.playerEntity.getId());
Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
ServerEntityUtils.repositionEntity(serverPlayerEntity, camPos);
});
}
} }
}); });

View File

@ -56,6 +56,15 @@ public class ImGuiRenderer {
if(ImGui.button("Draw Interaction Collidable Data")){ if(ImGui.button("Draw Interaction Collidable Data")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawInteractionCollidables(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawInteractionCollidables()); Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawInteractionCollidables(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawInteractionCollidables());
} }
if(ImGui.button("Draw Macro Data Colliders")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawMacroColliders(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawMacroColliders());
}
if(ImGui.button("Draw Client Cell Colliders")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawClientCellColliders(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawClientCellColliders());
}
if(ImGui.button("Draw Server Cell Colliders")){
Globals.gameConfigCurrent.getSettings().setGraphicsDebugDrawServerCellColliders(!Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerCellColliders());
}
ImGui.unindent(); ImGui.unindent();
} }
if(ImGui.collapsingHeader("OpenGL Details")){ if(ImGui.collapsingHeader("OpenGL Details")){

View File

@ -12,6 +12,7 @@ import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector4d; import org.joml.Vector4d;
import org.ode4j.math.DVector3; import org.ode4j.math.DVector3;
import org.ode4j.ode.DBhvSpace;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DBox; import org.ode4j.ode.DBox;
import org.ode4j.ode.DCapsule; import org.ode4j.ode.DCapsule;
@ -98,7 +99,7 @@ public class CollisionEngine {
/** /**
* Distance from current floating point origin to trigger a rebase * Distance from current floating point origin to trigger a rebase
*/ */
private static final double REBASE_TRIGGER_DISTANCE = 500; private static final double REBASE_TRIGGER_DISTANCE = 16;
/** /**
* world data that the collision engine leverages for position correction and the like * world data that the collision engine leverages for position correction and the like
@ -113,7 +114,7 @@ public class CollisionEngine {
/** /**
* The main space in the world * The main space in the world
*/ */
private DSpace space; private DBhvSpace space;
/** /**
* Lock for thread-safeing all ODE calls * Lock for thread-safeing all ODE calls
@ -172,11 +173,6 @@ public class CollisionEngine {
*/ */
private CollisionResolutionCallback collisionResolutionCallback; private CollisionResolutionCallback collisionResolutionCallback;
/**
* The body that contains all static shapes
*/
private DBody staticBody;
/** /**
* Callback for any near collisions in the broadphase of the collision check * Callback for any near collisions in the broadphase of the collision check
*/ */
@ -202,11 +198,6 @@ public class CollisionEngine {
//base plane //base plane
basePlane = OdeHelper.createPlane(space, 0, 1, 0, 0); basePlane = OdeHelper.createPlane(space, 0, 1, 0, 0);
//static body
staticBody = this.createDBody();
staticBody.setKinematic();
contactgroup = OdeHelper.createJointGroup(); contactgroup = OdeHelper.createJointGroup();
this.nearCallback = new DNearCallback() { this.nearCallback = new DNearCallback() {
@Override @Override
@ -496,7 +487,7 @@ public class CollisionEngine {
//add contact to contact group //add contact to contact group
DJoint c = OdeHelper.createContactJoint(world,contactgroup,contact); DJoint c = OdeHelper.createContactJoint(world,contactgroup,contact);
if(b1 == null){ if(b1 == null){
c.attach(b2,null); c.attach(null,b2);
} else if(b2 == null){ } else if(b2 == null){
c.attach(b1,null); c.attach(b1,null);
} else { } else {
@ -726,6 +717,7 @@ public class CollisionEngine {
} }
} }
} }
newOrigin = newOrigin.round();
Vector3d delta = new Vector3d(this.floatingOrigin); Vector3d delta = new Vector3d(this.floatingOrigin);
delta = delta.sub(newOrigin); delta = delta.sub(newOrigin);
@ -1498,6 +1490,14 @@ public class CollisionEngine {
; ;
return message; return message;
} }
/**
* Gets the floating origin of the collision engine
* @return The floating origin
*/
public Vector3d getFloatingOrigin(){
return new Vector3d(this.floatingOrigin);
}
/** /**

View File

@ -712,7 +712,7 @@ public class PhysicsEntityUtils {
*/ */
public static void clientAttachTriGeomCollider(Entity terrain, TriGeomData data){ public static void clientAttachTriGeomCollider(Entity terrain, TriGeomData data){
DGeom terrainGeom = CollisionBodyCreation.generateGeomFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT); DGeom terrainGeom = CollisionBodyCreation.generateGeomFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
PhysicsEntityUtils.setCollidable(terrain, collidable); PhysicsEntityUtils.setCollidable(terrain, collidable);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable); Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable);
PhysicsEntityUtils.setDGeom(terrain,terrainGeom); PhysicsEntityUtils.setDGeom(terrain,terrainGeom);
@ -775,7 +775,7 @@ public class PhysicsEntityUtils {
Realm realm = Globals.serverState.realmManager.getEntityRealm(terrain); Realm realm = Globals.serverState.realmManager.getEntityRealm(terrain);
DGeom terrainCollider = CollisionBodyCreation.generateGeomFromTerrainData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT); DGeom terrainCollider = CollisionBodyCreation.generateGeomFromTerrainData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT);
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
PhysicsEntityUtils.setCollidable(terrain, collidable); PhysicsEntityUtils.setCollidable(terrain, collidable);
realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable); realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable);
PhysicsEntityUtils.setDGeom(terrain,terrainCollider); PhysicsEntityUtils.setDGeom(terrain,terrainCollider);

View File

@ -53,6 +53,9 @@ public class UserSettings {
boolean graphicsDebugDrawNavmesh; boolean graphicsDebugDrawNavmesh;
boolean graphicsDebugDrawGridAlignment; boolean graphicsDebugDrawGridAlignment;
boolean graphicsDebugDrawInteractionCollidables; boolean graphicsDebugDrawInteractionCollidables;
boolean graphicsDebugDrawMacroColliders;
boolean graphicsDebugDrawClientCellColliders;
boolean graphicsDebugDrawServerCellColliders;
//debug network //debug network
boolean netRunNetMonitor; boolean netRunNetMonitor;
@ -218,7 +221,38 @@ public class UserSettings {
*/ */
public void setGraphicsDebugDrawInteractionCollidables(boolean graphicsDebugDrawInteractionCollidables) { public void setGraphicsDebugDrawInteractionCollidables(boolean graphicsDebugDrawInteractionCollidables) {
this.graphicsDebugDrawInteractionCollidables = graphicsDebugDrawInteractionCollidables; this.graphicsDebugDrawInteractionCollidables = graphicsDebugDrawInteractionCollidables;
} }
public boolean getGraphicsDebugDrawMacroColliders() {
return graphicsDebugDrawMacroColliders;
}
public void setGraphicsDebugDrawMacroColliders(boolean graphicsDebugDrawMacroColliders) {
this.graphicsDebugDrawMacroColliders = graphicsDebugDrawMacroColliders;
}
public boolean getGraphicsDebugDrawClientCellColliders() {
return graphicsDebugDrawClientCellColliders;
}
public void setGraphicsDebugDrawClientCellColliders(boolean graphicsDebugDrawCellColliders) {
this.graphicsDebugDrawClientCellColliders = graphicsDebugDrawCellColliders;
}
public boolean getGraphicsDebugDrawServerCellColliders() {
return graphicsDebugDrawServerCellColliders;
}
public void setGraphicsDebugDrawServerCellColliders(boolean graphicsDebugDrawServerCellColliders) {
this.graphicsDebugDrawServerCellColliders = graphicsDebugDrawServerCellColliders;
}

View File

@ -17,6 +17,7 @@ public class Signal {
// //
ENGINE_SHUTDOWN, ENGINE_SHUTDOWN,
ENGINE_RETURN_TO_TITLE, ENGINE_RETURN_TO_TITLE,
ENGINE_SYNCHRONOUS_CODE,
// //
//RENDERING //RENDERING

View File

@ -16,6 +16,7 @@ public class MainThreadSignalService extends SignalServiceImpl {
"MainThreadSignalService", "MainThreadSignalService",
new SignalType[]{ new SignalType[]{
SignalType.ENGINE_RETURN_TO_TITLE, SignalType.ENGINE_RETURN_TO_TITLE,
SignalType.ENGINE_SYNCHRONOUS_CODE,
} }
); );
} }
@ -28,6 +29,10 @@ public class MainThreadSignalService extends SignalServiceImpl {
MainMenuLoading.returnToMainMenu(null); MainMenuLoading.returnToMainMenu(null);
rVal = true; rVal = true;
} break; } break;
case ENGINE_SYNCHRONOUS_CODE: {
((Runnable)signal.getData()).run();
rVal = true;
} break;
default: { default: {
LoggerInterface.loggerEngine.WARNING("MainThreadSignalService received signal that it does not have handling for! " + signal); LoggerInterface.loggerEngine.WARNING("MainThreadSignalService received signal that it does not have handling for! " + signal);
} break; } break;

View File

@ -15,6 +15,7 @@ public class EntityTags {
public static final String LIFE_STATE = "lifeState"; public static final String LIFE_STATE = "lifeState";
public static final String CREATURE = "creature"; public static final String CREATURE = "creature";
public static final String FOLIAGE = "foliage"; public static final String FOLIAGE = "foliage";
public static final String TERRAIN = "terrain";
public static final String UI = "ui"; //is it a ui entity public static final String UI = "ui"; //is it a ui entity
public static final String DRAWABLE = "drawable"; //is it drawable public static final String DRAWABLE = "drawable"; //is it drawable
public static final String DRAW_INSTANCED = "drawInstanced"; //if it's instanced, but not necessarily managed by a service (ie a tree branch) public static final String DRAW_INSTANCED = "drawInstanced"; //if it's instanced, but not necessarily managed by a service (ie a tree branch)

View File

@ -22,6 +22,7 @@ import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.EntityTypes.EntityType; import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
@ -103,6 +104,7 @@ public class TerrainChunk {
} }
} }
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.TERRAIN);
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
return rVal; return rVal;

View File

@ -8,6 +8,7 @@ import org.joml.Matrix4d;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import org.ode4j.ode.DAABBC;
import org.ode4j.ode.DCapsule; import org.ode4j.ode.DCapsule;
import org.ode4j.ode.DGeom; import org.ode4j.ode.DGeom;
import org.ode4j.ode.DSphere; import org.ode4j.ode.DSphere;
@ -16,6 +17,7 @@ import electrosphere.client.block.BlockChunkData;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.interact.select.AreaSelection; import electrosphere.client.interact.select.AreaSelection;
import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.data.block.fab.FurnitureSlotMetadata; import electrosphere.data.block.fab.FurnitureSlotMetadata;
@ -29,6 +31,7 @@ import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState;
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
@ -186,7 +189,7 @@ public class DebugContentPipeline implements RenderPipeline {
// //
//Draw town data //Draw town data
if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawGridAlignment()){ if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawMacroColliders()){
for(VirtualStructure struct : Globals.serverState.realmManager.first().getMacroData().getStructures()){ for(VirtualStructure struct : Globals.serverState.realmManager.first().getMacroData().getStructures()){
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, struct.getAABB(), AssetDataStrings.TEXTURE_BLUE_TRANSPARENT); DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, struct.getAABB(), AssetDataStrings.TEXTURE_BLUE_TRANSPARENT);
} }
@ -195,6 +198,29 @@ public class DebugContentPipeline implements RenderPipeline {
} }
} }
//
//Draw cell colliders data
if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawClientCellColliders()){
for(Entity ent : Globals.clientState.clientScene.getEntitiesWithTag(EntityTags.TERRAIN)){
if(PhysicsEntityUtils.getDGeom(ent) != null){
Vector3d entPos = EntityUtils.getPosition(ent);
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, new Vector3d(entPos).add(4,4,4), new Vector3d(entPos).add(12,12,12), AssetDataStrings.TEXTURE_RED_TRANSPARENT);
}
}
}
if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawServerCellColliders()){
Vector3d floatingOrigin = Globals.serverState.realmManager.first().getCollisionEngine().getFloatingOrigin();
for(Entity ent : EntityLookupUtils.getAllEntities()){
if(PhysicsEntityUtils.getDGeom(ent) != null && ent.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN)){
DGeom geom = PhysicsEntityUtils.getDGeom(ent);
DAABBC aabb = geom.getAABB();
Vector3d min = new Vector3d(aabb.getMin0(),aabb.getMin1(),aabb.getMin2()).add(floatingOrigin);
Vector3d max = new Vector3d(aabb.getMax0(),aabb.getMax1(),aabb.getMax2()).add(floatingOrigin);
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, min, max, AssetDataStrings.TEXTURE_RED_TRANSPARENT);
}
}
}
//update pipeline state to use mats again //update pipeline state to use mats again
renderPipelineState.setUseMaterial(true); renderPipelineState.setUseMaterial(true);
@ -439,6 +465,17 @@ public class DebugContentPipeline implements RenderPipeline {
* @param areaSelection The area selection * @param areaSelection The area selection
*/ */
static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AABBd aabb, String texturePath){ static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, AABBd aabb, String texturePath){
DebugContentPipeline.renderAABB(openGLState, renderPipelineState, modelTransformMatrix, new Vector3d(aabb.minX,aabb.minY,aabb.minZ), new Vector3d(aabb.maxX,aabb.maxY,aabb.maxZ), texturePath);
}
/**
* Renders an area select
* @param openGLState The opengl state
* @param renderPipelineState The render pipeline state
* @param modelTransformMatrix The model transform matrix
* @param areaSelection The area selection
*/
static void renderAABB(OpenGLState openGLState, RenderPipelineState renderPipelineState, Matrix4d modelTransformMatrix, Vector3d start, Vector3d end, String texturePath){
Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE); Model model = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE);
if(model != null){ if(model != null){
Texture texture = Globals.assetManager.fetchTexture(texturePath); Texture texture = Globals.assetManager.fetchTexture(texturePath);
@ -446,10 +483,10 @@ public class DebugContentPipeline implements RenderPipeline {
texture.bind(openGLState); texture.bind(openGLState);
} }
//calculate camera-modified vector3d //calculate camera-modified vector3d
Vector3d cameraModifiedPosition = new Vector3d(aabb.minX,aabb.minY,aabb.minZ).lerp(new Vector3d(aabb.maxX,aabb.maxY,aabb.maxZ),0.5).sub(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera)); Vector3d cameraModifiedPosition = new Vector3d(start.x,start.y,start.z).lerp(new Vector3d(end.x,end.y,end.z),0.5).sub(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
modelTransformMatrix.identity(); modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.scale(new Vector3d(aabb.maxX - aabb.minX,aabb.maxY - aabb.minY,aabb.maxZ - aabb.minZ)); modelTransformMatrix.scale(new Vector3d(end.x - start.x,end.y - start.y,end.z - start.z));
model.setModelMatrix(modelTransformMatrix); model.setModelMatrix(modelTransformMatrix);
model.draw(renderPipelineState,openGLState); model.draw(renderPipelineState,openGLState);
} }