| 123456789101112131415161718192021222324252627282930313233343536373839 |
- <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><meta name="keywords" content="spatial, node, mesh, geometry, scenegraph"><title>Traverse the SceneGraph</title><link rel="stylesheet" href="./asciidoctor.css">
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
- <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"><link rel="stylesheet" href="/home/travis/build/jMonkeyEngine/wiki/build/asciidoc/html5/jme3/advanced/twemoji-awesome.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/jme3/advanced/traverse_scenegraph.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/jme3/advanced/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"></div><h1>Traverse the SceneGraph</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#example-use-cases">Example Use Cases</a></li><li><a href="#code-sample">Code Sample</a></li><li><a href="#see-also">See Also</a></li></ul></div></div><div id="content"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>You can run a search across the whole scene graph and search for individual Spatials (<code>Nodes</code> and `Geometry`s) by custom criteria, such as the Spatial’s name, or the Spatial’s class, or the Spatial’s user data, or Spatial’s Controls. You do this when you want modify the found nodes (move them, call a method, etc) but you don’t have a local variable for them.</p></div></div></div>
- <div class="sect1"><h2 id="example-use-cases">Example Use Cases</h2><div class="sectionbody"><div class="paragraph"><p><strong>Example 1:</strong></p></div>
- <div class="olist arabic"><ol class="arabic"><li><p>You have created a procedural scene with lots of dynamically generated elements.</p></li><li><p>You want to find individual Spatials under ever-changing conditions and modify their state.</p></li></ol></div>
- <div class="paragraph"><p><strong>Example 2:</strong></p></div>
- <div class="olist arabic"><ol class="arabic"><li><p>You created a mostly static scene in the jMonkeyEngine SDK and exported it as .j3o file.<br>
- The scene also contains interactive objects, for example a particle emitter, spatials with user data, or spatials with custom controls.</p></li><li><p>You load the .j3o scene using the assetManager.</p></li><li><p>You want to interact with one of the loaded interactive scene elements in your Java code.<br>
- For example, you want to call <code>emitAllParticles()</code> on the particle emitter. Or you want to find all NPC’s Geometries with a custom CivilianControl, and call the CivilianControl method that makes them start acting their role.</p></li></ol></div>
- <div class="paragraph"><p>In this case, you can use a SceneGraphVisitorAdapter to identify and access the Spatials in question.</p></div></div></div>
- <div class="sect1"><h2 id="code-sample">Code Sample</h2><div class="sectionbody"><div class="paragraph"><p>For each search, you create a <code>com.jme3.scene.SceneGraphVisitorAdapter</code> that defines your search criteria and what you want to do with the found Spatials. Then you call the <code>depthFirstTraversal(visitor)</code> or <code>breadthFirstTraversal(visitor)</code> method of the Spatial (e.g. the rootNode, or better, a subnode) to start the search.</p></div>
- <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java">SceneGraphVisitor visitor = <span class="keyword">new</span> SceneGraphVisitor() {
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> visit(Spatial spatial) {
- <span class="comment">// search criterion can be control class:</span>
- MyControl control = spatial.getControl(MyControl.class);
- <span class="keyword">if</span> (control != <span class="predefined-constant">null</span>) {
- <span class="comment">// you have access to any method, e.g. name.</span>
- <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">"</span><span class="content">Instance of </span><span class="delimiter">"</span></span> + control.getClass().getName()
- + <span class="string"><span class="delimiter">"</span><span class="content"> found for </span><span class="delimiter">"</span></span> + spatial.getName());
- }
- }
- };
- <span class="comment">// Now scan the tree either depth first...</span>
- rootNode.depthFirstTraversal(visitor);
- <span class="comment">// ... or scan it breadth first.</span>
- rootNode.breadthFirstTraversal(visitor);</code></pre></div></div>
- <div class="paragraph"><p>Which of the two methods is faster depends on how you designed the scengraph, and what tree element you are looking for. If you are searching for one single Geometry that is a “leaf of the tree, and then stop searching, depth-first may be faster. If you search for a high-level grouping Node, breadth-first may be faster.</p></div>
- <div class="paragraph"><p>The choice of depth- vs breadth-first also influences the order in which found elements are returned (children first or parents first). If you want to modify user data that is inherited from the parent node (e.g. transformations), the order of application is important, because the side-effects add up.</p></div>
- <div class="paragraph"><p>You can use the SceneGraphVisitorAdapter class to scan separately for Geometry and Nodes.</p></div></div></div>
- <div class="sect1"><h2 id="see-also">See Also</h2><div class="sectionbody"><div class="ulist"><ul><li><p><a href="../../jme3/the_scene_graph.html">The Scene Graph</a></p></li><li><p><a href="../../jme3/advanced/spatial.html">Spatial</a></p></li></ul></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2019-12-20 23:30:51 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
- apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
- indexName: 'jmonkeyengine',
- inputSelector: '#doc-search',
- debug: false // Set debug to true if you want to inspect the dropdown
- });</script></body></html>
|