Collision triggered multiple times on 1 object even after removing

Hi I’m trying to launch an object and when it hits the floor it has to be removed. What I’ve done:

An object is created on every mouse click

[java] Vector3f v3 = Player.getInstance().getLocalTranslation();

    // Get the position of the cursor
    Vector2f mouse = RePest.getInstance().getInputManager().getCursorPosition();

    Vector3f click3d = RePest.getInstance().getCamera().getWorldCoordinates(new Vector2f(mouse.x, mouse.y), 0f).clone();

    Vector2f v2 = new Vector2f(click3d.x - v3.x, click3d.y - 1.26f);
   
    v2.normalize();

    // Convert the 2d vector back to a 3d vector
    shootingdirection.x = v2.x;
    shootingdirection.y = v2.y;
    shootingdirection.z = 0f;

    Spatial object = level.getAssetManager().loadModel("Models/Extra/M_Blikje.j3o");

    level.getRootNode().attachChild(object);
    object.setLocalTranslation(Player.getInstance().getLocalTranslation());

    object.move(0.f, 1f, -0.2f);
    ball_phy = new TimeGuardBodyControl(level.getPhysics(),level.getRootNode(),level,RePest.getInstance().getRenderManager());
    object.addControl(ball_phy);
    level.getPhysics().getPhysicsSpace().add(ball_phy);
    ball_phy.setLinearVelocity(shootingdirection.mult(30f));[/java]

This works as it should.

As control it has a “TimeGuardBodyControl” object.

Which has a collision function:

[java] @Override
public void collision(PhysicsCollisionEvent event) {

    if (("M_Blikje-geom-0".equals(event.getNodeA().getName()) || "Schoolfloor".equals(event.getNodeA().getName())) && ("M_Blikje-geom-0".equals(event.getNodeB().getName()) || "Schoolfloor".equals(event.getNodeB().getName()))) {
        System.out.println("Node A " + event.getNodeA().getName());
        System.out.println("Node B " + event.getNodeB().getName());

        if (("M_Blikje-geom-0".equals(event.getNodeA().getName()))) {
            bulletAppState.getPhysicsSpace().remove(event.getNodeA().getControl(0));
            rootnode.detachChild(event.getNodeA());
        }

        if (("M_Blikje-geom-0".equals(event.getNodeB().getName()))) {
            bulletAppState.getPhysicsSpace().remove(event.getNodeB().getControl(0));
            rootnode.detachChild(event.getNodeB());
        }
    }
}[/java]

Now this effect happens:

First objects is launched and hits the floor: Collision is called once
2nd Object is launched and hits the floor: Collision is called twice when that object hits the floor
3th object is launched and hits the floor : Collision is called trice when that object hits the floor

and so on

If I check the code to launch an object is only called once when a mouseclick happens…

So, why is this happening ? Am I removing the object that hit the ground wrong ?

try just using .removeFromParent(), and also get the physicsControl by using node.getControl(PhysicsControl.class);

Ok, tried it:

   [java] if (("M_Blikje-geom-0".equals(event.getNodeA().getName()) || "Schoolfloor".equals(event.getNodeA().getName())) && ("M_Blikje-geom-0".equals(event.getNodeB().getName()) || "Schoolfloor".equals(event.getNodeB().getName()))) {
        System.out.println("Node A " + event.getNodeA().getName());
        System.out.println("Node B " + event.getNodeB().getName());

        if (("M_Blikje-geom-0".equals(event.getNodeA().getName()))) {
            //bulletAppState.getPhysicsSpace().remove(event.getNodeA().getControl(0));
            //rootnode.detachChild(event.getNodeA());
            bulletAppState.getPhysicsSpace().remove(event.getNodeA().getControl(PhysicsControl.class));
            event.getNodeA().removeFromParent();
        }

        if (("M_Blikje-geom-0".equals(event.getNodeB().getName()))) {
            //bulletAppState.getPhysicsSpace().remove(event.getNodeB().getControl(0));
            //rootnode.detachChild(event.getNodeB());
            bulletAppState.getPhysicsSpace().remove(event.getNodeB().getControl(PhysicsControl.class));
            event.getNodeA().removeFromParent();
        }
    }[/java]

But still the same effect.

(My output from launching 3 objects)

Node A M_Blikje-geom-0
Node B Schoolfloor

Node A M_Blikje-geom-0
Node B Schoolfloor
Node A M_Blikje-geom-0
Node B Schoolfloor

Node A M_Blikje-geom-0
Node B Schoolfloor
Node A M_Blikje-geom-0
Node B Schoolfloor
Node A M_Blikje-geom-0
Node B Schoolfloor

in the last if statement, you check if it is nodeB, but remove nodeA.

Thanks for pointing that out, I changed it. Though the problem remains.

   [java] if (("M_Blikje-geom-0".equals(event.getNodeA().getName()) || "Schoolfloor".equals(event.getNodeA().getName())) && ("M_Blikje-geom-0".equals(event.getNodeB().getName()) || "Schoolfloor".equals(event.getNodeB().getName()))) {
        System.out.println("Node A " + event.getNodeA().getName());
        System.out.println("Node B " + event.getNodeB().getName());

        if (("M_Blikje-geom-0".equals(event.getNodeA().getName()))) {
            //bulletAppState.getPhysicsSpace().remove(event.getNodeA().getControl(0));
            //rootnode.detachChild(event.getNodeA());
            bulletAppState.getPhysicsSpace().remove(event.getNodeA().getControl(PhysicsControl.class));
            event.getNodeA().removeFromParent();
        }

        if (("M_Blikje-geom-0".equals(event.getNodeB().getName()))) {
            //bulletAppState.getPhysicsSpace().remove(event.getNodeB().getControl(0));
            //rootnode.detachChild(event.getNodeB());
            bulletAppState.getPhysicsSpace().remove(event.getNodeB().getControl(PhysicsControl.class));
            event.getNodeB().removeFromParent();
        }
    }[/java]

I believe both the .removeFromParent and .remove methods return booleans - do they both return true?

1 Like

The remove does not return a boolean, but the removeFromParent does.

The output of launching 3 objects and printing the boolean:

Node A M_Blikje-geom-0
Node B Schoolfloor
true

Node A M_Blikje-geom-0
Node B Schoolfloor
true
Node A M_Blikje-geom-0
Node B Schoolfloor
false

Node A M_Blikje-geom-0
Node B Schoolfloor
true
Node A M_Blikje-geom-0
Node B Schoolfloor
false
Node A M_Blikje-geom-0
Node B Schoolfloor
false

So the collision is triggered falsely sometimes ?

I think i found it. By adding:

[java]bulletAppState.getPhysicsSpace().removeCollisionListener(this);[/java]

It is only triggered once for every object as it should.

Thanks for helping !

1 Like

Are you clearing the collision results?

If not, it likely just adding to the list.

Well it’s hard to pinpoint at this time. How large or small is the projectile? You might be moving a very small object too fast for the collision detection to work effectively, since it only checks every 1/60th of a second. Is this a possibility?