Object select via mouse in a canvas

Hi,



I'm a noob and trying to adapt RenControlEditor to get the effect of being able to click within the GlCanvas and select an item.  At this point, I'm not looking to create any visual effect based on the selection, merely to know which item was selected kind of like the TestPick example, but only with a GlCanvas.



I've tried adding a relative mouse to the ChaseCamera such as:



 RelativeMouse aMouse = new RelativeMouse("mouse");
 amouse.registerWithInputHandler(chaser);

        chaser.addAction(new MouseInputAction() {

            public void performAction(InputActionEvent arg0) {
                if (MouseInput.get().isButtonDown(0)) {
                    System.out.println(MouseInput.get().getXAbsolute() + "," + MouseInput.get().getYAbsolute() + ":" + MouseInput.get().getXDelta() + "," + MouseInput.get().getYDelta());
                    System.out.println(amouse.getLocalTranslation().x + "," + amouse.getLocalTranslation().y);
                }
            }
        }, InputHandler.DEVICE_MOUSE, InputHandler.BUTTON_ALL, 0, false);



But the values returned from within the RelativeMouse are always 0,0.  I can't even begin trying to construct the camera-point ray in order to identify the selected nodes without the x,y coordinates of the mouse click.

Any suggestions would be much appreciated.

Thanks,

Alex

I got you covered! Just did this a couple weeks ago.



The problem I had the most trouble with was getting the correct mouse coordinates over the canvas. The only way I got this to work correctly was to implement MouseMotionListener in the main JFrame window of the application and in the mouseMoved and mouseDragged functions store the MouseEvent.getX() and getY() in a class variable. These are the mouse coordinates you need, except the y coordinate is flipped so you have to subtract it from the canvas height before you use it later on (you'll see in the code). I didn't use any specific mouse, relative or absolute.



In the input hander:


public void performAction(InputActionEvent evt) {

   if (evt.getTriggerName().compareToIgnoreCase("MOUSE0") == 0) {

      if(evt.getTriggerPressed()) {
         
         name = canvasImplmentor.pickElement(getMouseLocation()); // location comes from the MouseEvent.getX() and getY() in the main JFrame
      }
   }
}



In the canvas implementor class I have the actual picking code and it goes as follows:


public String pickElement(Vector2f screenPos) {

   // Adjust for flipped Y screen coordinate (height is the canvas height)
   screenPos.y = height - screenPos.y;

   String name = "";
   Vector3f worldCoords = cam.getWorldCoordinates(screenPos, 1.0f);

   final Ray mouseRay = new Ray(cam.getLocation(), worldCoords.subtractLocal(cam.getLocation()));
   mouseRay.getDirection().normalizeLocal();

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

   rootNode.findPick(mouseRay, results);

   if (results.getNumber() > 0)
      name = results.getPickData(0).getTargetMesh().getParentGeom().getName();

   results.clear();

   return name;
}



Are you using the AWTMouseInput and AWTKeyInputs?  They should already properly track your mouse position without having to add a mouse?

I am, but I could not figure out where to get the right mouse coordinate information from. I would not be surprised if there is an easier and more appropriate way to get the mouse coordinates. I fought with it for a few hours, no dice. Can you point to a quick sample of this or quickly outline where to get the info renanse?

Awesome!  Thank you very much. Will quickly give it a go.  I'd also be curious to hear how the standard AWTMouseInput could be used.



Thanks!

ashayk said:

I'd also be curious to hear how the standard AWTMouseInput could be used.


You can use AWT mouse input by inserting the following line in your code:

MouseInput.setProvider(MouseInput.INPUT_AWT);



This should enable AWT/Swing components (such as GLCanvas) to receive all mouse events directly. Then you can simply add MouseListeners/MouseMotionListeners to your canvas and get coordinate information through the received MouseEvent object.

I beleive this was the original approach I tried, but the coordinates were off. The canvas was moved down about 20 pixels to make room for a menubar, and the coordinates I was getting from AWT were relative to the top left of the frame, not the canvas. Maybe I was using them wrong, I don't know.

nymon said:

The canvas was moved down about 20 pixels to make room for a menubar, and the coordinates I was getting from AWT were relative to the top left of the frame, not the canvas. Maybe I was using them wrong, I don't know.


That may be because you were adding the MouseListener/MouseMotionListener to your frame instead of to the Canvas object. The coordinates in the MouseEvent will always be relative to the component that had the listener.

Alright, I'll give it another shot later and post back.

I wound up adding the MouseMotionListener to the canvas itself and checked that I'm getting the correct coordinates relative to it.  I plugged your code into the RenControlEditor and it works(!), but not consistently.  It almost seems like there's something missing from the ray points determination.  I can get things aligned just so and I can select the box every time.  Other times though, with a different camera angle, no go.



Any thoughts??  Getting close.



Thanks.