Linear damping tied to framerate on gravity/normal

This commit is contained in:
austin 2021-07-21 01:05:48 -04:00
parent 719a0eaa9c
commit 0d10747f09
4 changed files with 146 additions and 6 deletions

View File

@ -7,6 +7,7 @@ import electrosphere.entity.state.movement.Impulse;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor;
import java.util.concurrent.CopyOnWriteArrayList;
@ -65,7 +66,10 @@ public class GravityTree {
state = GravityTreeState.NOT_ACTIVE;
}
public void simulate(){
static final float gravityConstant = 0.3f;
static final float linearDamping = 0.002f;
public void simulate(float deltaTime){
float velocity = CreatureUtils.getVelocity(parent);
float acceleration = CreatureUtils.getAcceleration(parent);
float maxNaturalVelocity = CreatureUtils.getMaxNaturalVelocity(parent);
@ -104,7 +108,15 @@ public class GravityTree {
if(hadGroundCollision()){
state = GravityTreeState.NOT_ACTIVE;
} else {
position.set(new Vector3f(position.x,position.y - 0.08f,position.z));
float gravityDif = gravityConstant * (float)Math.pow(1.0f - linearDamping,deltaTime);
Vector3f newGravityPos = new Vector3f(position.x,position.y - gravityDif,position.z);
float hitFraction = Globals.collisionEngine.sweepTest(body, position, newGravityPos);
if(hitFraction >= 0){
position.set(new Vector3f(position.x,position.y - gravityDif * hitFraction,position.z));
} else {
position.set(new Vector3f(position.x,position.y - gravityDif,position.z));
}
// System.out.println(hitFraction);
bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(position),1.0f);
body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
}

View File

@ -1,15 +1,22 @@
package electrosphere.game.collision;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.BroadphasePair;
import com.bulletphysics.collision.broadphase.BroadphaseProxy;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
import com.bulletphysics.collision.broadphase.Dispatcher;
import com.bulletphysics.collision.broadphase.OverlappingPairCache;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.CollisionWorld.ClosestConvexResultCallback;
import com.bulletphysics.collision.dispatch.CollisionWorld.ConvexResultCallback;
import com.bulletphysics.collision.dispatch.CollisionWorld.LocalConvexResult;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.narrowphase.ManifoldPoint;
import com.bulletphysics.collision.narrowphase.PersistentManifold;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.InternalTickCallback;
@ -18,6 +25,7 @@ import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.util.ObjectArrayList;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@ -25,6 +33,7 @@ import electrosphere.entity.state.movement.Impulse;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.server.world.ServerWorldData;
import static electrosphere.main.Main.deltaTime;
import java.util.ArrayList;
import java.util.List;
import org.joml.Vector3f;
@ -40,6 +49,7 @@ public class CollisionEngine {
BroadphaseInterface broadphase;
DefaultCollisionConfiguration collisionConfiguration;
CollisionDispatcher dispatcher;
InternalTickCallback callback;
List<Entity> collisionEntities = new ArrayList();
List<Entity> physicsEntities = new ArrayList();
@ -48,6 +58,8 @@ public class CollisionEngine {
List<CollisionObject> collisionObject = new ArrayList();
List<Collidable> collidableList = new ArrayList();
static final float linearDamping = 0.2f;
public CollisionEngine(){
broadphase = new DbvtBroadphase();
collisionConfiguration = new DefaultCollisionConfiguration();
@ -63,7 +75,7 @@ public class CollisionEngine {
//
// world.addRigidBody(boxRigidBody);
world.setInternalTickCallback(new InternalTickCallback(){
callback = new InternalTickCallback(){
@Override
public void internalTick(DynamicsWorld dw, float f) {
Dispatcher dispatcher = dw.getDispatcher();
@ -82,6 +94,8 @@ public class CollisionEngine {
ManifoldPoint contactPoint = manifold.getContactPoint(j);
if (contactPoint.getDistance() < 0.0f) {
magnitude = contactPoint.getDistance();
//linear dampen
magnitude = magnitude * (float)Math.pow(1.0f - linearDamping,deltaTime) * deltaTime * 8;
hit = true;
normal = new Vector3f(contactPoint.normalWorldOnB.x,contactPoint.normalWorldOnB.y,contactPoint.normalWorldOnB.z);
break;
@ -95,7 +109,8 @@ public class CollisionEngine {
}
}
}
}, world);
};
world.setInternalTickCallback(callback, world);
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11507
//https://www.google.com/search?client=firefox-b-1-d&q=bullet+set+position+and+check+if+collision
@ -159,7 +174,9 @@ public class CollisionEngine {
}
public void simulatePhysics(float time){
world.stepSimulation(time);
world.performDiscreteCollisionDetection();
callback.internalTick(world, time);
// world.stepSimulation(time);
}
/**
@ -278,4 +295,103 @@ public class CollisionEngine {
return entityHeight > worldHeight + 0.1f;
}
public float sweepTest(CollisionObject object, Vector3f startPos, Vector3f endPos){
SphereShape sphere = new SphereShape(0.1f);
// CollisionObject collider = new CollisionObject();
// collider.setCollisionShape(sphere);
ClosestConvexResultCallbackImpl callback = new ClosestConvexResultCallbackImpl(startPos,endPos,object,dispatcher,world.getPairCache());
callback.collisionFilterGroup = 1;
callback.collisionFilterMask = 1;
world.convexSweepTest(sphere, PhysicsUtils.jomlVecToTransform(startPos), PhysicsUtils.jomlVecToTransform(endPos), callback);
// callback.hasHit()
if(callback.hasHit()){
return callback.closestHitFraction;
} else {
return -1.0f;
}
}
// private static class SpecificConvexResultCallback extends ConvexResultCallback {
//
// @Override
// public float addSingleResult(LocalConvexResult convexResult, boolean bln) {
// }
//
// }
private static class ClosestConvexResultCallbackImpl extends ClosestConvexResultCallback {
CollisionObject me;
private OverlappingPairCache pairCache;
private Dispatcher dispatcher;
public ClosestConvexResultCallbackImpl(Vector3f startPos, Vector3f endPos, CollisionObject me, Dispatcher dispatcher, OverlappingPairCache pairCache){
super(PhysicsUtils.jomlToVecmathVector3f(startPos),PhysicsUtils.jomlToVecmathVector3f(endPos));
this.me = me;
this.pairCache = pairCache;
this.dispatcher = dispatcher;
}
@Override
public float addSingleResult(LocalConvexResult convexResult, boolean normalInWorldSpace) {
if (convexResult.hitCollisionObject == me) {
return 1f;
}
Vector3f linVelA = new Vector3f(), linVelB = new Vector3f();
linVelA.sub(PhysicsUtils.vecmathToJomlVector3f(convexToWorld), PhysicsUtils.vecmathToJomlVector3f(convexFromWorld));
linVelB.set(0f, 0f, 0f);//toB.getOrigin()-fromB.getOrigin();
Vector3f relativeVelocity = new Vector3f();
relativeVelocity.sub(linVelA, linVelB);
// don't report time of impact for motion away from the contact normal (or causes minor penetration)
if (convexResult.hitNormalLocal.dot(PhysicsUtils.jomlToVecmathVector3f(relativeVelocity)) >= -0f) {
return 1f;
}
return super.addSingleResult(convexResult, normalInWorldSpace);
}
@Override
public boolean needsCollision(BroadphaseProxy proxy0) {
// don't collide with itself
if (proxy0.clientObject == me) {
return false;
}
// don't do CCD when the collision filters are not matching
if (!super.needsCollision(proxy0)) {
return false;
}
CollisionObject otherObj = (CollisionObject)proxy0.clientObject;
// call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
if (dispatcher.needsResponse(me, otherObj)) {
// don't do CCD when there are already contact points (touching contact/penetration)
ObjectArrayList<PersistentManifold> manifoldArray = new ObjectArrayList<PersistentManifold>();
BroadphasePair collisionPair = pairCache.findPair(me.getBroadphaseHandle(), proxy0);
if (collisionPair != null) {
if (collisionPair.algorithm != null) {
//manifoldArray.resize(0);
collisionPair.algorithm.getAllContactManifolds(manifoldArray);
for (int j=0; j<manifoldArray.size(); j++) {
PersistentManifold manifold = manifoldArray.getQuick(j);
if (manifold.getNumContacts() > 0) {
return false;
}
}
}
}
}
return true;
}
}
}

View File

@ -266,6 +266,18 @@ public class PhysicsUtils {
return new javax.vecmath.Quat4f(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
}
public static com.bulletphysics.linearmath.Transform jomlVecToTransform(Vector3f vector){
com.bulletphysics.linearmath.Transform transform = new com.bulletphysics.linearmath.Transform();
javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
transformMatrix.setIdentity();
transformMatrix.setTranslation(new javax.vecmath.Vector3f(vector.x, vector.y, vector.z));
transform.set(transformMatrix);
return transform;
}
public static void setRigidBodyTransform(Vector3f position, Quaternionf rotation, CollisionObject body){
com.bulletphysics.linearmath.Transform transform = new com.bulletphysics.linearmath.Transform();

View File

@ -61,7 +61,7 @@ public class MicroSimulation {
//simulate creature gravity trees
for(Entity currentGravity : Globals.entityManager.getGravityEntities()){
GravityTree gravityTree = (GravityTree)currentGravity.getData(EntityDataStrings.GRAVITY_TREE);
gravityTree.simulate();
gravityTree.simulate(deltaTime);
}
//attacker behavior tree
for(Entity currentAttacker : Globals.entityManager.getAttackerEntities()){