Lesson 5: Mouse Selection

Return to the home page

The goal: (the sphere's radius was changed to 4 for ease of view on my resolution). Keep in mind that the colors are randomlly generated, so it will not look exactly the same on your computer.

Click for full size. Hover over for more details.

Click here to download the code. (If the page opens in the broswer, you can right click on link and click "Save Link As", or right click on the page and click "Save As")

            
        // most applications will want to extend the SimpleGame class
        import com.jme.app.SimpleGame;
        
        // a vector containing three float numbers;
        //   used to store positions and translations
        import com.jme.math.Vector3f;
        
        // geometric shapes used in program
        import com.jme.scene.shape.Box;
        import com.jme.scene.shape.Sphere;
        
        // use predefined colors and create custom colors
        import com.jme.renderer.ColorRGBA;
        
        // work with basic materials
        import com.jme.scene.state.MaterialState;
        
        // process user input
        import com.jme.input.InputHandler;
        import com.jme.input.KeyInput;
        import com.jme.input.KeyBindingManager;
        import com.jme.input.FirstPersonHandler;
        
        // display text
        import com.jme.scene.Text;
        import com.jmex.font2d.Text2D;
        import com.jmex.font2d.Font2D;
        
        // an internal vertex of the scenegraph tree;
        //  use to group together objects,
        //  apply render settings, which affects all child vertices
        import com.jme.scene.Node;
        import com.jme.scene.Spatial;
        import com.jme.scene.Geometry;
        
        // methods to change render settings
        import com.jme.renderer.Renderer;
        
        // methods for mouse input & selection
        import com.jme.input.AbsoluteMouse;
        import com.jme.input.MouseInput;
        import com.jme.intersection.PickResults;
        import com.jme.intersection.BoundingPickResults;
        import com.jme.math.Ray;
        import com.jme.math.Vector2f;
        import com.jme.bounding.BoundingSphere;
        
        /**
         *   Click the sphere for psychedelic results.
         */
        public class MouseSelectDemo extends SimpleGame
        {
           // a geometric shape that will be rendered
           Sphere mySphere;
        
           AbsoluteMouse am;
           PickResults pr;
        
           public static void main(String[] args)
           {
               // create an instance of this program
               MouseSelectDemo app = new MouseSelectDemo();
        
               // before the main program starts, display the graphics configuration window
               //   where the user can choose among screen resolution, color depth, and full screen options
               app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        
               // The start() method runs simpleInitGame(),
               //   then starts the game loop: simpleUpdate(), then simpleRender()
               // To terminate game loop, call finish()
               app.start();
           }
        
           protected void simpleInitGame()
           {
               // make the standard cursor visible.
               org.lwjgl.input.Mouse.setGrabbed(false);
               // SimpleGame class defaults mouse behavior to rotate view; here we disable this.
               ((FirstPersonHandler)input).getMouseLookHandler().setEnabled(false);
        
               // Create a new mouse.
               am = new AbsoluteMouse("mouse", display.getWidth(), display.getHeight());
               // assign the mouse to an input handler, so we can process input it creates
               am.registerWithInputHandler(input);
               rootNode.attachChild(am);
               pr = new BoundingPickResults();
        
               // create a material to apply to geometric objects, use objects' default color,
               //  apply to front and back, and assign rendering to root node
               MaterialState customMaterial = display.getRenderer().createMaterialState();
               customMaterial.setColorMaterial(MaterialState.ColorMaterial.AmbientAndDiffuse);
               customMaterial.setMaterialFace(MaterialState.MaterialFace.FrontAndBack);
               rootNode.setRenderState(customMaterial);
        
               // Parameters for the Sphere constructor:
               //   Sphere( String name, Vector3f center, int zSamples, int radialSamples, float radius )
               mySphere = new Sphere("s", new Vector3f(0,0,0), 30, 30, 4 );
               mySphere.setDefaultColor( ColorRGBA.gray );
        
               // in order for this object to be selected by mouse,
               //  we must enable collision detection and assign a bounding surface.
               mySphere.setModelBound(new BoundingSphere());
               mySphere.updateModelBound();
        
               rootNode.attachChild( mySphere );
           }
        
           protected void simpleUpdate()
           {
               // 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);
                   // 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().setRandomColors();
                   }
               }
           }
        
           protected void simpleRender()
           {
               // nothing to add
           }
        }

     

Return to the home page