Node not going away

I am trying to get rid of a node when it collides with anything but it stays and calls the collisionListener multiple times.
The node holds a sphere and a particle Emitter and it collides randomly with one of 6 Torus all right next to each other forming a target shape. When i run it most of the time the Sphere Node gets stuck in The torus and never goes away.

collisionListener:
[java]
private PhysicsCollisionListener collisionListener = new PhysicsCollisionListener() {
public void collision(PhysicsCollisionEvent event) {

        ColorRGBA start=null, end=null;
        Vector3f postion=null;
        SpellBall ball=null;
        
        /* Check if one of the objects collided was a spell Ball */
        if(event.getNodeA().getClass()==SpellBall.class){
            /* Get starting and ending colors */
            ball = (SpellBall) event.getNodeA();
            postion = ball.getLocalTranslation();
            rootNode.detachChild(ball);
            ball.removeFromParent();
            ball.detachAllChildren();
            start = ball.getElement().getStartColor();
            end = ball.getElement().getEndColor();
            prevBallA = ball;
        }
        
        
        if(event.getNodeB().getClass()==SpellBall.class){
            /* Get starting and ending colors */
            ball = (SpellBall) event.getNodeB();
            postion = ball.getLocalTranslation();
            rootNode.detachChild(ball);
            ball.removeFromParent();
            ball.detachAllChildren();
            if(start!=null){
                ColorRGBA temp = ball.getElement().getStartColor();
                start = start.mult(temp);
            }else{
                start = ball.getElement().getStartColor();
            }
            if(end!=null){
                ColorRGBA temp = ball.getElement().getStartColor();
                end = end.mult(temp);
            }else{
                end = ball.getElement().getStartColor();
            }
            prevBallB = ball;
        }
        
        if(ball!=null){
            System.out.println(ball);
        }
        
        if(start!=null && end!=null && postion!=null){
            Explosion explosion = new Explosion(
                    "Explosion "+explosions.size(), assetManager);
            explosion.setFlameColor(start, end);
            explosion.setupExplosion(renderManager);
            explosion.setLocalTranslation(postion);
            rootNode.attachChild(explosion);
            explosions.add(explosion);
        }
        
        System.out.println(event.getNodeA().getClass().getName()+":"+event.getNodeB().getClass().getName());
    }  
};

[/java]

Hi,

I’m not an expert but I’d few comments :

  1. class SpellBall seems to extends Node/Spatial. It's a bad practice. You show not extends Node/Spatial, it's better to use Control, UserData, id + link to your entity (more info in the wiki)
  2. when you removeFromParent or detach a spatial, it's didn't do the same on the PhysicsSpace => Physics object is always present in the Physics space I use the following code (not perfect, but works) [java] /** * remove physics from Physics space and from Node space (remove control) * @param spatial */ static void removeAllPhysic(Spatial spatial) { PhysicsControl physicsNode = null; while ((physicsNode = spatial.getControl(PhysicsControl.class)) != null) { if (physicsNode.getPhysicsSpace() != null) physicsNode.getPhysicsSpace().removeAll(spatial); spatial.removeControl(physicsNode); } if (spatial instanceof Node) { ((Node)spatial).getChildren().stream().forEach((v) -> removeAllPhysic(v)); } } [/java]
  3. Collision listener is call asynchronously => when you remove object from PhysicsSpace several collision can be already detected but not yet notified, and other collisions would be detected before remove will be applied. My own workarounds
    • your listener/processor have a list of node to ignore (already removed) or used a marker (eg store in userData) to ignore some collision
    • the listener generate an Event send to a pipe where you can trottle events before do the job. I use rxjava for events, ...

An other way I use to remove object :

[java]
void remove(Spatial e) {
removePhy(e);
e.removeFromParent();
}

private void removePhy(Spatial e) {
	BulletAppState bulletAppState = app.getStateManager().getState(BulletAppState.class);
    PhysicsSpace space = bulletAppState.getPhysicsSpace();
	space.removeAll(e);
}

[/java]

The simplest way of removing a PhysicsControl from the physicsSpace is calling setEnabled(false) on it

Thanks, a lot guys that worked great :slight_smile:

@david.bernard.31 said: Hi,

I’m not an expert but I’d few comments :

  1. class SpellBall seems to extends Node/Spatial. It's a bad practice. You show not extends Node/Spatial, it's better to use Control, UserData, id + link to your entity (more info in the wiki)

Good to know, where in the wiki is the more info?

Under “Best Practices”…