| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <title>Mouse Picking :: jMonkeyEngine Docs</title>
- <link rel="canonical" href="https://wiki.jmonkeyengine.org/docs/jme3/advanced/mouse_picking.html">
- <meta name="keywords" content="documentation, node, ray, click, collision, keyinput, input">
- <meta name="generator" content="Antora 2.3.3">
- <link rel="stylesheet" href="../../../_/css/site.css">
- <meta property="og:image" content="https://wiki.jmonkeyengine.org/_/img/iconx128.png">
- <meta property="og:description" content="Mouse Picking">
- <meta property="og:title" content="jMonkeyEngine Docs">
- <link rel="stylesheet" href="../../../_/css/site-extra.css">
- <link rel="stylesheet" href="../../../_/css/vendor/docsearch.min.css">
- <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css -->
- <link rel="icon" href="../../../_/img/favicon.ico" type="image/x-icon">
- </head>
- <body class="article">
- <header class="header">
- <nav class="navbar">
- <div class="navbar-brand">
- <a class="navbar-item" href="https://wiki.jmonkeyengine.org">
- <img alt="" src="../../../_/img/jme-logo.png" height="32" type="image/x-icon">
- </a>
- <div class="navbar-item hide-for-print">
- <input id="search-input" type="text" placeholder="Search docs">
- </div>
- <button class="navbar-burger" data-target="topbar-nav">
- <span></span>
- <span></span>
- <span></span>
- </button>
- </div>
- <div id="topbar-nav" class="navbar-menu">
- <div class="navbar-end">
- <div class="navbar-item theme-switch-wrapper">
- <label class="theme-switch" for="checkbox">
- <input type="checkbox" id="checkbox" />
- <div class="slider round"></div>
- </label>
- </div>
- <a class="navbar-item" href="https://github.com/jmonkeyengine/wiki">Github</a>
- </div>
- </div>
- </nav>
- </header>
- <div class="body">
- <div class="nav-container" data-component="docs" data-version="master">
- <aside class="nav">
- <div class="panels">
- <div class="nav-panel-menu is-active" data-panel="menu">
- <nav class="nav-menu">
- <h3 class="title"><a href="../../documentation.html">Docs</a></h3>
- <ul class="nav-list">
- <li class="nav-item" data-depth="0">
- <ul class="nav-list">
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../documentation.html">Getting Started</a>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="https://javadoc.jmonkeyengine.org/v3.3.2-stable">JavaDoc</a>
- </li>
- <li class="nav-item" data-depth="1">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../../jme3.html">jMonkeyEngine 3</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Beginner Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_simpleapplication.html">Hello SimpleApplication</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_node.html">Hello Node</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_asset.html">Hello Asset</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_main_event_loop.html">Hello Main Event Loop</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_input_system.html">Hello Input System</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_material.html">Hello Material</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_animation.html">Hello Animation</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_picking.html">Hello Picking</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_collision.html">Hello Collision</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_terrain.html">Hello Terrain</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_audio.html">Hello Audio</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_effects.html">Hello Effects</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_physics.html">Hello Physics</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Intermediate Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Concepts</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/best_practices.html">Best Practices</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/simpleapplication.html">Simple Application</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../features.html">Features</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/optimization.html">Optimization</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../faq.html">FAQ</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Math Concepts</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../math_for_dummies.html">Math For Dummies</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/math.html">Math</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../math.html">More Math</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../rotate.html">Rotate</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../math_video_tutorials.html">Math Video Tutorials</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">3D Graphics Concepts</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/multi-media_asset_pipeline.html">Multi-Media Asset Pipeline</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../scenegraph_for_dummies.html">Scenegraph for Dummies</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../beginner/hellovector.html">Hello Vector</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../terminology.html">Terminology</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/how_to_use_materials.html">How to Use Materials</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../intermediate/transparency_sorting.html">Transparency and Sorting</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../external/blender.html">Importing from Blender</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../external/3dsmax.html">Importing from 3DS Max</a>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../logo.html">Logo Usage</a>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../bsd_license.html">License</a>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../github_tips.html">Github Tips</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="0">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">SDK</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../sdk.html">jMonkeyEngine SDK</a>
- </li>
- </ul>
- </li>
- </ul>
- </nav>
- </div>
- <div class="nav-panel-explore" data-panel="explore">
- <div class="context">
- <span class="title">Docs</span>
- <span class="version">master</span>
- </div>
- <ul class="components">
- <li class="component is-current">
- <span class="title">Docs</span>
- <ul class="versions">
- <li class="version is-current is-latest">
- <a href="../../documentation.html">master</a>
- </li>
- </ul>
- </li>
- <li class="component">
- <span class="title">Wiki UI</span>
- <ul class="versions">
- <li class="version is-latest">
- <a href="../../../wiki-ui/index.html">master</a>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- </div>
- </aside>
- </div>
- <main class="article">
- <div class="toolbar" role="navigation">
- <button class="nav-toggle"></button>
- <nav class="breadcrumbs" aria-label="breadcrumbs">
- <ul>
- <li><a href="../../documentation.html">Docs</a></li>
- <li><a href="mouse_picking.html">Mouse Picking</a></li>
- </ul>
- </nav>
- <div class="edit-this-page"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/docs/modules/ROOT/pages/jme3/advanced/mouse_picking.adoc">Edit this Page</a></div>
- </div>
- <div class="content">
- <article class="doc">
- <h1 class="page">Mouse Picking</h1>
- <div id="preamble">
- <div class="sectionbody">
- <div class="paragraph">
- <p>Mouse picking means that the user clicks an object in the scene to select it, or to interact with it otherwise. Games use picking to implement aiming and shooting, casting spells, picking up objects, selecting targets, dragging and moving objects, etc. Mouse picking can be done using fixed crosshairs, or using the mouse pointer.</p>
- </div>
- <div class="paragraph">
- <p><span class="image"><img src="../../_images/jme3/advanced/mouse-picking.png" alt="mouse-picking.png" width="" height=""></span></p>
- </div>
- <div class="paragraph">
- <p>See <a href="input_handling.html" class="page">Input Handling</a> for details on how to define the necessary input triggers, input mappings, and input listeners.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="pick-a-target-using-fixed-crosshairs"><a class="anchor" href="#pick-a-target-using-fixed-crosshairs"></a>Pick a Target Using Fixed Crosshairs</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The following <code>pick target</code> input mapping implements an action that determines what a user clicked. It assumes that the mouse pointer is invisible and there are crosshairs painted in the center of the screen. It assumes that the user aims the crosshairs at an object in the scene and clicks. You use Ray Casting to identify the geometry that was picked by the user. Use this method together with a first-person flyCam.</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>Activate the first-person camera: <code>flyCam.setEnabled(true);</code></p>
- </li>
- <li>
- <p>Keep mouse pointer invisible using <code>inputManager.setCursorVisible(false)</code>.</p>
- </li>
- <li>
- <p>Map the <code>pick target</code> action to a MouseButtonTrigger.</p>
- </li>
- <li>
- <p>Implement the action in the Listener.</p>
- </li>
- </ol>
- </div>
- <div class="paragraph">
- <p>The following example rotates Spatials named “Red Box or “Blue Box when they are clicked. Modify this code to do whatever your game needs to do with the identified target (shoot it, take it, move it, etc).</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> private AnalogListener analogListener = new AnalogListener() {
- public void onAnalog(String name, float intensity, float tpf) {
- if (name.equals("pick target")) {
- // Reset results list.
- CollisionResults results = new CollisionResults();
- // Aim the ray from camera location in camera direction
- // (assuming crosshairs in center of screen).
- Ray ray = new Ray(cam.getLocation(), cam.getDirection());
- // Collect intersections between ray and all nodes in results list.
- rootNode.collideWith(ray, results);
- // Print the results so we see what is going on
- for (int i = 0; i < results.size(); i++) {
- // For each “hit”, we know distance, impact point, geometry.
- float dist = results.getCollision(i).getDistance();
- Vector3f pt = results.getCollision(i).getContactPoint();
- String target = results.getCollision(i).getGeometry().getName();
- System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");
- }
- // 5. Use the results -- we rotate the selected geometry.
- if (results.size() > 0) {
- // The closest result is the target that the player picked:
- Geometry target = results.getClosestCollision().getGeometry();
- // Here comes the action:
- if(target.getName().equals("Red Box"))
- target.rotate(0, - intensity, 0);
- else if(target.getName().equals("Blue Box"))
- target.rotate(0, intensity, 0);
- }
- } // else if ...
- }
- };</code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="pick-a-target-using-the-mouse-pointer"><a class="anchor" href="#pick-a-target-using-the-mouse-pointer"></a>Pick a Target Using the Mouse Pointer</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The following <code>pick target</code> input mapping implements an action that determines what a user clicked. It assumes that the mouse pointer is visible, and the user aims the cursor at an object in the scene. You use ray casting to determine the geometry that was picked by the user.</p>
- </div>
- <div class="paragraph">
- <p><strong>Note:</strong> Picking with a visible mouse pointer implies that your application can no longer use the default flyCam where the MouseAxisTrigger rotates the camera. You have to deactivate the flyCam mappings and provide custom mappings. Either different inputs rotate the camera, or the camera is fixed.</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>Map the <code>pick target</code> action to a MouseButtonTrigger.</p>
- </li>
- <li>
- <p>Make the mouse pointer visible using <code>inputManager.setCursorVisible(true)</code>.</p>
- </li>
- <li>
- <p>Remap the inputs for camera rotation, or deactivate camera rotation.</p>
- </li>
- <li>
- <p>Implement the action in the Listener.</p>
- </li>
- </ol>
- </div>
- <div class="paragraph">
- <p>The following example rotates Spatials named “Red Box or “Blue Box when they are clicked. Modify this code to do whatever your game needs to do with the identified target (shoot it, take it, move it, etc).</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">private AnalogListener analogListener = new AnalogListener() {
- public void onAnalog(String name, float intensity, float tpf) {
- if (name.equals("pick target")) {
- // Reset results list.
- CollisionResults results = new CollisionResults();
- // Convert screen click to 3d position
- Vector2f click2d = inputManager.getCursorPosition();
- Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
- Vector3f dir = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
- // Aim the ray from the clicked spot forwards.
- Ray ray = new Ray(click3d, dir);
- // Collect intersections between ray and all nodes in results list.
- rootNode.collideWith(ray, results);
- // (Print the results so we see what is going on:)
- for (int i = 0; i < results.size(); i++) {
- // (For each “hit”, we know distance, impact point, geometry.)
- float dist = results.getCollision(i).getDistance();
- Vector3f pt = results.getCollision(i).getContactPoint();
- String target = results.getCollision(i).getGeometry().getName();
- System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");
- }
- // Use the results -- we rotate the selected geometry.
- if (results.size() > 0) {
- // The closest result is the target that the player picked:
- Geometry target = results.getClosestCollision().getGeometry();
- // Here comes the action:
- if (target.getName().equals("Red Box")) {
- target.rotate(0, -intensity, 0);
- } else if (target.getName().equals("Blue Box")) {
- target.rotate(0, intensity, 0);
- }
- }
- } // else if ...
- }
- };</code></pre>
- </div>
- </div>
- </div>
- </div>
- </article>
- <aside class="toc sidebar" data-title="Contents" data-levels="2">
- <div class="toc-menu"></div>
- </aside>
- </div>
- </main>
- </div>
- <footer class="footer">
- <p>Copyright 2020 jMonkeyEngine Wiki Contributors. Licensed BSD-3.</p>
- </footer>
- <script src="../../../_/js/vendor/docsearch.min.js"></script>
- <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js -->
- <script>
- var search = docsearch({
- apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
- indexName: 'jmonkeyengine',
- inputSelector: '#search-input',
- autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
- algoliaOptions: { hitsPerPage: 10 }
- }).autocomplete
- search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
- function focusSearchInput () { document.querySelector('#search-input').focus() }
- if (document.querySelector('.home-link.is-current')) window.addEventListener('load', focusSearchInput)
- </script>
- <script src="../../../_/js/site.js"></script>
- <script async src="../../../_/js/vendor/highlight.js"></script>
- </body>
- </html>
|