From 6729d0b6239de966bd4a208f37bc0cb415310b28 Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 15 May 2025 17:45:50 -0400 Subject: [PATCH] human capsule collidable --- assets/Data/entity/creatures/human.json | 10 +++---- assets/Data/entity/creatures/skeleton.json | 1 - docs/src/progress/renderertodo.md | 3 +++ .../interact/ClientInteractionEngine.java | 8 +++--- .../collision/CollisionBodyCreation.java | 8 +++--- .../collision/PhysicsEntityUtils.java | 16 ++++++------ .../data/collidable/CollidableTemplate.java | 15 +++++++++++ .../engine/assetmanager/AssetDataStrings.java | 1 + .../engine/loadingthreads/LoadingUtils.java | 3 ++- .../pipelines/debug/DebugContentPipeline.java | 26 +++++++++++++++++-- 10 files changed, 67 insertions(+), 24 deletions(-) diff --git a/assets/Data/entity/creatures/human.json b/assets/Data/entity/creatures/human.json index 742b1495..6895c5cc 100644 --- a/assets/Data/entity/creatures/human.json +++ b/assets/Data/entity/creatures/human.json @@ -388,10 +388,10 @@ ] }, "collidable" : { - "type" : "CYLINDER", - "dimension1" : 0.2, - "dimension2" : 1.6, - "dimension3" : 0.2, + "type" : "CAPSULE", + "dimension1" : 0.25, + "dimension2" : 0.9, + "dimension3" : 0.25, "linearFriction": 0.001, "mass": 0.3, "rotX": 0, @@ -399,7 +399,7 @@ "rotZ": 0, "rotW": 1, "offsetX" : 0, - "offsetY" : 0.8, + "offsetY" : 0.7, "offsetZ" : 0, "angularlyStatic" : true }, diff --git a/assets/Data/entity/creatures/skeleton.json b/assets/Data/entity/creatures/skeleton.json index d4f8eaf7..8418223d 100644 --- a/assets/Data/entity/creatures/skeleton.json +++ b/assets/Data/entity/creatures/skeleton.json @@ -62,7 +62,6 @@ "TARGETABLE", "CAN_EQUIP", "OUTLINE", - "PLAYABLE", "UNIT_CONTROLS" ], "inventoryData" : { diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 07b92c91..2c5a9233 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1831,6 +1831,9 @@ Move rendering flags under renderingEngine Move database connection into serverState Move more services into engineState Room tool functionality scaffolding +Load main level only loads human now +Human uses capsule collidable +Physics debug render renders capsules diff --git a/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java index 896f6757..cf190c4a 100644 --- a/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java +++ b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java @@ -54,7 +54,7 @@ public class ClientInteractionEngine { lock.lock(); interactables.add(rVal); switch(physicsTemplate.getType()){ - case "CYLINDER": { + case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { // //create dbody @@ -90,7 +90,7 @@ public class ClientInteractionEngine { Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable); } break; - case "CUBE": { + case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { // //create dbody rigidBody = CollisionBodyCreation.createCubeBody( @@ -125,13 +125,13 @@ public class ClientInteractionEngine { Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable); } break; - case "CAPSULE": { + case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { // //create dbody rigidBody = CollisionBodyCreation.createCapsuleBody( Globals.clientState.clientSceneWrapper.getInteractionEngine(), + physicsTemplate.getDimension1(), physicsTemplate.getDimension2(), - physicsTemplate.getDimension2() - physicsTemplate.getDimension1() - physicsTemplate.getDimension1(), categoryBit ); diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java index 867b2bed..568d88a3 100644 --- a/src/main/java/electrosphere/collision/CollisionBodyCreation.java +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -89,13 +89,15 @@ public class CollisionBodyCreation { /** * Creates a capsule body in the collision engine * @param collisionEngine The collision engine - * @param length The length of the capsule (not including round part at ends) * @param radius The radius of the sphere + * @param length The length of the capsule (not including round part at ends) * @return The DBody */ - public static DBody createCapsuleBody(CollisionEngine collisionEngine, double length, double radius, long categoryBits){ + public static DBody createCapsuleBody(CollisionEngine collisionEngine, double radius, double length, long categoryBits){ DCapsule geom = collisionEngine.createCapsuleGeom(radius,length,categoryBits); - return collisionEngine.createDBody(geom); + DBody rVal = collisionEngine.createDBody(geom); + collisionEngine.setOffsetRotation(geom); //ode4j required geom to already be on body before rotating for some reason + return rVal; } /** diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index a9d165ed..236324f3 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -69,7 +69,7 @@ public class PhysicsEntityUtils { categoryBit = Collidable.TYPE_STATIC_BIT; } switch(physicsTemplate.getType()){ - case "CYLINDER": { + case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { // //create dbody @@ -135,7 +135,7 @@ public class PhysicsEntityUtils { Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); } break; - case "CUBE": { + case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { // //create dbody rigidBody = CollisionBodyCreation.createCubeBody( @@ -199,13 +199,13 @@ public class PhysicsEntityUtils { Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); } break; - case "CAPSULE": { + case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { // //create dbody rigidBody = CollisionBodyCreation.createCapsuleBody( Globals.clientState.clientSceneWrapper.getCollisionEngine(), + physicsTemplate.getDimension1(), physicsTemplate.getDimension2(), - physicsTemplate.getDimension2() - physicsTemplate.getDimension1() - physicsTemplate.getDimension1(), categoryBit ); if(physicsTemplate.getMass() != null){ @@ -291,7 +291,7 @@ public class PhysicsEntityUtils { categoryBit = Collidable.TYPE_STATIC_BIT; } switch(physicsTemplate.getType()){ - case "CYLINDER": { + case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { // //create dbody @@ -358,7 +358,7 @@ public class PhysicsEntityUtils { realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); } break; - case "CUBE": { + case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { // //create dbody rigidBody = CollisionBodyCreation.createCubeBody( @@ -422,13 +422,13 @@ public class PhysicsEntityUtils { realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); } break; - case "CAPSULE": { + case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { // //create dbody rigidBody = CollisionBodyCreation.createCapsuleBody( realm.getCollisionEngine(), + physicsTemplate.getDimension1(), physicsTemplate.getDimension2(), - physicsTemplate.getDimension2() - physicsTemplate.getDimension1() - physicsTemplate.getDimension1(), categoryBit ); if(physicsTemplate.getMass() != null){ diff --git a/src/main/java/electrosphere/data/collidable/CollidableTemplate.java b/src/main/java/electrosphere/data/collidable/CollidableTemplate.java index 778527b5..908065f8 100644 --- a/src/main/java/electrosphere/data/collidable/CollidableTemplate.java +++ b/src/main/java/electrosphere/data/collidable/CollidableTemplate.java @@ -4,6 +4,21 @@ package electrosphere.data.collidable; * A template for a rigid body that should be attached to an entity */ public class CollidableTemplate { + + /** + * Cube collidable shape + */ + public static final String COLLIDABLE_TYPE_CUBE = "CUBE"; + + /** + * Cylinder collidable shape + */ + public static final String COLLIDABLE_TYPE_CYLINDER = "CYLINDER"; + + /** + * Capsule collidable shape + */ + public static final String COLLIDABLE_TYPE_CAPSULE = "CAPSULE"; /** * The primitive shape type diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java index 980e98f6..98272ba2 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java @@ -22,6 +22,7 @@ public class AssetDataStrings { */ public static final String UNITSPHERE = "unitSphere"; public static final String UNITCYLINDER = "unitCylinder"; + public static final String UNITCAPSULE = "unitCylinder"; public static final String UNITCUBE = "unitCube"; public static final String MODEL_PARTICLE = "particleModel"; public static final String TEXTURE_PARTICLE = "particleTexture"; diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java index 3c090feb..b2f671de 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java @@ -5,6 +5,7 @@ import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; import org.joml.Vector3d; import org.joml.Vector3f; @@ -149,7 +150,7 @@ public class LoadingUtils { //send default template back String race = EDITOR_RACE_NAME; if(!isEditor){ - List races = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces(); + List races = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().stream().filter((String name) -> !name.equals(EDITOR_RACE_NAME)).collect(Collectors.toList()); race = races.get(new Random().nextInt(races.size())); } CreatureData type = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(race); diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java index 119c0d02..368fd126 100644 --- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java @@ -192,7 +192,7 @@ public class DebugContentPipeline implements RenderPipeline { if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE) != null){ CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); switch(template.getType()){ - case "CYLINDER": { + case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { if((physicsGraphicsModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER)) != null){ //set color based on collision status, type, etc Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png"); @@ -210,7 +210,7 @@ public class DebugContentPipeline implements RenderPipeline { physicsGraphicsModel.draw(renderPipelineState,openGLState); } } break; - case "CUBE": { + case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { if((physicsGraphicsModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITCUBE)) != null){ //set color based on collision status, type, etc Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png"); @@ -229,6 +229,28 @@ public class DebugContentPipeline implements RenderPipeline { physicsGraphicsModel.draw(renderPipelineState,openGLState); } } break; + case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { + if((physicsGraphicsModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITCAPSULE)) != null){ + //set color based on collision status, type, etc + Texture texture = Globals.assetManager.fetchTexture("Textures/transparent_blue.png"); + if(texture != null){ + texture.bind(openGLState); + } + Vector3d position = EntityUtils.getPosition(physicsEntity); + Quaterniond rotation = EntityUtils.getRotation(physicsEntity); + //calculate camera-modified vector3d + Vector3d cameraModifiedPosition = new Vector3d(position).add(template.getOffsetX(),template.getDimension1() + template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(rotation); + modelTransformMatrix.scale(template.getDimension1(),template.getDimension2() * 0.5 + template.getDimension1() + template.getDimension1(),template.getDimension3()); + physicsGraphicsModel.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + } break; + default: { + throw new Error("Unsupported shape type!"); + } } } }