From 90e9492c18d41588b39cf369d66b91315acf41ee Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 22 May 2025 18:38:18 -0400 Subject: [PATCH] fix geom-body collision --- docs/src/progress/renderertodo.md | 1 + .../ui/menu/debug/ImGuiPlayerEntity.java | 13 ++++++ .../ui/menu/debug/render/ImGuiRenderer.java | 9 ++++ .../collision/CollisionEngine.java | 26 +++++------ .../collision/PhysicsEntityUtils.java | 4 +- .../data/settings/UserSettings.java | 36 +++++++++++++++- .../electrosphere/engine/signal/Signal.java | 1 + .../signal/sync/MainThreadSignalService.java | 5 +++ .../java/electrosphere/entity/EntityTags.java | 1 + .../entity/types/terrain/TerrainChunk.java | 2 + .../pipelines/debug/DebugContentPipeline.java | 43 +++++++++++++++++-- 11 files changed, 122 insertions(+), 19 deletions(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 37855622..4c3c4b63 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1936,6 +1936,7 @@ Scene view debug window Debug view of entity colliders Fix lookup bug in debug physics ui Floating point starting to play nice with engine +Fix geom-body collision sending wrong vector to body diff --git a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java index d8e252fb..8d83a374 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiPlayerEntity.java @@ -7,8 +7,10 @@ import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.ui.menu.debug.entity.ImGuiEntityMacros; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.engine.Globals; +import electrosphere.engine.signal.Signal.SignalType; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; +import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.entity.types.creature.CreatureUtils; @@ -95,6 +97,17 @@ public class ImGuiPlayerEntity { 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); + }); + } + } }); diff --git a/src/main/java/electrosphere/client/ui/menu/debug/render/ImGuiRenderer.java b/src/main/java/electrosphere/client/ui/menu/debug/render/ImGuiRenderer.java index fd4fea28..ce9d4b8b 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/render/ImGuiRenderer.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/render/ImGuiRenderer.java @@ -56,6 +56,15 @@ public class ImGuiRenderer { if(ImGui.button("Draw Interaction Collidable Data")){ 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(); } if(ImGui.collapsingHeader("OpenGL Details")){ diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 568fd8e5..81b2ab8b 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -12,6 +12,7 @@ import org.joml.Quaterniond; import org.joml.Vector3d; import org.joml.Vector4d; import org.ode4j.math.DVector3; +import org.ode4j.ode.DBhvSpace; import org.ode4j.ode.DBody; import org.ode4j.ode.DBox; import org.ode4j.ode.DCapsule; @@ -98,7 +99,7 @@ public class CollisionEngine { /** * 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 @@ -113,7 +114,7 @@ public class CollisionEngine { /** * The main space in the world */ - private DSpace space; + private DBhvSpace space; /** * Lock for thread-safeing all ODE calls @@ -172,11 +173,6 @@ public class CollisionEngine { */ 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 */ @@ -202,11 +198,6 @@ public class CollisionEngine { //base plane basePlane = OdeHelper.createPlane(space, 0, 1, 0, 0); - //static body - staticBody = this.createDBody(); - staticBody.setKinematic(); - - contactgroup = OdeHelper.createJointGroup(); this.nearCallback = new DNearCallback() { @Override @@ -496,7 +487,7 @@ public class CollisionEngine { //add contact to contact group DJoint c = OdeHelper.createContactJoint(world,contactgroup,contact); if(b1 == null){ - c.attach(b2,null); + c.attach(null,b2); } else if(b2 == null){ c.attach(b1,null); } else { @@ -726,6 +717,7 @@ public class CollisionEngine { } } } + newOrigin = newOrigin.round(); Vector3d delta = new Vector3d(this.floatingOrigin); delta = delta.sub(newOrigin); @@ -1498,6 +1490,14 @@ public class CollisionEngine { ; return message; } + + /** + * Gets the floating origin of the collision engine + * @return The floating origin + */ + public Vector3d getFloatingOrigin(){ + return new Vector3d(this.floatingOrigin); + } /** diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index ebc78930..4c2ff63a 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -712,7 +712,7 @@ public class PhysicsEntityUtils { */ public static void clientAttachTriGeomCollider(Entity terrain, TriGeomData data){ 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); Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable); PhysicsEntityUtils.setDGeom(terrain,terrainGeom); @@ -775,7 +775,7 @@ public class PhysicsEntityUtils { Realm realm = Globals.serverState.realmManager.getEntityRealm(terrain); 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); realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable); PhysicsEntityUtils.setDGeom(terrain,terrainCollider); diff --git a/src/main/java/electrosphere/data/settings/UserSettings.java b/src/main/java/electrosphere/data/settings/UserSettings.java index 398feb77..9f025b5b 100644 --- a/src/main/java/electrosphere/data/settings/UserSettings.java +++ b/src/main/java/electrosphere/data/settings/UserSettings.java @@ -53,6 +53,9 @@ public class UserSettings { boolean graphicsDebugDrawNavmesh; boolean graphicsDebugDrawGridAlignment; boolean graphicsDebugDrawInteractionCollidables; + boolean graphicsDebugDrawMacroColliders; + boolean graphicsDebugDrawClientCellColliders; + boolean graphicsDebugDrawServerCellColliders; //debug network boolean netRunNetMonitor; @@ -218,7 +221,38 @@ public class UserSettings { */ public void setGraphicsDebugDrawInteractionCollidables(boolean 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; + } + + + + + + + diff --git a/src/main/java/electrosphere/engine/signal/Signal.java b/src/main/java/electrosphere/engine/signal/Signal.java index a9e0d04b..9e0fc2cb 100644 --- a/src/main/java/electrosphere/engine/signal/Signal.java +++ b/src/main/java/electrosphere/engine/signal/Signal.java @@ -17,6 +17,7 @@ public class Signal { // ENGINE_SHUTDOWN, ENGINE_RETURN_TO_TITLE, + ENGINE_SYNCHRONOUS_CODE, // //RENDERING diff --git a/src/main/java/electrosphere/engine/signal/sync/MainThreadSignalService.java b/src/main/java/electrosphere/engine/signal/sync/MainThreadSignalService.java index c5dbd9aa..3103227d 100644 --- a/src/main/java/electrosphere/engine/signal/sync/MainThreadSignalService.java +++ b/src/main/java/electrosphere/engine/signal/sync/MainThreadSignalService.java @@ -16,6 +16,7 @@ public class MainThreadSignalService extends SignalServiceImpl { "MainThreadSignalService", new SignalType[]{ SignalType.ENGINE_RETURN_TO_TITLE, + SignalType.ENGINE_SYNCHRONOUS_CODE, } ); } @@ -28,6 +29,10 @@ public class MainThreadSignalService extends SignalServiceImpl { MainMenuLoading.returnToMainMenu(null); rVal = true; } break; + case ENGINE_SYNCHRONOUS_CODE: { + ((Runnable)signal.getData()).run(); + rVal = true; + } break; default: { LoggerInterface.loggerEngine.WARNING("MainThreadSignalService received signal that it does not have handling for! " + signal); } break; diff --git a/src/main/java/electrosphere/entity/EntityTags.java b/src/main/java/electrosphere/entity/EntityTags.java index 2496abcc..5a09eba3 100644 --- a/src/main/java/electrosphere/entity/EntityTags.java +++ b/src/main/java/electrosphere/entity/EntityTags.java @@ -15,6 +15,7 @@ public class EntityTags { public static final String LIFE_STATE = "lifeState"; public static final String CREATURE = "creature"; 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 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) diff --git a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java index 37284189..6ef83fdc 100644 --- a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java +++ b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java @@ -22,6 +22,7 @@ import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.EntityTypes.EntityType; 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); Globals.profiler.endCpuSample(); return rVal; diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java index 9fe24329..d03cf353 100644 --- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java @@ -8,6 +8,7 @@ import org.joml.Matrix4d; import org.joml.Quaterniond; import org.joml.Vector3d; import org.lwjgl.opengl.GL40; +import org.ode4j.ode.DAABBC; import org.ode4j.ode.DCapsule; import org.ode4j.ode.DGeom; import org.ode4j.ode.DSphere; @@ -16,6 +17,7 @@ import electrosphere.client.block.BlockChunkData; import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.interact.select.AreaSelection; import electrosphere.collision.CollisionEngine; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.data.block.fab.FurnitureSlotMetadata; @@ -29,6 +31,7 @@ import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState; @@ -186,7 +189,7 @@ public class DebugContentPipeline implements RenderPipeline { // //Draw town data - if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawGridAlignment()){ + if(Globals.gameConfigCurrent.getSettings().getGraphicsDebugDrawMacroColliders()){ for(VirtualStructure struct : Globals.serverState.realmManager.first().getMacroData().getStructures()){ 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 renderPipelineState.setUseMaterial(true); @@ -439,6 +465,17 @@ public class DebugContentPipeline implements RenderPipeline { * @param areaSelection The area selection */ 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); if(model != null){ Texture texture = Globals.assetManager.fetchTexture(texturePath); @@ -446,10 +483,10 @@ public class DebugContentPipeline implements RenderPipeline { texture.bind(openGLState); } //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.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.draw(renderPipelineState,openGLState); }