Mouse pick; strange behaviour

Hi, i opened a new thread because my issue seems to be based on an other problem…



Code


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package foxnet.test;

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.OrientedBoundingBox;
import com.jme.input.AbsoluteMouse;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.action.InputAction;
import com.jme.input.action.InputActionEvent;
import com.jme.intersection.BoundingPickResults;
import com.jme.intersection.IntersectionRecord;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Line;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.shape.Box;

/**
 *
 * @author Kr0e
 */
public class gui3dTest extends SimpleGame {

    class PickAction extends InputAction {

            public void performAction( InputActionEvent evt ) {
                if ( evt.getTriggerPressed() ) {                   
                    Vector2f screenPos = new Vector2f(am.getHotSpotPosition().x,
                                                      am.getHotSpotPosition().y);

                    Vector3f worldCoords = display.getWorldCoordinates(screenPos, 0);
                    Vector3f worldCoords2 = display.getWorldCoordinates(screenPos, 1);

                    Ray mouseRay = new Ray(worldCoords,
                                           worldCoords2.subtractLocal(worldCoords).normalizeLocal());

                    rootNode.detachChildNamed("line");

                    Line line = new Line("line", new Vector3f[]{
                    worldCoords, worldCoords.add(worldCoords2.mult(100) )
                    } , null, null, null);

                    rootNode.attachChild(line);

                    IntersectionRecord ir = box.getModelBound().intersectsWhere(mouseRay);
                   
                    System.out.println(ir.getClosestDistance());                 
                }
            }
    }

    AbsoluteMouse am;
    Box box;
    @Override
    protected void simpleInitGame() {
        MouseInput.get().setCursorVisible(true);
        ((FirstPersonHandler)input).getMouseLookHandler().setEnabled(false);

        am = new AbsoluteMouse("The Mouse", display.getWidth(), display.getHeight());

        am.setLocalTranslation(new Vector3f(display.getWidth() / 2,
                                            display.getHeight() / 2, 0));

        am.registerWithInputHandler(input);


        box = new Box("n", new Vector3f(), 4, 4, 4);
        box.setModelBound(new OrientedBoundingBox());
       
       
        box.getLocalRotation().fromAngleAxis(43, new Vector3f(0,1,0));

        box.updateModelBound();

        input.addAction( new PickAction(), InputHandler.DEVICE_MOUSE, 0, InputHandler.AXIS_NONE, false );      

        rootNode.attachChild(am);
        rootNode.attachChild(box);
    }

    public static void main(String[] argv) {
        new gui3dTest().start();
    }
}



On the image you see the console output and the ray which goes trough a box with an OBB but the output shows that the box is not picked... Whats wrong here ?

I've had a look at this, and although I dont really understand the maths (as usual  :?) I like a challenge.



The problem seems to be that the getModelBound just returns the bounding box without any transforms applied (?).

I kinda proved that to myself by adding a second cube to your example that was exactly the same size but not rotated and without any bounding - it was just there as a kinda template to see the extents. When clicking anywhere on the second cube tho it registered as a hit.



So I looked for a way of rotating the bounds, and found that the worldbound was just that  :slight_smile:



Using

      if( box.getWorldBound().intersects(mouseRay)){
          System.out.println("HIT IT!!");
      }



instead of the IntersectionRecord code showed the message when a pick happened as ( I assume ) it should, but

                getWorldBound().intersectsWhere (mouseRay) . . .


didn't work.

It seems to me that the boundingbox needs to be rotated to match its owning object before being used with .intersects(Ray ..) - or just use the world bound which already is transformed.
The intersectsWhere(Ray ..) code is a different matter altogether, as it seems to ignore the orientation of the bounding box altogether, but is a little outside my maths ability for now (im working on it!)

Im probably talking nonsense here, but thought I'd share my findings anyway as im curious what the proper solution is now :)

Hi,

i use now a own implementation of TrianglePickResults and TrianglePickData because i didn't find a way to solve this issue…

Thats a bit more slow but the distance is correct…



Greetings