[Solved]PhysicsCollisionListener doesn’t detect collision

Hi

I can’t make PhysicsCollisionListener detect collision. I’ve read something about “Called when a collision happened in the PhysicsSpace, called from render thread.” and that if you attach the listener from another thread it will not work.

I’ve tried in many ways, but nothing works… also tried:

@Override
public void render(RenderManager rm){
System.out.println( "Render");
if (l==null){
l=new CollisionList();
getPhysicsSpace().addCollisionListener(l);
}
super.render(rm);
}

tried attaching from main class:
Physics physic = new Physics();
physic.startPhysics();
physic.getPhysicsSpace().addCollisionListener(new CollisionList() );

help please

All these commands are not the default jme3 commands, I guess you do something wrong in your own classes.

The code for promulgating a collision to the listeners is quite straight forward so I would start by ensuring your collision is actually generating a collision event. I have used the collision listeners and they work fine when a collision actually happens. Does you listener work with the simple collision tutorial?

@normenn: Why they are not JME3 default? maybe because I’m extending BulletAppState?



@mattm: TestCollisionListener and TestCollisionListener using my CollisionListener run fine. but they add the collision listener in the simpleInitApp() method, witch is from SimpleApplication.



I’m trying to keep in separate classes SimpleApplication and BulletAppState, so I can have physic without graphics… but i can’t understand from witch Thread I’ve to add the listener (if this means something)

@lesto: you dont need to extend bulletappstate or any class in jme3 except Application. You do everything on the OpenGL thread, so in initialize() or update(), read the best practices document on how to split your application logic into multiple classes.

If you must try add stuff to items used on the OpenGL thread from other threads then there is the enqueue method that will insert the data onto the OpenGL thread (and either wait for this to execute or continue). However, as normen said, try and do the stuff, like registering listeners, in the init method. You do not need to have graphics with the simple application, you can run it headless.

ok, but I’m not using Graphics, so I can’t use AppState, because I’m running only BulletAppState, so I’ve extended it (if you have a better idea please tell me)

maybe I’ve to extend Application and don’t use call render() method? but this will create a lot of garbage, IMHO



where I can add the CollisionListener?

initialize() and update() came from OpenGl Thread, as you say, (so from SimpleApplication) but I’m not using it! it doesn’t exist, I think



I’ve read the best practises

https://wiki.jmonkeyengine.org/legacy/doku.php/?do=search&id=best+practices

but the truth is there isn’t very much example, and all use graphics+physic together. I want keep the server light as possible, and client will need 2 physic engine, so please be kind with me :slight_smile:

The application does not do graphics when the renderer is set to null, you can still use the update loop then.

here again :slight_smile:

public class CustomApplication extends Application{

@Override
public void initialize(){
super.initialize();
AppStateBullet state = new AppStateBullet();
stateManager.attach(state);
state.bullet.getPhysicsSpace().addCollisionListener( new CollisionList() );
//System.out.println("Use the state's methods... " + state.getX());
}

@Override
public void update(){
super.update();
float tpf = timer.getTimePerFrame();

stateManager.update(tpf);
stateManager.render(renderManager);
renderManager.render(tpf);
}

}


class AppStateBullet extends AbstractAppState and contain a BulletAppState. This class does everything I was doing in the BulletAppState extension. (simply some add method put input Rigid body in a list and the body are added to the world at the update call)

But CollisionList doesn't work!

p.s. There is no GUI, but a black window... where is created? at the end the server probably will run on an only-text SO, so everything is graphic and can cause crash have to be eliminated!

Just use a SimpleApplication, its not “simple” as in reducing your options. Probably we should change that name to keep people from avoiding it…

change to SimpleApplication, initialize() changed to simpleInitApp(), but the CollisionList still doesn’t work…


@Override
public void simpleInitApp() {
//super.simpleInitApp();

/** Configure cam to look at scene */
cam.setLocation(new Vector3f(0, 20, 0));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(105);

AppStateBullet state = new AppStateBullet();
stateManager.attach(state);
state.startPhysic();
state.bullet.getPhysicsSpace().addCollisionListener( new CollisionList() );
//System.out.println("Use the state's methods... " + state.getX());
}


edit: CollisionList work with default jme3 test, I can't understand where is the difference!

AppStateBullet is not the default class, again, when you use your own classes you have to debug yourself, I cannot know what you do in these classes and I dont wont to debug your whole software…

ok, if I create the AppStateBullet inside Application and then attach the listener everything work.

if I try to attach listener from BulletAppState or inside an AppState that containing BulletAppState nothing works… this is a little annoying and IMHO weird.

There are possibility that this will change?



thanks for help :slight_smile:

I think you have some other problem there. Most probably a threading problem, the physics has to be started on the thread that receives the collision messages, which is the one the update loop runs on, the “OpenGL thread” (even when opengl is not running).

the physics has to be started on the thread that receives the collision messages, which is the one the update loop runs on, the “OpenGL thread”


So, the “OpenGL thread” is the Thread who call update and get the messages, and "physically" is Application ( as it implement SystemListener and call all the update() ) right?
like I'm doing now, and it work
if not, I'm not getting it
I've tried to attach the listener in the update() of the AppState who contains bullet, and also in the update() extending directly BulletAppState, but they don't implement SystemListener so all messages are lost, right?

Yeah, its like the runloop in most frameworks (AWT, Cocoa, what have you)

sorry, I’m not so much “insider”…

as I know AWT event listener can be added from everywhere (but maybe I’m wrong). Never tried Cocoa



So if I implement SystemListener in a class, maybe in another Thread(I don’t need this, is just speculation) and from this class I add a PhysicsCollisionListener to an BulletAppState I can “hear” the event?

Sorry but I’m too much tired to code some test now

No, just initialize it properly and you can listen from any thread.

just initialize it properly

this IS the problem. What I'm expected to do to initialize it properly?
"it" is? BulletAppState?
why isn't getPhysicsSpace().addCollisionListener( .. ); enough?

maybe you mean initialize PhysicsCollisionListener from Application an then pass it to others Thread?

argh, it's time to sleep

No, just like its shown in every tutorial and test. No calling startPhysics() etc., simply using it in initialize().