Mouse Picking

Hi again… I would like to ask about the mouse picking chapter in the tutorial posted in the link below

http://www.jmonkeyengine.com/wiki/doku.php/scene_editor_course_and_programming_guide



I was wondering if someone could enlighten me on this matter… I have no backgroud on raytracing whatsoever… please help

I'm not quite sure what else you'd like to know about it…



Here's an example of one I just pulled out of a project I'm working on (I've added some comments, hope it helps!):


public class MousePicking {
   private PickResults results;
   private Spatial pickedSpatial;
   private Node pickedDesign;
   private Geometry selectedMesh;
   private Node lowestNode;
   private float distanceToObject;

   /**
    *
    */
   public MousePicking(){
      // position of mouse on screen
      Vector2f screenPosition = new Vector2f(MouseInput.get().getXAbsolute(), MouseInput.get().getYAbsolute());
      
      // mouse coordinates -> world coordinates
      Vector3f worldCoords = DisplaySystem.getDisplaySystem().getWorldCoordinates(screenPosition, 0);
      Vector3f worldCoords2 = DisplaySystem.getDisplaySystem().getWorldCoordinates(screenPosition, 1);
      
      // create a ray from the origin (where your mouse clicked right in front of your camera) to where your mouse clicked in the distance
      Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(worldCoords).normalizeLocal());
      
      // set up triangle picking and set the results to check the distance.
      results = new TrianglePickResults();
      results.setCheckDistance(true);
      results.clear();
      System.out.println("checking picks");
      
      // this looks complicated, but all it is essentially: "rootNode.findPick(mouseRay, results);
      ((SceneGameState)GameStateManager.getInstance().getChild("sceneGameState")).getDesignNode().findPick(mouseRay, results);
      
      // assigns the closest mesh to the "selectedMesh" variable
      selectedMesh = results.getPickData(0).getTargetMesh();
      System.out.println("picked " + results.getNumber() + " geometries");
      
      // lists everything that was picked
      for(int i=0; i<results.getNumber(); i++){
         System.out.println(i + ": " + results.getPickData(i).getTargetMesh().getName());
      }
   }
}

thanks for the quickie reply sbook… that enlightened me a a lot on what ray tracing’s logic is… anyway… I’ve got this problem… I’ve tried to use your code but I get exceptions since the ray I cast can’t pick anything… then I tried creating a visible line on where the ray traces… I was wondering, as shown on the picture below, even if the line or the ray visibly collided with the object… why does the results variable still remain null…?



Is there a bounding box around your object?



mySpatial.setModelBound(new BoundingBox());
mySpatial.updateModelBound();

thank you very much sbook… that solved my problem… it seems I overlooked the updateModelBound function although I've put boundingboxes to all my objects… now it works like a charm…thnx!

Hi sbook,



i'm trying to use your code aswell (thanks :D),



But Netbeans is complaining about "SceneGamestate", I guess there's just something stupid i forgot to do, but at this point, i've no idea what that might be? (well at least I'm far enough to say, that it cannot be solved by pressing rightclick,refactoring,solve imports :D:D:D)





thanks, Frantic

Sorry!!  SceneGameState is a GameState in our own game :slight_smile:



rootNode.findPick() wll accomplish the same thing.

Thanks,



my new problem is, i'm able to select a TriMesh( triangle ) using Mouseclick, but its not exact, it's enough to click in the bounding around the triangle, but thats not exact, is there a imple way to avoid this? (i just need that for triangles)

      
public void MousePickUpdate(){
            if (MouseInput.get().isButtonDown(0)) {
                // Get the position that the mouse is pointing to
                Vector2f screenPos = new Vector2f();
                screenPos.set(am.getHotSpotPosition().x, am.getHotSpotPosition().y);
                // Get the world location of that X,Y value
                Vector3f worldCoords = aDisplaySystem.getWorldCoordinates(screenPos, 0);
                Vector3f worldCoords2 = aDisplaySystem.getWorldCoordinates(screenPos, 1);
                // Create a ray starting from the camera, and going in the direction
                // of the mouse's location
                Ray mouseRay = new Ray(worldCoords, worldCoords2.subtractLocal(
                                worldCoords).normalizeLocal());
                // Does the mouse's ray intersect the box's world bounds?

                results = new TrianglePickResults();
      results.setCheckDistance(true);
      results.clear();

                rootNode.calculatePick(mouseRay, results);

                for (int i = 0; i < results.getNumber(); i++) {
                        results.getPickData(i).getTargetMesh().setRandomColors();
                }
            }
        }