From 9566bf27209146ea2d57d915662ea3395f149388 Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 15 May 2025 19:23:32 -0400 Subject: [PATCH] physics work --- assets/Data/entity/creatures/human.json | 16 +++---- docs/src/progress/renderertodo.md | 2 + .../components/imgui/CollidableEditBlock.java | 27 +++++++++++ .../collision/CollisionEngine.java | 18 ++++++- .../collision/collidable/SurfaceParams.java | 48 +++++++++++++++++++ .../electrosphere/engine/time/Timekeeper.java | 2 +- 6 files changed, 102 insertions(+), 11 deletions(-) diff --git a/assets/Data/entity/creatures/human.json b/assets/Data/entity/creatures/human.json index 6895c5cc..5a8ebc65 100644 --- a/assets/Data/entity/creatures/human.json +++ b/assets/Data/entity/creatures/human.json @@ -148,8 +148,8 @@ "movementSystems" : [ { "type" : "GROUND", - "acceleration" : 4000.0, - "maxVelocity" : 20.5, + "acceleration" : 400.0, + "maxVelocity" : 80.5, "strafeMultiplier" : 1.0, "backpedalMultiplier" : 0.5, "footstepFirstAudioOffset" : 0.2, @@ -182,7 +182,7 @@ { "type" : "JUMP", "jumpFrames" : 3, - "jumpForce" : 1.3, + "jumpForce" : 80, "animationJump" : { "nameThirdPerson" : "Jump", "nameFirstPerson" : "Jump", @@ -388,10 +388,10 @@ ] }, "collidable" : { - "type" : "CAPSULE", - "dimension1" : 0.25, - "dimension2" : 0.9, - "dimension3" : 0.25, + "type" : "CYLINDER", + "dimension1" : 0.35, + "dimension2" : 1.6, + "dimension3" : 0.35, "linearFriction": 0.001, "mass": 0.3, "rotX": 0, @@ -399,7 +399,7 @@ "rotZ": 0, "rotW": 1, "offsetX" : 0, - "offsetY" : 0.7, + "offsetY" : 0.8, "offsetZ" : 0, "angularlyStatic" : true }, diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d445b508..4dffba14 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1835,6 +1835,8 @@ Load main level only loads human now Human uses capsule collidable Physics debug render renders capsules Fix virtual scrollable working with certain panels +Humans use capsule shape now +Physics numbers reworked diff --git a/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java b/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java index efb50d61..fa602c89 100644 --- a/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java +++ b/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java @@ -2,6 +2,7 @@ package electrosphere.client.ui.components.imgui; import org.ode4j.ode.DBody; import org.ode4j.ode.DBox; +import org.ode4j.ode.DCapsule; import org.ode4j.ode.DCylinder; import org.ode4j.ode.DGeom; import org.ode4j.ode.DMass; @@ -117,6 +118,32 @@ public class CollidableEditBlock { float adjusted = (float)Math.log(mass[0] + 1); massObj.setMass(adjusted); } + } else if(geom instanceof DCapsule){ + DCapsule cylinder = (DCapsule)geom; + if(ImGui.sliderFloat3("Offset", offset, MIN_OFFSET, MAX_OFFSET)){ + cylinder.setOffsetPosition(offset[0], offset[1], offset[2]); + template.setOffsetX(offset[0]); + template.setOffsetY(offset[1]); + template.setOffsetZ(offset[2]); + geom.enable(); + } + if(ImGui.sliderFloat("Radius",radius,MIN_SCALE,MAX_SCALE)){ + cylinder.setParams(radius[0], cylinder.getLength()); + template.setDimension1(radius[0]); + template.setDimension3(radius[0]); + geom.enable(); + } + if(ImGui.sliderFloat("Length",length,MIN_SCALE,MAX_SCALE)){ + cylinder.setParams(cylinder.getRadius(), length[0]); + template.setDimension2(length[0]); + geom.enable(); + } + if(physicsBody.getMass() instanceof DMass && ImGui.sliderFloat("Mass",mass,MIN_MASS,MAX_MASS)){ + DMass massObj = (DMass)physicsBody.getMass(); + float adjusted = (float)Math.log(mass[0] + 1); + massObj.setMass(adjusted); + geom.enable(); + } } else { throw new Error("Unsupported geom type! " + geom); } diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 681f76fa..b58718e4 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -52,8 +52,10 @@ import electrosphere.logger.LoggerInterface; */ public class CollisionEngine { - //gravity constant - public static final float GRAVITY_MAGNITUDE = 0.15f; + /** + * gravity constant + */ + public static final float GRAVITY_MAGNITUDE = 5f; /** * The damping applied to angular velocity @@ -82,6 +84,11 @@ public class CollisionEngine { */ public static final int COLLIDABLE_COUNT_WARNING_THRESHOLD = 5000; + /** + * Quickstep iteration count + */ + public static final int QUICKSTEP_ITERATION_COUNT = 50; + /** * Default distance to interact with collidables at (ie picking where to place things) */ @@ -146,6 +153,7 @@ public class CollisionEngine { public CollisionEngine(){ world = OdeHelper.createWorld(); world.setGravity(0,-GRAVITY_MAGNITUDE,0); + world.setQuickStepNumIterations(QUICKSTEP_ITERATION_COUNT); space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT); // world.setContactMaxCorrectingVel(0.1); // world.setContactSurfaceLayer(0.001); @@ -365,6 +373,12 @@ public class CollisionEngine { if(surfaceParams.getBounceVel() != null){ contact.surface.bounce_vel = surfaceParams.getBounceVel(); } + if(surfaceParams.getSoftErp() != null){ + contact.surface.soft_erp = surfaceParams.getSoftErp(); + } + if(surfaceParams.getSoftCfm() != null){ + contact.surface.soft_cfm = surfaceParams.getSoftCfm(); + } } //calculate collisions int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer()); diff --git a/src/main/java/electrosphere/collision/collidable/SurfaceParams.java b/src/main/java/electrosphere/collision/collidable/SurfaceParams.java index 636d1b03..50a3f333 100644 --- a/src/main/java/electrosphere/collision/collidable/SurfaceParams.java +++ b/src/main/java/electrosphere/collision/collidable/SurfaceParams.java @@ -72,6 +72,20 @@ public class SurfaceParams { */ Double bounceVel; + /** + *

Error Reduction Parameter

+ *

How much of the penetration is corrected per time step

+ *

Note that mode must be set with dContactSoftERP.

+ */ + Double softErp; + + /** + *

Constraint Force Mixing

+ *

How soft or spongy the contact is

+ *

Note that mode must be set with dContactSoftCFM.

+ */ + Double softCfm; + /** * Constructor */ @@ -83,6 +97,8 @@ public class SurfaceParams { rhoN = 10.0; bounce = 0.001; bounceVel = 100.0; + softErp = 0.2; + softCfm = 1e-5; } /** @@ -141,6 +157,22 @@ public class SurfaceParams { return bounceVel; } + /** + * Gets the error reduction parameter + * @return The error reduction parameter + */ + public Double getSoftErp(){ + return softErp; + } + + /** + * Gets the constraining force mixing + * @return The constraining force mixing + */ + public Double getSoftCfm(){ + return softCfm; + } + /** * Sets the rolling friction of the surface params * @param friction The rolling friction @@ -157,4 +189,20 @@ public class SurfaceParams { this.mu = linearFriction; } + /** + * Sets the error reduction parameter + * @param softErp The error reduction parameter + */ + public void setSoftErp(double softErp){ + this.softErp = softErp; + } + + /** + * Sets the constraint force mixing + * @param softCfm The constraint force mixing + */ + public void setSoftCfm(double softCfm){ + this.softCfm = softCfm; + } + } diff --git a/src/main/java/electrosphere/engine/time/Timekeeper.java b/src/main/java/electrosphere/engine/time/Timekeeper.java index b7c5ad6e..139c5284 100644 --- a/src/main/java/electrosphere/engine/time/Timekeeper.java +++ b/src/main/java/electrosphere/engine/time/Timekeeper.java @@ -37,7 +37,7 @@ public class Timekeeper { public static final int SIM_FRAME_HARDCAP = 3; //step interval time size (for physics) - public static final float ENGINE_STEP_SIZE = 0.05f; + public static final float ENGINE_STEP_SIZE = 0.01f;