Problem with mesh collision shapes

Hey, i found a big problem with mesh collision shapes. I think it’s a bug…When i run my test code the following exception is threw :



[java]java.lang.NullPointerException

at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:119)

at com.bulletphysics.collision.dispatch.CompoundCollisionAlgorithm.destroy(CompoundCollisionAlgorithm.java:76)

at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:120)

at com.bulletphysics.collision.dispatch.CompoundCollisionAlgorithm.destroy(CompoundCollisionAlgorithm.java:76)

at com.bulletphysics.collision.dispatch.CollisionDispatcher.freeCollisionAlgorithm(CollisionDispatcher.java:120)

at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache.cleanOverlappingPair(HashedOverlappingPairCache.java:219)

at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache$CleanPairCallback.processOverlap(HashedOverlappingPairCache.java:447)

at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache.processAllOverlappingPairs(HashedOverlappingPairCache.java:190)

at com.bulletphysics.collision.broadphase.HashedOverlappingPairCache.cleanProxyFromPairs(HashedOverlappingPairCache.java:207)

at com.bulletphysics.collision.dispatch.CollisionWorld.removeCollisionObject(CollisionWorld.java:172)

at com.bulletphysics.dynamics.DiscreteDynamicsWorld.removeRigidBody(DiscreteDynamicsWorld.java:423)

at com.jme3.bullet.PhysicsSpace.removeNode(PhysicsSpace.java:608)

at com.jme3.bullet.PhysicsSpace.removeAll(PhysicsSpace.java:549)

at com.jme3.bullet.PhysicsSpace.removeAll(PhysicsSpace.java:573)

at mygame.test.OgreSceneTest.onAnalog(OgreSceneTest.java:122)

at com.jme3.input.InputManager.invokeAnalogs(InputManager.java:215)

at com.jme3.input.InputManager.invokeUpdateActions(InputManager.java:188)

at com.jme3.input.InputManager.update(InputManager.java:481)

at com.jme3.app.Application.update(Application.java:448)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:194)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:144)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:141)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:198)

at java.lang.Thread.run(Thread.java:662)[/java]



Then when i change the mesh collision shapes to other basics shapes it works fine.

It’s so difficult to explain, then is better you get the following test code and run in your machine :wink: :



[java]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package mygame.test;



    import com.jme3.app.SimpleApplication;

    import com.jme3.bullet.BulletAppState;

    import com.jme3.bullet.collision.shapes.CompoundCollisionShape;

    import com.jme3.bullet.collision.shapes.MeshCollisionShape;

    import com.jme3.bullet.nodes.PhysicsNode;

    import com.jme3.input.controls.AnalogListener;

    import com.jme3.input.controls.KeyTrigger;

    import com.jme3.material.Material;

    import com.jme3.math.ColorRGBA;

    import com.jme3.math.Vector3f;

    import com.jme3.renderer.RenderManager;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.debug.Grid;

    import com.jme3.scene.shape.Box;



    /**

    *
  • @author Glauco

    */

    public class OgreSceneTest extends SimpleApplication implements

    AnalogListener {



    /**
  • @param args the command line arguments

    */

    public static void main(String[] args) {

    // TODO code application logic here

    OgreSceneTest test = new OgreSceneTest();

    test.setShowSettings(false);

    test.start();

    }



    @Override

    public void simpleInitApp() {

    //set the app’s title to “PhysicsEditor”

    context.setTitle(“PhysicsEditor”);



    //set the background color to gray

    viewPort.setBackgroundColor(ColorRGBA.Gray);



    //do the app to use physics

    stateManager.attach(new BulletAppState());



    //increase the camera’s move speed

    flyCam.setMoveSpeed(100);



    //remove all app’s view informations

    guiNode.detachAllChildren();



    //attach a green grid 9x9 to the root node

    Grid grid = new Grid(18, 18, 1);

    Geometry gridgeo = new Geometry(“grid”, grid);

    Material mt = new Material(assetManager, “Common/MatDefs/Misc/WireColor.j3md”);

    mt.setColor(“m_Color”, ColorRGBA.Green);

    gridgeo.setMaterial(mt);

    gridgeo.center();

    rootNode.attachChild(gridgeo);



    //configure the cam’s position and rotation

    cam.getLocation().addLocal(0, 2, 0);

    cam.lookAt(new Vector3f(0, 0, 0), new Vector3f(0, 1, 0));



    Box box = new Box(1, 1, 1);

    Geometry geo = new Geometry(“geo”, box);

    geo.setMaterial(mt);

    Box box2 = new Box(1, 1, 1);

    Geometry geo2 = new Geometry(“geo”, box);

    geo2.setMaterial(mt);

    Box box3 = new Box(1, 1, 1);

    Geometry geo3 = new Geometry(“geo”, box);

    geo3.setMaterial(mt);

    CompoundCollisionShape c1 = new CompoundCollisionShape();

    //c1.addChildShape(new MeshCollisionShape(geo.getMesh()), Vector3f.ZERO.clone());

    c1.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

    CompoundCollisionShape c2 = new CompoundCollisionShape();

    //c2.addChildShape(new MeshCollisionShape(geo2.getMesh()), Vector3f.ZERO.clone());

    c2.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

    CompoundCollisionShape c3 = new CompoundCollisionShape();

    //c3.addChildShape(new MeshCollisionShape(geo3.getMesh()), Vector3f.ZERO.clone());

    c3.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

    PhysicsNode phynode = new PhysicsNode(geo, c1, 1);

    PhysicsNode phynode2 = new PhysicsNode(geo2, c2, 1);

    PhysicsNode phynode3 = new PhysicsNode(geo3, c3, 1);

    phynode.attachDebugShape(assetManager);

    phynode2.attachDebugShape(assetManager);

    phynode3.attachDebugShape(assetManager);

    phynode.updateGeometricState();

    phynode2.updateGeometricState();

    phynode3.updateGeometricState();

    rootNode.attachChild(phynode);

    rootNode.updateGeometricState();

    rootNode.attachChild(phynode2);

    rootNode.updateGeometricState();

    rootNode.attachChild(phynode3);

    rootNode.updateGeometricState();



    inputManager.addMapping(“start”, new KeyTrigger(keyInput.KEY_SPACE));

    inputManager.addMapping(“pause”, new KeyTrigger(keyInput.KEY_RSHIFT));

    inputManager.addListener(this, “start”, “pause”);



    }



    @Override

    public void simpleRender(RenderManager rm) {

    }



    @Override

    public void simpleUpdate(float tpf) {

    }



    public void onAnalog(String name, float value, float tpf) {

    if (name.equals(“start”)) {

    stateManager.getState(BulletAppState.class).getPhysicsSpace().addAll(rootNode);

    }

    if (name.equals(“pause”)) {

    stateManager.getState(BulletAppState.class).getPhysicsSpace().removeAll(rootNode);

    }

    }

    }

    [/java]



    I would like you run the test code testing the keys :

    key_space ( add all physics nodes to physics space) and key_r_right ( remove all physics nodes from physics space).

    perceive now it works fine…

    Now comment the uncommented lines and uncomment the commented lines at following lines and run the test code again( to test with mesh collision shapes now) :

    [java] //c1.addChildShape(new MeshCollisionShape(geo.getMesh()), Vector3f.ZERO.clone());

    c1.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

    //c2.addChildShape(new MeshCollisionShape(geo2.getMesh()), Vector3f.ZERO.clone());

    c2.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

    //c3.addChildShape(new MeshCollisionShape(geo3.getMesh()), Vector3f.ZERO.clone());

    c3.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());[/java]



    perceibe now it doens’t works…

Looks like you’re modifying the scene graph from another thread. There is a removeRigidBody() in the stacktrace, that must come from somewhere.

No, This is the single class. I added 2 key inputs to the test code.

KEY_SPACE AND KEY_RSHIFT. Where KEY_SPACE add all physics nodes to the physics space, and KEY_SHIFT remove instead.

When i run the test code it runs fine, until i press the KEY_SPACE and then i press KEY_RSHIFT and then a exception occours…

I did several tests with mesh collision shapes and other basics collision shapes ( box, sphere, cylinder ), and i concluded :

  • If three or more physics collision objects, with mesh shape or compound mesh shape each, and them to be added to physics space and then to be removed from physics space, a exception occours… but if them has another basic collision shape ( box, sphere or cylinder collision shape ) instead, nothing exception is throw. So i commented the lines : 79, 82 and 85… to test.

Does this also happen when you dont use the addAll/removeAll methods but add/remove them separately?

Hey, i did more tests… i experienced add/remove each physics collision object separately to see what happens…and now the exception in throw when i add them and not more when i remove them after added.

Before i tested as follows :



[java] public void onAnalog(String name, float value, float tpf) {

if (name.equals(“start”)) {

stateManager.getState(BulletAppState.class).getPhysicsSpace().addAll(rootNode);

}

if (name.equals(“pause”)) {

stateManager.getState(BulletAppState.class).getPhysicsSpace().removeAll(rootNode);

}

}[/java]



…and the exception just was threw after the physics collision object were be removed using removeAll ( after them were be added ) …



After i tested as follows :



[java]public void onAnalog(String name, float value, float tpf) {

if (name.equals(“start”)) {

//stateManager.getState(BulletAppState.class).getPhysicsSpace().addAll(rootNode);

for (Spatial spt : rootNode.getChildren()) {

if (spt instanceof PhysicsCollisionObject) {

stateManager.getState(BulletAppState.class).getPhysicsSpace().add(spt);

}

}

}

if (name.equals(“pause”)) {

//stateManager.getState(BulletAppState.class).getPhysicsSpace().removeAll(rootNode);

for (Spatial spt : rootNode.getChildren()) {

if (spt instanceof PhysicsCollisionObject) {

stateManager.getState(BulletAppState.class).getPhysicsSpace().remove(spt);

}

}

}

}[/java]



…And now the exception is throw so i added them.

OBS.: It occours just Mesh Collision Shapes, with Box, Cylinder or Sphere Collision Shapes it don’t occours.

And it just occours with three or more physics collision objects with mesh collision shapes…with 2 physics collision objects or 1 it don’t occours…

Try not using the listener, it might be its triggered multiple times…

Yes, i perceive it now, and i adjusted it to not be multiplied…but still the exception occours after i try to remove them from physics space…I did several tests…the mesh shapes has problems…

normen said:
Try not using the listener, it might be its triggered multiple times..

Could very well be it. You might be removing stuff twice.

I had the events fired twice until I realised that it sends an event for KeyUp -and- KeyDown (doh!).
I believe in the examples there is an &&KEYDOWN part in the "if (name.equals("pause")) {".

The exception has nothing to do with key events…If this is so hard to understand then see it :



[java]

Box box = new Box(1, 1, 1);

Geometry geo = new Geometry(“geo”, box);

geo.setMaterial(mt);

Box box2 = new Box(1, 1, 1);

Geometry geo2 = new Geometry(“geo”, box);

geo2.setMaterial(mt);

Box box3 = new Box(1, 1, 1);

Geometry geo3 = new Geometry(“geo”, box);

geo3.setMaterial(mt);

CompoundCollisionShape c1 = new CompoundCollisionShape();

c1.addChildShape(new MeshCollisionShape(geo.getMesh()), Vector3f.ZERO.clone());

//c1.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

CompoundCollisionShape c2 = new CompoundCollisionShape();

c2.addChildShape(new MeshCollisionShape(geo2.getMesh()), Vector3f.ZERO.clone());

//c2.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

CompoundCollisionShape c3 = new CompoundCollisionShape();

c3.addChildShape(new MeshCollisionShape(geo3.getMesh()), Vector3f.ZERO.clone());

//c3.addChildShape(new BoxCollisionShape(Vector3f.UNIT_XYZ), Vector3f.ZERO.clone());

PhysicsNode phynode = new PhysicsNode(geo, c1, 1);

PhysicsNode phynode2 = new PhysicsNode(geo2, c2, 1);

PhysicsNode phynode3 = new PhysicsNode(geo3, c3, 1);

phynode.setName(“phynode1”);

phynode2.setName(“phynode2”);

phynode3.setName(“phynode3”);

phynode.attachDebugShape(assetManager);

phynode2.attachDebugShape(assetManager);

phynode3.attachDebugShape(assetManager);

phynode.updateGeometricState();

phynode2.updateGeometricState();

phynode3.updateGeometricState();

rootNode.attachChild(phynode);

rootNode.updateGeometricState();

rootNode.attachChild(phynode2);

rootNode.updateGeometricState();

rootNode.attachChild(phynode3);

rootNode.updateGeometricState();

stateManager.getState(BulletAppState.class).getPhysicsSpace().addAll(rootNode);

//Obs.: Here occours the exception…

stateManager.getState(BulletAppState.class).getPhysicsSpace().removeAll(rootNode);

[/java]



Note : The exception just occours because the scene graph has 3 physics collision objects ( obviously 3 mesh shapes ), if had 2 or less the exception didn’t occours. Can trust me…I did several tests…Do you too ;)…

Yes and I get the same behavior but since you are on it you can test it further to find out whats the problem :stuck_out_tongue: Did you try with other meshes?

Ok, i tried with other meshes but the same exception occours when the removeAll(rootNode) method is called. And now i perceive more one problem…and now with Line meshes, but this time with Line meshes the exception occours without i call the addAll(rootNode) or the removeAll(rootNode) method…Line meshes get another behavior : java.lang.IndexOutOfBoundsException.



Here are the tested meshes for me:



[java]

Mesh mesh = null;

//mesh = new Box(1, 1, 1);

//mesh = new Cylinder(10, 10, 1, 3, true);

//mesh = new Sphere(10, 10, 1);

//mesh = new Dome(4, 10, 1);

//mesh = new Line(Vector3f.ZERO.clone(), Vector3f.UNIT_XYZ.clone());

//mesh = new PQTorus(10, 10, 1, 1, 10, 10);

//mesh = new Quad(1, 1, true);

mesh = new Torus(10, 10, 1, 1);

[/java]

Line meshes will not work. The meshes have to consist of closed triangles.

Hey, I’m trying convert quaternion to matrix3f, and unlike, but without sucess…I’m doing so :



[java]

private Matrix3f rotation;



public Quaternion getRotation() {

return new Quaternion().fromRotationMatrix(rotation);

}



public void setRotation(Quaternion rotation) {

this.rotation.set(rotation);

}

[/java]