GhostControl is not overlapping

Hi,
I try to check if a npc which I can drag around the scene intersects with the sceneCollider, if I drop it.
This is the code I use:
[java] private boolean checkDropPossibility(CollisionResult closest) {
if (closest.getGeometry().getName().equals(WorldManager.GROUND)) {
Vector3f closPos = closest.getContactPoint();
Vector3f goToPos = new Vector3f(closPos.x, closPos.y + 7, closPos.z);

        Node testNode = new Node("TestNode");

        GhostControl shapeControl = new GhostControl(new CapsuleCollisionShape(3.5f, 7f, 1));
        testNode.addControl(shapeControl);
        rootNode.attachChild(testNode);
        testNode.setLocalTranslation(goToPos);
        physics.getPhysicsSpace().add(shapeControl);
        System.out.println("Count: " + shapeControl.getOverlappingCount());
        if (shapeControl.getOverlappingCount() > 0) {
            return false;
        }
            return true;
    } else {
        return false;
    }          
}[/java] 

However, getOverlappingCount is always 0. The GhostControl is at the right place when I enable Debug. How is that possible?

EDIT: Propably the problem is caused because none Physic Tick has passed when I check for overlappingObjects. The method is called in the simple application update loop. How can I make sure one physic Tick has passed and then check for collisions?

You have to read the manual… In particular, there is a whole chapter dealing with this trouble : look at ticks-listeners.
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics_listeners#physics_tick_listener

Call the method in the physicsTick() method? This will be called after a physicsTick. prePhysicsTick() can be used for updating things before a physicsTick.

Alternatively, You can use the integrated PhysicsCollisionListener: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics_listeners
You can have your npc-control implement this and do all your stuff in the control instead of in your simpleapplication. If you do so, don’t forget to register your listener to the PhysicsSpace (if you don’t do this, the collision(PhysicsCollisionEvent event) will never be triggered). But given your code, it does not seem you are using physics, although you are refering to physic Ticks?

Hey, thanks for your answer :).
The problem is that the npc is dragged into the scene when you press a mouse button. This calls the “add npc” method, which calls the method in the first post to check if the npc can be added, which only happens when he doesnt intersect with the World Collider. The mouse click gets recognized in the apps update loop. So how is it possible to instantly check if a collision occured with the ghostControl, or something like that if I do not call the method in a physicsTick, as I can’t do it in my case.

Did you check
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:collision_and_intersection

There is some information in here regarding collisions between non physical objects. It also tells you the requirements of the objects to be able to detect collisions between them. Maybe that will get you further?

I still don’t see why you are using physics. Is this only for the collision detection, or are you using it for other purposes as well? If it is only for collision detection, it might be over-kill, especially when you can implement it they way as described in above mentioned link.

1 Like

I don’t want to use physics in this case, but I don’t know what else I could do. If I try it with collide with, the only object I get collision with is the object itself, even if it isn’t a child of WorldCollider.
This is the code I use:
[java] private boolean checkDropPossibility(Vector3f mouse3d, Vector3f dir) {
Ray ray = new Ray(mouse3d, dir);
CollisionResults results = new CollisionResults();
((Node)((Node)rootNode.getChild(WorldManager.WORLD)).getChild(WorldManager.LANDSCAPE)).getChild(WorldManager.GROUND).collideWith(ray, results);
CollisionResult closest = results.getClosestCollision();
Vector3f closPos = closest.getContactPoint();
Vector3f goToPos = new Vector3f(closPos.x, closPos.y + 7, closPos.z);

    Node testNode = new Node("TestNode");
    Box box = new Box(3,6,3);
    Geometry test = new Geometry("Test1",box);
    test.setMaterial(new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"));
    testNode.attachChild(test);
    rootNode.attachChild(testNode);
    testNode.setLocalTranslation(goToPos);
    
    CollisionResults results2 = new CollisionResults();
    testNode.collideWith(rootNode.getChild(WorldManager.WORLDCOLLIDER).getWorldBound(), results2);
    
    if (results2.size() > 0) {
        for(int i = 0; i < results2.size();i++){
            CollisionResult r = results2.getCollision(i);
            System.out.println(r.getGeometry().getName());
        }
        return false;
    }
    return true;
}[/java]

When I swap the nodes and do rootNode.getChild(WorldManager.WORLDCOLLIDER).collideWith(testNode.getWorldBound(), results2); instead everything works fine. Thanks for your help :).

When I understand your code correctly, you first get the position where you have clicked with your mouse on the ground, then create a box 7 units above that position and after that, you check if this newly added box is colliding with the WORLDCOLLIDER. Seems good to me. Is your WORLDCOLLIDER’s bounding box where you expect it to be, or is it somewhere far away and thus not colliding with the NPC?

And you are saying ‘System.out.println(r.getGeometry().getName());’ is giving you “Test1”? That would be strange…

Just a wild guess, but would adding a boundingbox to your geometry help? Maybe it is not calculated by JME before you try to check for collisions? You could also quickly try to create your testNode during initialization and just move it out of the way for a while. As soon as you are going to place it, set its location to ‘goToPos’. Just to see if it has to do with timing.

[EDIT] --> Never mind, I just see you have solved it :slight_smile: