[Solved] Why does my mouse picking not collide with anything?

I am trying to follow the hello picking tutorial, to implement bullets that make a sound when they collide.

Currently, I have this code:

long lastShot = 0;

long sec = 1000000000L;

public void shoot(){
    //if (!shoot) return;
    if (lastShot + sec / 10 > System.nanoTime()){
        return;
    }
    lastShot = System.nanoTime();
    // 1. Reset results list.
    CollisionResults results = new CollisionResults();
    // 2. Aim the ray from cam loc to cam direction.
    Ray ray = new Ray(cam.getLocation(), cam.getDirection());
    // 3. Collect intersections between Ray and Shootables in results list.
    rootNode.collideWith(ray, results);
    // 4. Print the results
    System.out.println("----- Collisions? " + results.size() + "-----");
    for (int i = 0; i < results.size(); i++) {
      // For each hit, we know distance, impact point, name of geometry.
      float dist = results.getCollision(i).getDistance();
      Vector3f pt = results.getCollision(i).getContactPoint();
      String hit = results.getCollision(i).getGeometry().getName();
      System.out.println("* Collision #" + i);
      System.out.println("  You shot " + hit + " at " + pt + ", " + dist + " wu away.");
    }
    // 5. Use the results (we mark the hit object)
    if (results.size() > 0) {
      // The closest collision point is what was truly hit:
      CollisionResult closest = results.getClosestCollision();
      Vector3f contact = closest.getContactPoint();
      s.audio_gun.playInstance();
    } else {
      // No hits
    }
 
}

Which is called every update. However, ----- Collisions? 0----- is always what is printed out, even though, as you can see by this picture, the camera definitely has a target.

Please print your ray, to control that your camera, location and direction are at expected values.

Maybe you have declared another camera object?

Also try to remove your Skybox.
Wasn’t there the case that when the Skybox was attached to the rootNode and so the Ray always collided with the Skybox or something?

Hey, that actually worked - Removing the Skybox means that the collision is successful.

I suppose I now need to make a different node for the Skybox, or something like that?

Yes, the thing is you’d have to ensure that colissions only happen with other nodes, something like:
root Node → World Node & Skybox Node, and then collide against the World Node.

Note: Regardless of that you should keep track of your Collidables to save a huge amount of cpu (for example when you can only pick the jet and not the mountains)

Maybe @pspeed knows something (once he get’s up), why that was happening with the skybox and if it’s a bug or supposed to be like this.

I wouldn’t say it’s desired behavior. The collision results should include the skybox and the other collided nodes, then it’s up to you to select the one that interests you.

Didn’t know about this issue/behavior

1 Like

Adding a separate node for collide-able objects works like a charm. I’m glad this had an easy solution and that it wasn’t just me doing something stupid.

I added a comment to the code in the tutorial, basically saying “Don’t collide with the root node!” so that future people will not make the same mistake.

Thanks for the help everybody, I appreciate it.

I had a simmilar problem with the skybox once, it kept being the closest collision even though there were other things in front. Fixed it pretty much the same way.

As a side note, if you want something to be uncolidable in any possible scenario and it extends Geometry you can extend it and override the collideWith() method to make it always return zero.

That’s what I use for meshes that are only effects (aka particle emitters, glow quads, etc.) but need to be deep inside the scene graph to prevent glitches due to desynchronization of JBullet.
And you know, optimisation.