Collision detection doesn't stop detecting

I’m running into a strange issue with the collision detector. I’m creating a game without any physics, so I’m using the GhostControllers with a custom CollisionDetector (code below). After boot sequence, everything works fine, and collision detection happens when my objects collide, but the detection keeps cycling long after my objects are no longer colliding. It seems that the longer the my objects are in the collided state, the longer it takes for them to stop being collided.

Is there a configuration I’m missing in order to turn off collision after my objects are no longer colliding?


public class CollisionDetection implements PhysicsCollisionListener {

public CollisionDetection(BulletAppState bulletAppState) {
    bulletAppState.getPhysicsSpace().addCollisionListener(this);
}

@Override
public void collision(PhysicsCollisionEvent event) {
    GameObject aObj = GameObjectFactory.getGameObject(event.getNodeA().getName());
    GameObject bObj = GameObjectFactory.getGameObject(event.getNodeB().getName());
    if (KillableObject.class.isAssignableFrom(aObj.getClass())) {
        tryKill((KillableObject) aObj);
    } else if (KillableObject.class.isAssignableFrom(bObj.getClass())) {
        tryKill((KillableObject) bObj);
    }
}

private void tryKill(KillableObject killableObject) {
    if (killableObject.canKill()) {
        FactoryFactory.setGameState(GameState.KILLED);
    }
}

}

I haven’t worked with those so I can’t help with that. However, since you’re saying you don’t use any physics; are you aware you can handle collision without using Bullet?
https://jmonkeyengine.github.io/wiki/jme3/advanced/collision_and_intersection.html

I’d orignally looked at this option but this restriction prevented me from being able to use this method.

“An important restriction is that you can only collide geometry vs bounding volumes or rays. (This means for example that a must be of Type Node or Geometry and b respectively of Type BoundingBox, BoundingSphere or Ray.)”

Hopefully someone will correct me if I’m wrong, but I think this means that you can still collide two collidables (such as a two bounding spheres), but in order to collide two geometries, you have to reference the second one’s bounding volume.

  geometry0.collideWith(geometry1.getWorldBounds());

I had noticed a similar issue in JME3 demos,specifically jme3test.bullet.TestAttachGhostObject where collision appears to be happening even for some time after the objects are not colliding anymore.
It resembles a delay in ghost object collision detection.

Could this issue be cause by the fact I’m locking my screen rate to 60hz even though my computer is running faster than that? I haven’t dove into the JNI components yet, but it seems to me that there is a collision queue that is getting populated at a different rate then it is getting drained.

That would depend on how you are doing that, how you’ve setup physics, and a dozen other things that are in code we can’t see.

You are more likely to get help on an issue like this if you can post a complete (simplified, single class) test case that illustrates the issue.

This is generally how I’ve got everything configured.

public class Application extends SimpleApplication {

    private ScreenMapping screenMapping;
    private BulletAppState bulletAppState;

    public static void main(String[] args) {
        Application app = new Application();
        AppSettings settings = new AppSettings(true);
        settings.setFrameRate(60);
        app.setSettings(settings);
        app.start(); // start the game
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        CollisionDetection detector = new CollisionDetection(bulletAppState);

        List<GameObject> gameObjects = new ArrayList();
        gameObjects.add(GameObjectFactory.makeObject(new Vector2f(1, 0, 0)));
        gameObjects.add(GameObjectFactory.makeObject(new Vector2f(4, 0, 0)));

        for(GameObject obj : gameObjects) {
            rootNode.attach(obj)
        }
        bulletAppState.getPhysicsSpace().add(screenMapping.getCanvasNode());
        for(GameObject obj : gameObjects) {
            bulletAppState.getPhysicsSpace().add(obj.getSpatial());
        }
    }

    @Override
    public void simpleUpdate(float tpf) {
        ...
    }
}
public class GameObject {
    Spatial spatial;

    public GameObject(Spatial spatial) {
        this.spatial = spatial;
        CollisionShape shape = new BoxCollisionShape(new Vector(1, 1, 1));
        this.spatial.addControl(createGhostControl(shape));
    }

    public GhostControl createGhostControl(CollisionShape collisionShape) {
        GhostControl control = new GhostControl(collisionShape);
        control.removeCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_01);
        control.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
        return control;
    }
}

Half of my objects need to collide with another half, that’s why I’m using collisionGroups. I can confirm that collisions start when they should, but they continue long after they should.

Yeah. And since the example uses BoxCollisionShape, that limitation shouldn’t be an issue.

I was able to switch over to Collidables relatively easily. Thanks for the pointers.