Trying to build a simple Quad Button Menu

Im trying to build a simple menu that uses the mouse as its selector.  I started with the HelloMousePick but it uses boxes. Im trying to make it work with quads



Can anyone tell me why a quad on ortho does not get added to the pick list when the mouse is over it.



Thanks,

Greg

PS Please excuse all the commented out code… was experimenting.




public class HelloWorldMousePick extends SimpleGame {
    private static final Logger logger = Logger.getLogger(HelloWorldMousePick.class
            .getName());

   // This will be my mouse
   AbsoluteMouse am;

   // This will be he box in the middle
   Box b;

    Quad q1;

   PickResults pr;

   public static void main(String[] args) {
      HelloWorldMousePick app = new HelloWorldMousePick();
      app.setConfigShowMode(ConfigShowMode.AlwaysShow);
      app.start();
   }

   protected void simpleInitGame() {
      // Create a new mouse. Restrict its movements to the display screen.
      am = new AbsoluteMouse("The Mouse", display.getWidth(), display
            .getHeight());

      // Get a picture for my mouse.
      TextureState ts = display.getRenderer().createTextureState();
        URL cursorLoc = HelloWorldMousePick.class.getClassLoader().getResource(
                "jmetest/data/cursor/cursor1.png" );
        Texture t = TextureManager.loadTexture(cursorLoc, Texture.MinificationFilter.NearestNeighborNoMipMaps,
            Texture.MagnificationFilter.Bilinear);
      ts.setTexture(t);
      am.setRenderState(ts);

      // Make the mouse's background blend with what's already there
      BlendState as = display.getRenderer().createBlendState();
      as.setBlendEnabled(true);
      as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
      as.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
      as.setTestEnabled(true);
      as.setTestFunction(BlendState.TestFunction.GreaterThan);
      am.setRenderState(as);

      // Get the mouse input device and assign it to the AbsoluteMouse
      // Move the mouse to the middle of the screen to start with
      am.setLocalTranslation(new Vector3f(display.getWidth() / 2, display
            .getHeight() / 2, 0));
      // Assign the mouse to an input handler
        am.registerWithInputHandler( input );



//        // Create the box in the middle. Give it a bounds
//      b = new Box("My Box", new Vector3f(-1, -1, -1), new Vector3f(1, 1, 1));
//      b.setModelBound(new BoundingBox() );
////        b.setCullHint(Spatial.CullHint.Never );
////        b.setRenderQueueMode(Renderer.QUEUE_ORTHO);
//      b.updateModelBound();
//        b.updateRenderState();

      ts = display.getRenderer().createTextureState();
        URL textURL = HelloWorldMousePick.class.getClassLoader().getResource(
                "com/bluntzer/data/scorpion.png" );
        t = TextureManager.loadTexture(textURL, Texture.MinificationFilter.NearestNeighborNoMipMaps,
            Texture.MagnificationFilter.Bilinear);
      ts.setTexture(t);
      b.setRenderState(ts);


        q1 = new Quad("Ortho Q2", 40, 40);
        q1.setLocalTranslation(new Vector3f(200, 200, 0));
        q1.setZOrder(1);
        q1.setDefaultColor(ColorRGBA.white.clone());
        q1.setLightCombineMode(Spatial.LightCombineMode.Off);

        q1.setModelBound(new BoundingBox());
        q1.updateModelBound();
        q1.setRenderState(ts);

        q1.setCullHint(Spatial.CullHint.Never);
        q1.setRenderQueueMode(Renderer.QUEUE_ORTHO);

        q1.updateRenderState();

        rootNode.attachChild(b);
        rootNode.attachChild(q1);
      //statNode.updateRenderState();
        // Attach Children


       // ImageButtonNode ibn = new ImageButtonNode("BUTTON");

      //rootNode.attachChild(ibn);
      rootNode.attachChild(am);
      // Remove all the lightstates so we can see the per-vertex colors
      lightState.detachAll();
      b.setLightCombineMode( LightCombineMode.Off );
      q1.setLightCombineMode( LightCombineMode.Off );
      pr = new BoundingPickResults();
      (( FirstPersonHandler ) input ).getMouseLookHandler().setEnabled( false );
   }

   protected void simpleUpdate() {
      // Get the mouse input device from the jME mouse
      // Is button 0 down? Button 0 is left click
//      if (MouseInput.get().isButtonDown(0)) {
         Vector2f screenPos = new Vector2f();
         // Get the position that the mouse is pointing to
         screenPos.set(am.getHotSpotPosition().x, am.getHotSpotPosition().y);
         // Get the world location of that X,Y value
         Vector3f worldCoords = display.getWorldCoordinates(screenPos, 0);
         Vector3f worldCoords2 = display.getWorldCoordinates(screenPos, 1);
            //logger.info( worldCoords.toString() );
            // 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?
         pr.clear();
         rootNode.findPick(mouseRay, pr);

         for (int i = 0; i < pr.getNumber(); i++) {
            pr.getPickData(i).getTargetMesh().setSolidColor(ColorRGBA.green);
         }
//      }
   }
}


I just happen to be looking at this same subject.



Looking in the code for findPick, rootNode might be checking for hits by checking bounds in world coordinates. Your mouseRay is in world coordinates too. However, your quad button is rendered in ortho, using screen coordinates, so the mouseRay won't intersect them. I haven't tried it yet myself, but findPick might work if you leave the mouseRay as screen coordnates.

hey guys.



one listener for multiple button Quads in ortho mode:



    MouseInput.get().addListener(new MouseInputListener() {
      public void onButton(int button, boolean pressed, int x, int y) {
        if (button == 0) { // left mouse button
          if (getPickHits(quad1, x, y) && pressed) { // at button down
            // do stuff
          } else if (getPickHits(quad2, x, y) && !pressed) { // at release
            // do stuff
          } else if (getPickHits(quad3, x, y) && !pressed) { // at release
            // do stuff
          } // else if
        } // if
      } // onButton
    }

  public boolean getPickHits(Quad q, int x, int y) {
    int xFrom, xTo, yFrom, yTo;
    xFrom = (int)(q.getWorldTranslation().x - q.getWidth() / 2);
    xTo = (int)(q.getWorldTranslation().x + q.getWidth() / 2);
    yFrom = (int)(q.getWorldTranslation().y - q.getHeight() / 2);
    yTo = (int)(q.getWorldTranslation().y + q.getHeight() / 2);
    return isBetween(x, xFrom, xTo) && isBetween(y, yFrom, yTo);
  } // getPickHits

  private boolean isBetween(float toCheck, float lower, float upper) {
    return toCheck >= lower && toCheck <= upper;
  } // isBetween



Optimizable? Sure, but it works  ;)