Browse Source

- Added a test case for the add kinematic object to physic space to tets with native bullet
- made a workaround in PhysicSpace for non native

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7369 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 14 years ago
parent
commit
93d0ed73e3

+ 22 - 10
engine/src/jbullet/com/jme3/bullet/PhysicsSpace.java

@@ -132,8 +132,8 @@ public class PhysicsSpace {
     private int maxSubSteps = 4;
     private int maxSubSteps = 4;
     private javax.vecmath.Vector3f rayVec1 = new javax.vecmath.Vector3f();
     private javax.vecmath.Vector3f rayVec1 = new javax.vecmath.Vector3f();
     private javax.vecmath.Vector3f rayVec2 = new javax.vecmath.Vector3f();
     private javax.vecmath.Vector3f rayVec2 = new javax.vecmath.Vector3f();
-    private com.bulletphysics.linearmath.Transform sweepTrans1=new com.bulletphysics.linearmath.Transform(new javax.vecmath.Matrix3f());
-    private com.bulletphysics.linearmath.Transform sweepTrans2=new com.bulletphysics.linearmath.Transform(new javax.vecmath.Matrix3f());
+    private com.bulletphysics.linearmath.Transform sweepTrans1 = new com.bulletphysics.linearmath.Transform(new javax.vecmath.Matrix3f());
+    private com.bulletphysics.linearmath.Transform sweepTrans2 = new com.bulletphysics.linearmath.Transform(new javax.vecmath.Matrix3f());
     private AssetManager debugManager;
     private AssetManager debugManager;
 
 
     /**
     /**
@@ -559,7 +559,20 @@ public class PhysicsSpace {
 
 
     private void addRigidBody(PhysicsRigidBody node) {
     private void addRigidBody(PhysicsRigidBody node) {
         physicsNodes.put(node.getObjectId(), node);
         physicsNodes.put(node.getObjectId(), node);
+
+        //Workaround
+        //It seems that adding a Kinematic RigidBody to the dynamicWorld prevent it from being non kinematic again afterward.
+        //so we add it non kinematic, then set it kinematic again.
+        boolean kinematic = false;
+        if (node.isKinematic()) {
+            kinematic = true;
+            node.setKinematic(false);
+        }
         dynamicsWorld.addRigidBody(node.getObjectId());
         dynamicsWorld.addRigidBody(node.getObjectId());
+        if (kinematic) {
+            node.setKinematic(true);
+        }
+
         Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding RigidBody {0} to physics space.", node.getObjectId());
         Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding RigidBody {0} to physics space.", node.getObjectId());
         if (node instanceof PhysicsVehicle) {
         if (node instanceof PhysicsVehicle) {
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding vehicle constraint {0} to physics space.", ((PhysicsVehicle) node).getVehicleId());
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.INFO, "Adding vehicle constraint {0} to physics space.", ((PhysicsVehicle) node).getVehicleId());
@@ -695,13 +708,13 @@ public class PhysicsSpace {
      * You have to use different Transforms for start and end (at least distance > 0.4f).
      * You have to use different Transforms for start and end (at least distance > 0.4f).
      * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
      * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
      */
      */
-    public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end){
+    public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end) {
         List<PhysicsSweepTestResult> results = new LinkedList<PhysicsSweepTestResult>();
         List<PhysicsSweepTestResult> results = new LinkedList<PhysicsSweepTestResult>();
-        if(!(shape.getCShape() instanceof ConvexShape)){
+        if (!(shape.getCShape() instanceof ConvexShape)) {
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!");
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!");
             return results;
             return results;
         }
         }
-        dynamicsWorld.convexSweepTest((ConvexShape)shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
+        dynamicsWorld.convexSweepTest((ConvexShape) shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
         return results;
         return results;
 
 
     }
     }
@@ -711,17 +724,17 @@ public class PhysicsSpace {
      * You have to use different Transforms for start and end (at least distance > 0.4f).
      * You have to use different Transforms for start and end (at least distance > 0.4f).
      * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
      * SweepTest will not see a collision if it starts INSIDE an object and is moving AWAY from its center.
      */
      */
-    public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end, List<PhysicsSweepTestResult> results){
+    public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end, List<PhysicsSweepTestResult> results) {
         results.clear();
         results.clear();
-        if(!(shape.getCShape() instanceof ConvexShape)){
+        if (!(shape.getCShape() instanceof ConvexShape)) {
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!");
             Logger.getLogger(PhysicsSpace.class.getName()).log(Level.WARNING, "Trying to sweep test with incompatible mesh shape!");
             return results;
             return results;
         }
         }
-        dynamicsWorld.convexSweepTest((ConvexShape)shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
+        dynamicsWorld.convexSweepTest((ConvexShape) shape.getCShape(), Converter.convert(start, sweepTrans1), Converter.convert(end, sweepTrans2), new InternalSweepListener(results));
         return results;
         return results;
     }
     }
 
 
-    private class InternalSweepListener extends CollisionWorld.ConvexResultCallback{
+    private class InternalSweepListener extends CollisionWorld.ConvexResultCallback {
 
 
         private List<PhysicsSweepTestResult> results;
         private List<PhysicsSweepTestResult> results;
 
 
@@ -735,7 +748,6 @@ public class PhysicsSpace {
             results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln));
             results.add(new PhysicsSweepTestResult(obj, Converter.convert(lcr.hitNormalLocal), lcr.hitFraction, bln));
             return lcr.hitFraction;
             return lcr.hitFraction;
         }
         }
-
     }
     }
 
 
     /**
     /**

+ 80 - 0
engine/src/test/jme3test/bullet/TestKinematicAddToPhysicsSpaceIssue.java

@@ -0,0 +1,80 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package jme3test.bullet;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.bullet.BulletAppState;
+import com.jme3.bullet.PhysicsSpace;
+import com.jme3.bullet.collision.shapes.MeshCollisionShape;
+import com.jme3.bullet.collision.shapes.PlaneCollisionShape;
+import com.jme3.bullet.collision.shapes.SphereCollisionShape;
+import com.jme3.bullet.control.RigidBodyControl;
+import com.jme3.math.Plane;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Node;
+import com.jme3.scene.shape.Sphere;
+
+/**
+ *
+ * @author Nehon
+ */
+public class TestKinematicAddToPhysicsSpaceIssue extends SimpleApplication {
+
+    public static void main(String[] args) {
+        TestKinematicAddToPhysicsSpaceIssue app = new TestKinematicAddToPhysicsSpaceIssue();
+        app.start();
+    }
+    BulletAppState bulletAppState;
+
+    @Override
+    public void simpleInitApp() {
+
+        bulletAppState = new BulletAppState();
+        stateManager.attach(bulletAppState);
+        bulletAppState.getPhysicsSpace().enableDebug(assetManager);
+        // Add a physics sphere to the world
+        Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
+        physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0));
+        rootNode.attachChild(physicsSphere);
+
+        //Setting the rigidBody to kinematic before adding it to the physic space
+        physicsSphere.getControl(RigidBodyControl.class).setKinematic(true);
+        //adding it to the physic space
+        getPhysicsSpace().add(physicsSphere);         
+        //Making it not kinematic again, it should fall under gravity, it doesn't
+        physicsSphere.getControl(RigidBodyControl.class).setKinematic(false);
+
+        // Add a physics sphere to the world using the collision shape from sphere one
+        Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
+        physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(5, 6, 0));
+        rootNode.attachChild(physicsSphere2);
+        
+        //Adding the rigid body to physic space
+        getPhysicsSpace().add(physicsSphere2);
+        //making it kinematic
+        physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false);
+        //Making it not kinematic again, it works properly, the rigidbody is affected by grvity.
+        physicsSphere2.getControl(RigidBodyControl.class).setKinematic(false);
+
+      
+
+        // an obstacle mesh, does not move (mass=0)
+        Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0);
+        node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f));
+        rootNode.attachChild(node2);
+        getPhysicsSpace().add(node2);
+
+        // the floor mesh, does not move (mass=0)
+        Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new PlaneCollisionShape(new Plane(new Vector3f(0, 1, 0), 0)), 0);
+        node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f));
+        rootNode.attachChild(node3);
+        getPhysicsSpace().add(node3);
+
+    }
+
+    private PhysicsSpace getPhysicsSpace() {
+        return bulletAppState.getPhysicsSpace();
+    }
+}