Null pointer exception in PhysicsCollisionListener when calling event.getNodeA() on android

Hello, I have the same problem that the user “cocoliso” had on:

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/null-pointer-exception-in-collision-listener-on-android/

and

http://hub.jmonkeyengine.org/groups/physics/forum/topic/null-pointer-exception-on-collision-method-in-android-3-1/



“normen” said:

“I cannot reproduce this, for me collision callbacks work fine both with native bullet and jbullet… Do the getObjectA and getObjectB return anything? The NPE can only happen if they are null.”



So I wrote a small test application:



[java]import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.;

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

import com.jme3.bullet.control.GhostControl;

import com.jme3.material.Material;

import com.jme3.math.
;

import com.jme3.scene.*;

import com.jme3.scene.shape.Box;



public class Main extends SimpleApplication {



public static void main(String[] args) {

Main app = new Main();

app.start();

}



BulletAppState bulletAppState;



@Override

public void simpleInitApp() {

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

bulletAppState.getPhysicsSpace().addCollisionListener(physicsCollisionListener);

bulletAppState.getPhysicsSpace().enableDebug(assetManager);



Geometry box1 = createBox();

rootNode.attachChild(box1);



Geometry box2 = createBox();

box2.move(1, 1, 1);

rootNode.attachChild(box2);

}







private PhysicsCollisionListener physicsCollisionListener = new PhysicsCollisionListener() {

public void collision(PhysicsCollisionEvent event) {

Spatial nodeA = event.getNodeA(); // the problem is here

}

};





private Geometry createBox() {

Geometry geom = new Geometry(“Box”, new Box(Vector3f.ZERO, 1, 1, 1));

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

mat.setColor(“Color”, ColorRGBA.White);

geom.setMaterial(mat);





GhostControl gControl = new GhostControl(new BoxCollisionShape(new Vector3f(1, 1, 1)));

geom.addControl(gControl);

bulletAppState.getPhysicsSpace().add(gControl);



return geom;

}

}[/java]



this code should run if you copy and paste this code on to new project.

If you run this on the desktop this will work.

But if you run this on Android you get this error:



E/AndroidHarness( 4696): java.lang.NullPointerException

E/AndroidHarness( 4696): SEVERE AndroidHarness 10:28:39 PM Exception thrown in Thread[GLThread 11,5,main]: at com.jme3.bullet.collision.PhysicsCollisionEvent.getNodeA(89)

E/AndroidHarness( 4696): at mygame.Main$1.collision(49)

E/AndroidHarness( 4696): at com.jme3.bullet.PhysicsSpace.distributeEvents(359)

E/AndroidHarness( 4696): at com.jme3.bullet.BulletAppState.update(173)

E/AndroidHarness( 4696): at com.jme3.app.state.AppStateManager.update(249)

E/AndroidHarness( 4696): at com.jme3.app.SimpleApplication.update(255)

E/AndroidHarness( 4696): at com.jme3.system.android.OGLESContext.onDrawFrame(412)

E/AndroidHarness( 4696): at android.opengl.GLSurfaceView$GLThread.guardedRun(1363)

E/AndroidHarness( 4696): at android.opengl.GLSurfaceView$GLThread.run(1118)



Can you test this if you have an android phone, do you get the NullPointerException as well?

Thanks.





note: I’m testing this on LG p500 - Android 2.3.3 - API level 10

CPU: ARMv6 at 600MHz (rev 5) features: swp half thumb fastmult vfp edsp java

CPU architecture: 6TEJ

GPU: OpenGL ES 2.0 and OpenGL ES-CM 1.1

GPU Renderer: Adreno ™ 200

This is due to the fact that android uses native bullet and that is not done yet. The fact that you run on android is an important side-info btw, thats why we ask you to post system info etc.

@normen said:
The fact that you run on android is an important side-info btw, thats why we ask you to post system info etc.


LG p500 – Android 2.3.3 – API level 10
CPU: ARMv6 at 600MHz (rev 5) features: swp half thumb fastmult vfp edsp java
CPU architecture: 6TEJ
GPU: OpenGL ES 2.0 and OpenGL ES-CM 1.1
GPU Renderer: Adreno (TM) 200

Yes, exactly. It seems the code for collisions that was lately contributed for native bullet has issues on certain platforms. It works for me but there were some kinks I wanted to iron out anyway so when I get to that I can hopefully also fix these issues.

I also have the same problem on my HTC sensation (2.3.4). @Iwergic solution with the type.processed or w/e filtering seemed .to work

I think this check helped me out:



[java]public void collision(PhysicsCollisionEvent event) {

if ( event.getObjectA() == null || event.getObjectB() == null )

return;





}

[/java]

The problem I had (and still have) is that the collision event is being fired more often than it should. If you structure your collision routine like below, it worked for me. You want to ignore calls when the PhysicsCollisionEvent type is not TYPE_PROCESSED. The routine is being called for the other types sometimes which have null objects for NodeA and/or NodeB.



[java]

public void collision(PhysicsCollisionEvent event) {

switch (event.getType()) {

case PhysicsCollisionEvent.TYPE_ADDED:

logger.log(Level.INFO, "Physics Collision Added");

break;

case PhysicsCollisionEvent.TYPE_DESTROYED:

logger.log(Level.INFO, "Physics Collision Destroyed");

break;

case PhysicsCollisionEvent.TYPE_PROCESSED:

// logger.log(Level.INFO, "Physics Collision Processed");



final Spatial nodeA = event.getNodeA();

if (nodeA != null) {

// logger.log(Level.INFO, "NodeA: {0}", nodeA.getName());

} else {

logger.log(Level.INFO, "NodeA is null");

return;

}



final Spatial nodeB = event.getNodeB();

if (nodeB != null) {

// logger.log(Level.INFO, "NodeB: {0}", nodeB.getName());

} else {

logger.log(Level.INFO, "NodeB is null");

return;

}



if ((nodeA == geometry) || (nodeB == geometry)) {

logger.log(Level.INFO, "Collision with Geometry");

if (state == State.MOVING) {

curTime = 0f;

state = State.STARTING_EXPLOSION;

}

}



break;

}



}



[/java]

2 Likes