How to use PhysicsCollisionListener?


#1

How to use PhysicsCollisionListener?

I’m looking at the documentation on collisions to activate events.
I have a problem, according to the documentation, an addCollisionListener can be added to the physical space for later in the function detect collisions such as using the name of the collided nodes.

public void collision(PhysicsCollisionEvent CollisionesEncontradas){
    if(CollisionesEncontradas.getNodeA().getName().equals("esfera")){
         System.out.println("la esfera a entrado a un area de colision");
     }
     else if(CollisionesEncontradas.getNodeB().getName().equals("esfera")){
         System.out.println("la esfera a entrado a un area de colision");
     }
    
} //procesa las colisiones en las escena.

However when adding the ghostControl to the addcollisionListener I can not detect the collisions since the data type is not the same and I can not understand how it works

CODE:

 private void FisicaEnLaEscena(){
    ///////////agrega propiedades físicas a los nodos/////////////////
    fisica = new BulletAppState();//creo el objeto con las propiedades fisicas
    stateManager.attach(fisica);//agrego propiedades fisicas a la escena
    
    fisica.setDebugEnabled(true);//muestro las colisiones al renderizar
    //------------------------------------------------------------------------------//
 } //agrega propiedades físicas a los nodos


private void cubosConFisica(){
    ///creo las colisiones a todos los cubos
    cubos = ((Node)((Node)Escena_principal).getChild("ConjuntoCajas")).getChild("Scene");//busco al nodo 
    listaCubos = ((Node)cubos).getChildren();//guardo todos los nodos en una lista
    

    for(Spatial i : listaCubos){ //creo un bucle foreach
       i = ((Node)i).getChild(0);
       //crearColisiones(i, 1.0f,-200.0f);
       crearAreasColisionesFantasmas(i);
       //crearColisiones(i, 1.0f, -200);
       i.setMaterial(madera);
        
    }
} //agrega fisica a los cubos  


private void crearAreasColisionesFantasmas(Spatial i){
     ////creo un rigidbody control a las CAJAS le agrego las físicas
     
     //colisiones
     CollisionShape cajasColision = CollisionShapeFactory.createBoxShape(i);//creo la colision
    
     
     //cuerpo rigido
     GhostControl cuerpofantasmaCajas = new GhostControl(cajasColision);//creo el control del cuerpo y por parametro agrego la colision y la masa
     cuerpofantasmaCajas.addCollideWithGroup(0);
     i.addControl(cuerpofantasmaCajas);//agrego un controlador de fisica a ese objeto
     fisica.getPhysicsSpace().add(cuerpofantasmaCajas);//agrego a las fisicas del space
     
     
     fisica.getPhysicsSpace().addCollisionListener(cuerpofantasmaCajas);
     
     
 } //crea las colisiones fantasmas para detectar cuando un objeto entra



public void collision(PhysicsCollisionEvent CollisionesEncontradas){
    if(CollisionesEncontradas.getNodeA().getName().equals("esfera")){
         System.out.println("la esfera a entrado a un area de colision");
     }
     else if(CollisionesEncontradas.getNodeB().getName().equals("esfera")){
         System.out.println("la esfera a entrado a un area de colision");
     }
    
} //procesa las colisiones en las escena.

#2

GhostControl is not listener itself. You need Class that implement PhysicsCollisionListener

easy tip:

move cursor into () and press ctrl-space, you will see possibilities.

you need create own PhysicsCollisionListener extended class. there is example in:
https://wiki.jmonkeyengine.org/jme3/advanced/physics_listeners.html

so you can even extend GhostControl and make it implement PhysicsCollisionListener, then use it as listener. But imo better have it separate.


#3

Yes, I saw it … I wanted to avoid creating another class, but apparently if or if I have to work with another class … Thank you very much.


#4

imo you should just use Anonymous PhysicsCollisionListener. no need extend any other class.

like in a lot of JME or just Java method usages.


#5

It’s a lot to ask if I ask you for an example of code?


#6
    bulletAppState.getPhysicsSpace().addCollisionListener(new PhysicsCollisionListener() {
        @Override
        public void collision(PhysicsCollisionEvent event) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    });

?

if you use some IDE you can just ctrl-space or auto generate it.


#7

Thank you very much, it works, but why does it detect so many collisions if it only collides one time? If you look at the console you see that the message is executed many times on the screen

If I want to activate a sound it will sound many times then …


#8

this check collisions in ALL WORLD(all physics space you executed this method on).

also if something collide all the time, it could report many.

you need filter this to know your object.(as i see you already do so i think it just collide all time)

edit:

lets say barrel is rolling on ground, you need to know when to play sound of rolling metal barrel, so you check this collisions.


#9

But the message repeated 9 times is only shown when colliding with 1 object … what am I doing wrong … How is that filter … thanks for your time you are helping me a lot.


#10

i dont know, i dont see your game/app, i dont see what you do.

anyway 1 object can collide with second object more time than one time.


#11

Well thank you very much, you have helped me a lot, I will think about everything you said to me. When I solve this problem I will do a tutorial in Spanish.


#12

Physics collisions are reported multiple times because the listener is invoked once for every “contact manifold” and there can be up to 4 contact manifolds per collision object. And since there are 2 collision objects involved, you can get up to 8 invocations for a single collision.

Most of the time, you can just ignore the duplicates.


#13

How can I ignore those duplicates? It’s the big doubt I had all day …

both in godot engine and unity there is a function that produces an event when a body enters a non-collisionable area, however I can not find something similar in Jmonkey Engine.


#14

what I want is simply to increase a score when colliding, but I can not find a way to detect that collision and add 1 point in this way.


#15

To ignore duplicates, I’d keep track of which collisions the software has already seen (on the current physics tick).

I’ve never heard of non-collisionable areas before. What are they typically used for?


#16

This 2 minute video explains it better than me …


#17

That is, the 3 main functions that detect collisions are.
“When an object enters”
“when an object is inside”
“when an object comes out”

and with this I can easily make a score …
but in jmonkey engine there is no such thing.


#18

What function would I have to create for that? Because that’s my problem, I want the first collision to stop colliding so that for example, I can add a point.


#19

In jMonkeyEngine, there are at least 3 methods to have physics collisions without generating contact forces:

  1. You can use a PhysicsGhostObject instead of a PhysicsRigidBody. This is the oldest solution, but it isn’t much help for characters or vehicles.
  2. You can use .setContactResponse(false) to disable contact forces for particular collision objects. This is my preferred solution, but it’s relatively new. It was added to Minie v0.5.1 and jme3-bullet v3.3.0-alpha1. It also exists in master-branch jme3-jbullet, but hasn’t appeared in any jme3-jbullet release yet.
  3. I’ve heard you can use a PhysicsCollisionGroupListener listener which returns false. I’ve never tried this, so I don’t know how well it works.

#20

GHOSTCONTROL thought it was the solution, however it also returns many messages by console, that is, it detects many collisions.

I’m really about to give up … How would you do a simple score when destroying an object?