- fix some deprecations and warnings

- fix jmp internal manual

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7735 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 14 years ago
parent a43e52a384
commit 030edabc80
  1. 130
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/3d_models.html
  2. 497
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/animation.html
  3. 256
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/application_states.html
  4. 161
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html
  5. 285
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/audio.html
  6. 366
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html
  7. 302
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/camera.html
  8. 585
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/cinematics.html
  9. 321
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/collision_and_intersection.html
  10. 286
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/combo_moves.html
  11. 234
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html
  12. 319
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html
  13. 151
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/debugging.html
  14. 356
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/effects_overview.html
  15. 268
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html
  16. 244
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/hud.html
  17. 358
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/input_handling.html
  18. 495
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html
  19. 376
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/jme3_shaders.html
  20. 219
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/light_and_shadow.html
  21. 236
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/localization.html
  22. 158
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/logging.html
  23. 145
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html
  24. 447
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html
  25. 290
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/mesh.html
  26. 46
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/motion_path.html
  27. 160
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/multiple_camera_views.html
  28. 201
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/multithreading.html
  29. 425
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/networking.html
  30. 171
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html
  31. 258
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html
  32. 111
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html
  33. 129
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html
  34. 254
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html
  35. 385
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html
  36. 841
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/physics.html
  37. 221
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html
  38. 417
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/post-processor_water.html
  39. 219
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/ragdoll.html
  40. 91
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/shape.html
  41. 140
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/sky.html
  42. 159
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/spatial.html
  43. 182
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/swing_canvas.html
  44. 189
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/terrain.html
  45. 126
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/update_loop.html
  46. 357
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/vehicles.html
  47. 179
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/walking_character.html
  48. 265
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/water.html
  49. 321
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html
  50. 513
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html
  51. 292
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html
  52. 422
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html
  53. 432
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html
  54. 363
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html
  55. 179
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html
  56. 506
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_material.html
  57. 447
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_node.html
  58. 440
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html
  59. 409
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html
  60. 303
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html
  61. 560
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html
  62. 262
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/build_jme3_sources_with_netbeans.html
  63. 47
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/bullet_multithreading.html
  64. 609
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/api_feature_mapping.html
  65. 175
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html
  66. 753
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/best_practices.html
  67. 114
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/file_types.html
  68. 99
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/headlessserver.html
  69. 92
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html
  70. 94
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/optimization.html
  71. 465
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html
  72. 148
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/terrain_collision.html
  73. 1301
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/math.html
  74. 875
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/terminology.html
  75. 191
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/the_scene_graph.html
  76. 98
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/webstart.html
  77. 456
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/application_deployment.html
  78. 247
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/asset_packs.html
  79. 362
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/code_editor.html
  80. 346
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html
  81. 125
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/default_build_script.html
  82. 156
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development.html
  83. 123
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/extension_library.html
  84. 28
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/general.html
  85. 61
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/model_loader.html
  86. 71
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/projects_assets.html
  87. 139
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/scene.html
  88. 127
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/sceneexplorer.html
  89. 201
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/setup.html
  90. 148
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/material_editing.html
  91. 239
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html
  92. 408
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/project_creation.html
  93. 270
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/scene_composer.html
  94. 89
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/scene_explorer.html
  95. 228
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/terrain_editor.html
  96. 23
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/troubleshooting.html
  97. 71
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/use_own_jme.html
  98. 59
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/vehicle_creator.html
  99. 312
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/version_control.html
  100. 47
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/spidermonkey/tutorial/compression.html
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,83 +1,49 @@
<h1><a
<h1><a>Models and Scenes</a></h1> name="models_and_scenes">Models and Scenes</a></h1><div
<div> class="level1"><p> Like <a
href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s, 3D models are also made up of <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/mesh.html">Mesh</a>es, but models are more complex than Shapes. While Shapes are built into jME3, you typically create models in external 3D Mesh Editors.</p></div><h2><a
name="using_models_and_scenes_with_jme3">Using Models and Scenes with jME3</a></h2><div
Like <a href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s, 3D models are also made up of <a href="/com/jme3/gde/core/docs/jme3/advanced/mesh.html">Mesh</a>es, but models are more complex than Shapes. While Shapes are built into jME3, you typically create models in external 3D Mesh Editors. class="level2"><p> To use 3D models in a jME3 application:</p><ol><li
</p> class="level1"><div
class="li"> Export the 3D model in Ogre <acronym
</div> title="Extensible Markup Language">XML</acronym> or Wavefront OBJ format. Export Scenes as Ogre DotScene format.</div></li><li
class="level1"><div
<h2><a>Using Models and Scenes with jME3</a></h2> class="li"> Save the files into a subdirectory of your jME3 project&#039;s <code>assets</code> directory.</div></li><li
<div> class="level1"><div
class="li"> In your code, you use the <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a> to load models as <a
href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a>s into a jME application.<pre>Spatial model = assetManager.loadModel&#40;
To use 3D models in a jME3 application: &quot;Models/MonkeyHead/MonkeyHead.mesh.xml&quot; &#41;;</pre></div></li><li
</p> class="level1"><div
<ol> class="li"> (For the release build:) Use the jMonkeyPlatform to convert models to .j3o format. You don&#039;t need this step as long you still develop and test the aplication within the jMonkeyPlatform.</div></li></ol></div><h2><a
<li><div> Export the 3D model in Ogre <acronym title="Extensible Markup Language">XML</acronym> or Wavefront OBJ format. Export Scenes as Ogre DotScene format.</div> name="creating_models_and_scenes">Creating Models and Scenes</a></h2><div
</li> class="level2"><p> To create 3D models and scenes, you need a 3D Mesh Editor such as <a
<li><div> Save the files into a subdirectory of your jME3 project&#039;s <code>assets</code> directory.</div> href="http://www.blender.org/">Blender</a>, with an OgreXML Exporter plugin.</p><p> <strong>Tip:</strong> Consider creating <a
</li> href="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics">UV textures</a> for more complex models, it looks more professional.</p><p> 3D mesh editors are third-party products, so please consult their documentation for instructions how to use them. Here is an example workflow for Blender users:</p><p> To export your models as Ogre <acronym
<li><div> In your code, you use the <a href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a> to load models as <a href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a>s into a jME application. <pre>Spatial model = assetManager.loadModel&#40; title="Extensible Markup Language">XML</acronym> meshes with materials:</p><ol><li
&quot;Models/MonkeyHead/MonkeyHead.mesh.xml&quot; &#41;;</pre></div> class="level1"><div
</li> class="li"> Open the menu File &gt; Export &gt; OgreXML Exporter to open the exporter dialog.</div></li><li
<li><div> (For the release build:) Use the jMonkeyPlatform to convert models to .j3o format. You don&#039;t need this step as long you still develop and test the aplication within the jMonkeyPlatform.</div> class="level1"><div
</li> class="li"> In the Export Materials field: Give the material the same name as the model. For example, the model <code>something.mesh.xml</code> goes with <code>something.material</code>, plus (optionally) <code>something.skeleton.xml</code>, and some <acronym
</ol> title="Joint Photographics Experts Group">JPG</acronym> files.</div></li><li
class="level1"><div
</div> class="li"> In the Export Meshes field: Select a target subdirectory of your <code>assets/Models/</code> directory. E.g. <code>assets/Models/something/</code>.</div></li><li
class="level1"><div
<h2><a>Creating Models and Scenes</a></h2> class="li"> Activate the following exporter settings:</div><ul><li
<div> class="level2"><div
class="li"> Copy Textures: YES</div></li><li
<p> class="level2"><div
class="li"> Rendering Materials: YES</div></li><li
To create 3D models and scenes, you need a 3D Mesh Editor such as <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.blender.org/"><param name="text" value="<html><u>Blender</u></html>"><param name="textColor" value="blue"></object>, with an OgreXML Exporter plugin. class="level2"><div
</p> class="li"> Flip Axis: YES</div></li><li
class="level2"><div
<p> class="li"> Require Materials: YES</div></li><li
<strong>Tip:</strong> Consider creating <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics"><param name="text" value="<html><u>UV textures</u></html>"><param name="textColor" value="blue"></object> for more complex models, it looks more professional. class="level2"><div
</p> class="li"> Skeleton name follows mesh: YES</div></li></ul></li><li
class="level1"><div
<p> class="li"> Click export.</div></li></ol><p> You can now use the <a
3D mesh editors are third-party products, so please consult their documentation for instructions how to use them. Here is an example workflow for Blender users: href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to <a
</p> href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">load and view models</a>. You can <a
href="/com/jme3/gde/core/docs/sdk/scene_composer.html">create scenes</a> from them and write cde that loads them into your application.</p></div>
<p>
To export your models as Ogre <acronym title="Extensible Markup Language">XML</acronym> meshes with materials:
</p>
<ol>
<li><div> Open the menu File &gt; Export &gt; OgreXML Exporter to open the exporter dialog.</div>
</li>
<li><div> In the Export Materials field: Give the material the same name as the model. For example, the model <code>something.mesh.xml</code> goes with <code>something.material</code>, plus (optionally) <code>something.skeleton.xml</code>, and some <acronym title="Joint Photographics Experts Group">JPG</acronym> files.</div>
</li>
<li><div> In the Export Meshes field: Select a target subdirectory of your <code>assets/Models/</code> directory. E.g. <code>assets/Models/something/</code>.</div>
</li>
<li><div> Activate the following exporter settings: </div>
<ul>
<li><div> Copy Textures: YES</div>
</li>
<li><div> Rendering Materials: YES</div>
</li>
<li><div> Flip Axis: YES</div>
</li>
<li><div> Require Materials: YES</div>
</li>
<li><div> Skeleton name follows mesh: YES</div>
</li>
</ul>
</li>
<li><div> Click export.</div>
</li>
</ol>
<p>
You can now use the <a href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to <a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">load and view models</a>. You can <a href="/com/jme3/gde/core/docs/sdk/scene_composer.html">create scenes</a> from them and write cde that loads them into your application.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:3d_models?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:3d_models?do=export_xhtmlbody">view online version</a></em></p>

@ -1,267 +1,157 @@
<h1><a
<h1><a>Animation in jME3</a></h1> name="animation_in_jme3">Animation in jME3</a></h1><div
<div> class="level1"><p> In 3D games, you do not only load static 3D models, you also want to be able to trigger animations in the model from the Java code. Animated models must be created in an external mesh editor (for example, Blender).</p><p> What is required for the model?</p><ol><li
class="level1"><div
<p> class="li"> For each model, you have to define a skeleton (bones rigging).</div></li><li
class="level1"><div
In 3D games, you do not only load static 3D models, you also want to be able to trigger animations in the model from the Java code. Animated models must be created in an external mesh editor (for example, Blender). class="li"> For each motion, you have to specify how it distorts the model (skinning).</div></li><li
</p> class="level1"><div
class="li"> For each animation, you have to specify a series of snapshots of how the bones are positioned (keyframes).</div></li><li
<p> class="level1"><div
What is required for the model? class="li"> One model can contain several animations. You give every animation a name when you save it in the mesh editor.</div></li></ol><p> More information: <a
</p> href="/com/jme3/gde/core/docs/jme3/terminology#animation.html">Animation</a></p><p> What is required in your java class?</p><ul><li
<ol> class="level1"><div
<li><div> For each model, you have to define a skeleton (bones rigging). </div> class="li"> One animation controller per animated Model</div></li><li
</li> class="level1"><div
<li><div> For each motion, you have to specify how it distorts the model (skinning). </div> class="li"> As many channels per controller as you need to play several animations in parallel. In simple cases one channel is enough, sometimes you need two or more per model.</div></li></ul></div><h2><a
</li> name="controlling_animations">Controlling Animations</a></h2><div
<li><div> For each animation, you have to specify a series of snapshots of how the bones are positioned (keyframes).</div> class="level2"></div><h3><a
</li> name="the_controller">The Controller</a></h3><div
<li><div> One model can contain several animations. You give every animation a name when you save it in the mesh editor.</div> class="level3"><p> Create one <code>com.jme3.animation.AnimControl</code> object in your JME3 application for each animated model that you want to control. You have to register each animated model to one of these Animation Controllers. The control object gives you access to the available animation sequences in the model.</p><pre> AnimControl playerControl; // you need one controller per model
</li>
</ol>
<p>
More information: <a href="/com/jme3/gde/core/docs/jme3/terminology#animation.html">Animation</a>
</p>
<p>
What is required in your java class?
</p>
<ul>
<li><div> One animation controller per animated Model</div>
</li>
<li><div> As many channels per controller as you need to play several animations in parallel. In simple cases one channel is enough, sometimes you need two or more per model.</div>
</li>
</ul>
</div>
<h2><a>Controlling Animations</a></h2>
<div>
</div>
<h3><a>The Controller</a></h3>
<div>
<p>
Create one <code>com.jme3.animation.AnimControl</code> object in your JME3 application for each animated model that you want to control. You have to register each animated model to one of these Animation Controllers. The control object gives you access to the available animation sequences in the model.
</p>
<pre> AnimControl playerControl; // you need one controller per model
Node player = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;; // load a model Node player = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;; // load a model
playerControl = player.getControl&#40;AnimControl.class&#41;; // get control over this model playerControl = player.getControl&#40;AnimControl.class&#41;; // get control over this model
playerControl.addListener&#40;this&#41;; // add listener</pre> playerControl.addListener&#40;this&#41;; // add listener</pre></div><h3><a
</div> name="channels">Channels</a></h3><div
class="level3"><p> A controller has several animation channels (<code>com.jme3.animation.AnimChannel</code>). Each channel can play one animation sequence at a time.</p><p> There often are situations where you want to run several animation sequences at the same time, e.g. &quot;shooting while walking&quot; or &quot;boxing while jumping&quot;. In this case, you create several channels, assign an animation to each, and play them in parallel.</p><pre> AnimChannel channel_walk = playerControl.createChannel&#40;&#41;;
<h3><a>Channels</a></h3>
<div>
<p>
A controller has several animation channels (<code>com.jme3.animation.AnimChannel</code>). Each channel can play one animation sequence at a time.
</p>
<p>
There often are situations where you want to run several animation sequences at the same time, e.g. “shooting while walking” or “boxing while jumping”. In this case, you create several channels, assign an animation to each, and play them in parallel.
</p>
<pre> AnimChannel channel_walk = playerControl.createChannel&#40;&#41;;
AnimChannel channel_jump = playerControl.createChannel&#40;&#41;; AnimChannel channel_jump = playerControl.createChannel&#40;&#41;;
...</pre> ...</pre><p> To reset a controller, call <code>control.clearChannels();</code></p></div><h2><a
<p> name="animation_control_properties">Animation Control Properties</a></h2><div
To reset a controller, call <code>control.clearChannels();</code> class="level2"><p> The following information is available for an AnimControl.</p><div
</p> class="table sectionedit1"><table
class="inline"><tr
</div> class="row0"><th
class="col0">AnimControl Property</th><th
<h2><a>Animation Control Properties</a></h2> class="col1">Usage</th></tr><tr
<div> class="row1"><td
class="col0">createChannel()</td><td
<p> class="col1">Returns a new channel, controlling all bones by default.</td></tr><tr
class="row2"><td
The following information is available for an AnimControl. class="col0">getNumChannels()</td><td
class="col1">The number of channels registered to this Control.</td></tr><tr
</p> class="row3"><td
<table> class="col0">getChannel(0)</td><td
<tr> class="col1">Gets individual channels by index number. At most <code>getNumChannels()</code>.</td></tr><tr
<th>AnimControl Property</th><th>Usage</th> class="row4"><td
</tr> class="col0">clearChannels()</td><td
<tr> class="col1">Clear all channels in this control.</td></tr><tr
<td>createChannel()</td><td>Returns a new channel, controlling all bones by default.</td> class="row5"><td
</tr> class="col0">addListener(animEventListener) <br/> removeListener(animEventListener) <br/> clearListeners()</td><td
<tr> class="col1">Adds or removes listeners to receive animation related events.</td></tr></table></div><div
<td>getNumChannels()</td><td>The number of channels registered to this Control.</td> class="table sectionedit2"><table
</tr> class="inline"><tr
<tr> class="row0"><th
<td>getChannel(0)</td><td>Gets individual channels by index number. At most <code>getNumChannels()</code>.</td> class="col0">AnimControl Property</th><th
</tr> class="col1">Usage</th></tr><tr
<tr> class="row1"><td
<td>clearChannels()</td><td>Clear all channels in this control.</td> class="col0">setAnimations(aniHashMap)</td><td
</tr> class="col1">Sets the animations that this AnimControl is capable of playing. The animations must be compatible with the skeleton given in the constructor.</td></tr><tr
<tr> class="row2"><td
<td>addListener(animEventListener) <br/> class="col0">addAnim(boneAnim) <br/> removeAnim(boneAnim)</td><td
removeListener(animEventListener) <br/> class="col1">Adds or removes an animation from this Control.</td></tr><tr
clearListeners() </td><td>Adds or removes listeners to receive animation related events.</td> class="row3"><td
</tr> class="col0">getAnimationNames()</td><td
</table> class="col1">A String Collection of names of all animations that this Control can play for this model.</td></tr><tr
<table> class="row4"><td
<tr> class="col0">getAnim(&quot;anim&quot;)</td><td
<th>AnimControl Property</th><th>Usage</th> class="col1">Retrieve an animation from the list of animations.</td></tr><tr
</tr> class="row5"><td
<tr> class="col0">getAnimationLength(&quot;anim&quot;)</td><td
<td>setAnimations(aniHashMap)</td><td>Sets the animations that this AnimControl is capable of playing. The animations must be compatible with the skeleton given in the constructor.</td> class="col1">Returns the length of the given named animation in seconds</td></tr></table></div><div
</tr> class="table sectionedit3"><table
<tr> class="inline"><tr
<td>addAnim(boneAnim) <br/> class="row0"><th
removeAnim(boneAnim)</td><td>Adds or removes an animation from this Control.</td> class="col0">AnimControl Property</th><th
</tr> class="col1">Usage</th></tr><tr
<tr> class="row1"><td
<td>getAnimationNames()</td><td>A String Collection of names of all animations that this Control can play for this model.</td> class="col0">getSkeleton()</td><td
</tr> class="col1">The Skeleton object controlled by this Control.</td></tr><tr
<tr> class="row2"><td
<td>getAnim(“anim”)</td><td>Retrieve an animation from the list of animations.</td> class="col0">getTargets()</td><td
</tr> class="col1">The Skin objects controlled by this Control, as Mesh array.</td></tr><tr
<tr> class="row3"><td
<td>getAnimationLength(“anim”)</td><td>Returns the length of the given named animation in seconds</td> class="col0">getAttachmentsNode(&quot;bone&quot;)</td><td
</tr> class="col1">Returns the attachment node of a bone. Attach models and effects to this node to make them follow this bone&#039;s motions.</td></tr></table></div></div><h2><a
</table> name="animation_channel_properties">Animation Channel Properties</a></h2><div
<table> class="level2"><p> The following properties are set per AnimChannel.</p><div
<tr> class="table sectionedit4"><table
<th>AnimControl Property</th><th>Usage</th> class="inline"><tr
</tr> class="row0"><th
<tr> class="col0">AnimChannel Property</th><th
<td>getSkeleton()</td><td>The Skeleton object controlled by this Control.</td> class="col1">Usage</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">setLoopMode(LoopMode.Loop);</td><td
<td>getTargets()</td><td>The Skin objects controlled by this Control, as Mesh array.</td> class="col1"> From now on, the animation on this channel will repeat from the beginning when it ends.</td></tr><tr
</tr> class="row2"><td
<tr> class="col0">setLoopMode(LoopMode.DontLoop);</td><td
<td>getAttachmentsNode(“bone”)</td><td>Returns the attachment node of a bone. Attach models and effects to this node to make them follow this bone&#039;s motions.</td> class="col1"> From now on, the animation on this channel will play once, and the freeze at the last keyframe.</td></tr><tr
</tr> class="row3"><td
</table> class="col0">setLoopMode(LoopMode.Cycle);</td><td
class="col1"> From now on, the animation on this channel will play forward, then backward, then again forward, and so on.</td></tr><tr
</div> class="row4"><td
class="col0">setSpeed(1f);</td><td
<h2><a>Animation Channel Properties</a></h2> class="col1"> From now on, play this animation slower (&lt;1f) or faster (&gt;1f), or with default speed (1f).</td></tr><tr
<div> class="row5"><td
class="col0">setTime(1.3f);</td><td
<p> class="col1"> Fast-forward or rewind to a certain moment in time of this animation.</td></tr></table></div><p> The following information is available for a channel.</p><div
class="table sectionedit5"><table
The following properties are set per AnimChannel. class="inline"><tr
class="row0"><th
</p> class="col0">AnimChannel Property</th><th
<table> class="col1">Usage</th></tr><tr
<tr> class="row1"><td
<th>AnimChannel Property</th><th>Usage</th> class="col0">getAnimationName()</td><td
</tr> class="col1">The name of the animation playing on this channel. Returns <code>null</code> when no animation is playing.</td></tr><tr
<tr> class="row2"><td
<td>setLoopMode(LoopMode.Loop); </td><td> From now on, the animation on this channel will repeat from the beginning when it ends. </td> class="col0">getLoopMode()</td><td
</tr> class="col1">The current loop mode on this channel. The returned com.jme3.animation enum can be LoopMode.Loop, LoopMode.DontLoop, or LoopMode.Cycle.</td></tr><tr
<tr> class="row3"><td
<td>setLoopMode(LoopMode.DontLoop); </td><td> From now on, the animation on this channel will play once, and the freeze at the last keyframe. </td> class="col0">getAnimMaxTime()</td><td
</tr> class="col1">The total length of the animation on this channel. Or <code>0f</code> if nothing is playing.</td></tr><tr
<tr> class="row4"><td
<td>setLoopMode(LoopMode.Cycle); </td><td> From now on, the animation on this channel will play forward, then backward, then again forward, and so on. </td> class="col0">getTime()</td><td
</tr> class="col1">How long the animation on this channel has been playing. It returns <code>0f</code> if the channel has not started playing yet, or a value up to getAnimMaxTime().</td></tr><tr
<tr> class="row5"><td
<td>setSpeed(1f); </td><td> From now on, play this animation slower (&lt;1f) or faster (&gt;1f), or with default speed (1f). </td> class="col0">getControl()</td><td
</tr> class="col1">The AnimControl that belongs to this AnimChannel.</td></tr></table></div><p> Use the following methods to add or remove individual bones to an AnimChannel. This is useful when you play two animations in parallel on two channels, and each controls a subset of the bones (e.g. one the arms, and the other the legs).</p><div
<tr> class="table sectionedit6"><table
<td>setTime(1.3f); </td><td> Fast-forward or rewind to a certain moment in time of this animation. </td> class="inline"><tr
</tr> class="row0"><th
</table> class="col0">AnimChannel Methods</th><th
class="col1">Usage</th></tr><tr
<p> class="row1"><td
class="col0">addAllBones()</td><td
The following information is available for a channel. class="col1">Add all the bones of the model&#039;s skeleton to be influenced by this animation channel. (default)</td></tr><tr
class="row2"><td
</p> class="col0">addBone(&quot;bone1&quot;) <br/> addBone(bone1)</td><td
<table> class="col1">Add a single bone to be influenced by this animation channel.</td></tr><tr
<tr> class="row3"><td
<th>AnimChannel Property</th><th>Usage</th> class="col0">addToRootBone(&quot;bone1&quot;) <br/> addToRootBone(bone1)</td><td
</tr> class="col1">Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given bone, to the root bone.</td></tr><tr
<tr> class="row4"><td
<td>getAnimationName()</td><td>The name of the animation playing on this channel. Returns <code>null</code> when no animation is playing.</td> class="col0">addFromRootBone(&quot;bone1&quot;) <br/> addFromRootBone(bone1)</td><td
</tr> class="col1">Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given root bone, going towards the children bones.</td></tr></table></div></div><h2><a
<tr> name="playing_animations">Playing Animations</a></h2><div
<td>getLoopMode()</td><td>The current loop mode on this channel. The returned com.jme3.animation enum can be LoopMode.Loop, LoopMode.DontLoop, or LoopMode.Cycle.</td> class="level2"><p> Animations are played by channel. <strong>Note:</strong> Whether the animation channel plays continuously or only once, depends on the Loop properties you have set.</p><div
</tr> class="table sectionedit7"><table
<tr> class="inline"><tr
<td>getAnimMaxTime()</td><td>The total length of the animation on this channel. Or <code>0f</code> if nothing is playing.</td> class="row0"><th
</tr> class="col0">Channel Method</th><th
<tr> class="col1">Usage</th></tr><tr
<td>getTime()</td><td>How long the animation on this channel has been playing. It returns <code>0f</code> if the channel has not started playing yet, or a value up to getAnimMaxTime().</td> class="row1"><td
</tr> class="col0">channel_walk.setAnim(&quot;Walk&quot;,0.50f);</td><td
<tr> class="col1"> Start the animation named &quot;Walk&quot; on channel channel_walk. <br/> The float value specifies the time how long the animation should overlap with the previous one on this channel. If set to 0f, then no blending will occur and the new animation will be applied instantly.</td></tr></table></div><p> <strong>Tip:</strong> Use the AnimEventLister below to react at the end or start of an animation cycle.</p></div><h3><a
<td>getControl()</td><td>The AnimControl that belongs to this AnimChannel.</td> name="usage_example">Usage Example</a></h3><div
</tr> class="level3"><p> In this short example, we define the space key to trigger playing the &quot;Walk&quot; animation on channel2.</p><pre> public void simpleInitApp&#40;&#41; &#123;
</table>
<p>
Use the following methods to add or remove individual bones to an AnimChannel. This is useful when you play two animations in parallel on two channels, and each controls a subset of the bones (e.g. one the arms, and the other the legs).
</p>
<table>
<tr>
<th>AnimChannel Methods</th><th>Usage</th>
</tr>
<tr>
<td>addAllBones()</td><td>Add all the bones of the model&#039;s skeleton to be influenced by this animation channel. (default)</td>
</tr>
<tr>
<td>addBone(“bone1”) <br/>
addBone(bone1)</td><td>Add a single bone to be influenced by this animation channel.</td>
</tr>
<tr>
<td>addToRootBone(“bone1”) <br/>
addToRootBone(bone1) </td><td>Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given bone, to the root bone.</td>
</tr>
<tr>
<td>addFromRootBone(“bone1”) <br/>
addFromRootBone(bone1) </td><td>Add a series of bones to be influenced by this animation channel: Add all bones, starting from the given root bone, going towards the children bones.</td>
</tr>
</table>
</div>
<h2><a>Playing Animations</a></h2>
<div>
<p>
Animations are played by channel. <strong>Note:</strong> Whether the animation channel plays continuously or only once, depends on the Loop properties you have set.
</p>
<table>
<tr>
<th>Channel Method</th><th>Usage</th>
</tr>
<tr>
<td>channel_walk.setAnim(“Walk”,0.50f); </td><td> Start the animation named “Walk” on channel channel_walk. <br/>
The float value specifies the time how long the animation should overlap with the previous one on this channel. If set to 0f, then no blending will occur and the new animation will be applied instantly.</td>
</tr>
</table>
<p>
<strong>Tip:</strong> Use the AnimEventLister below to react at the end or start of an animation cycle.
</p>
</div>
<h3><a>Usage Example</a></h3>
<div>
<p>
In this short example, we define the space key to trigger playing the “Walk” animation on channel2.
</p>
<pre> public void simpleInitApp&#40;&#41; &#123;
... ...
inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;; inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;;
@ -277,77 +167,36 @@ In this short example, we define the space key to trigger playing the “Walk”
&#125; &#125;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre></div><h2><a
</div> name="animation_event_listener">Animation Event Listener</a></h2><div
class="level2"><p> A jME3 application that contains animations can implement the <code>com.jme3.animation.AnimEventListener</code> interface.</p><pre>public class HelloAnimation extends SimpleApplication
<h2><a>Animation Event Listener</a></h2> implements AnimEventListener &#123; ... &#125;</pre><p> This optional Listener enables you to respond to animation start and end events, onAnimChange() and onAnimCycleDone().</p></div><h3><a
<div> name="responding_to_animation_end">Responding to Animation End</a></h3><div
class="level3"><p> The onAnimCycleDone() event is invoked when an animation cycle has ended. For non-looping animations, this event is invoked when the animation is finished playing. For looping animations, this even is invoked each time the animation loop is restarted.</p><p> You have access to the following objects:</p><ul><li
<p> class="level1"><div
class="li"> The controller to which the listener is assigned.</div></li><li
A jME3 application that contains animations can implement the <code>com.jme3.animation.AnimEventListener</code> interface. class="level1"><div
</p> class="li"> The animation channel being played.</div></li><li
<pre>public class HelloAnimation extends SimpleApplication class="level1"><div
implements AnimEventListener &#123; ... &#125;</pre> class="li"> The name of the animation that has just finished playing.</div></li></ul><pre> public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
<p>
This optional Listener enables you to respond to animation start and end events, onAnimChange() and onAnimCycleDone().
</p>
</div>
<h3><a>Responding to Animation End</a></h3>
<div>
<p>
The onAnimCycleDone() event is invoked when an animation cycle has ended. For non-looping animations, this event is invoked when the animation is finished playing. For looping animations, this even is invoked each time the animation loop is restarted.
</p>
<p>
You have access to the following objects:
</p>
<ul>
<li><div> The controller to which the listener is assigned.</div>
</li>
<li><div> The animation channel being played.</div>
</li>
<li><div> The name of the animation that has just finished playing.</div>
</li>
</ul>
<pre> public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
// test for a condition you are interested in, e.g. ... // test for a condition you are interested in, e.g. ...
if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123; if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123;
// respond to the event here, e.g. ... // respond to the event here, e.g. ...
channel.setAnim&#40;&quot;Stand&quot;, 0.50f&#41;; channel.setAnim&#40;&quot;Stand&quot;, 0.50f&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="responding_to_animation_start">Responding to Animation Start</a></h3><div
class="level3"><p> The onAnimChange() event is invoked every time before an animation is set by the user to be played on a given channel (<code>channel.setAnim()</code>).</p><p> You have access to the following objects</p><ul><li
<h3><a>Responding to Animation Start</a></h3> class="level1"><div
<div> class="li"> The controller to which the listener is assigned.</div></li><li
class="level1"><div
<p> class="li"> The animation channel being played.</div></li><li
class="level1"><div
The onAnimChange() event is invoked every time before an animation is set by the user to be played on a given channel (<code>channel.setAnim()</code>). class="li"> The name of the animation that will start playing.</div></li></ul><pre> public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
</p>
<p>
You have access to the following objects
</p>
<ul>
<li><div> The controller to which the listener is assigned.</div>
</li>
<li><div> The animation channel being played.</div>
</li>
<li><div> The name of the animation that will start playing.</div>
</li>
</ul>
<pre> public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
// test for a condition you are interested in, e.g. ... // test for a condition you are interested in, e.g. ...
if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123; if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123;
// respond to the event here, e.g. ... // respond to the event here, e.g. ...
channel.setAnim&#40;&quot;Reset&quot;, 0.50f&#41;; channel.setAnim&#40;&quot;Reset&quot;, 0.50f&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:animation?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:animation?do=export_xhtmlbody">view online version</a></em></p>

@ -1,109 +1,62 @@
<h1><a
<h1><a>Application States</a></h1> name="application_states">Application States</a></h1><div
<div> class="level1"><p> <code>com.jme3.app.state.AppState</code> is a customizable jME3 interface that allows you to control the global game logic (game mechanics). To control the behaviour of a type of Spatial, see <a
href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead – both can be used together.</p><p> To implement game logic:</p><ol><li
<p> class="level1"><div
class="li"> You define a custom AppState and implement its behaviour in the AppState&#039;s update() method.</div><ul><li
<code>com.jme3.app.state.AppState</code> is a customizable jME3 interface that allows you to control the global game logic (game mechanics). To control the behaviour of a type of Spatial, see <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead – both can be used together. class="level2"><div
</p> class="li"> You can pass arguments and manipulate everything inside the app&#039;s scope.</div></li></ul></li><li
class="level1"><div
<p> class="li"> Attach the AppState to your application&#039;s AppStateManager (<code>stateManager.attach(myAppState);</code>) to activate it.</div></li><li
To implement game logic: class="level1"><div
</p> class="li"> Create one AppState for each type of game behavior. When you add several AppStates to one Application, they will be executed in the order they were added.</div></li></ol></div><h2><a
<ol> name="usage_examples">Usage Examples</a></h2><div
<li><div> You define a custom AppState and implement its behaviour in the AppState&#039;s update() method.</div> class="level2"><p> JME3 comes with a BulletAppState that implements Physical behaviour (using the jBullet library). You, for example, could write an Artificial Intelligence AppState to control all your enemy units. Existing examples in the code base include:</p><ul><li
<ul> class="level1"><div
<li><div> You can pass arguments and manipulate everything inside the app&#039;s scope.</div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/jbullet/com/jme3/bullet/">BulletAppState</a> controls physical behaviour in PhysicsControl&#039;ed Spatials.</div></li><li
</ul> class="level1"><div
</li> class="li"> <a
<li><div> Attach the AppState to your application&#039;s AppStateManager (<code>stateManager.attach(myAppState);</code>) to activate it.</div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/app/state/TestAppStates.java">TestAppStates.java</a> an example of a custom AppState</div><ul><li
</li> class="level2"><div
<li><div> Create one AppState for each type of game behavior. When you add several AppStates to one Application, they will be executed in the order they were added.</div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/app/state/RootNodeState.java">RootNodeState.java</a></div></li></ul></li></ul></div><h2><a
</ol> name="appstate">AppState</a></h2><div
class="level2"><p> The AppState interface allows you to hook a continously executing piece of code into the main loop.</p><div
</div> class="table sectionedit1"><table
class="inline"><tr
<h2><a>Usage Examples</a></h2> class="row0"><th
<div> class="col0">AppState Method</th><th
class="col1">Usage</th></tr><tr
<p> class="row1"><td
class="col0">isActive()</td><td
JME3 comes with a BulletAppState that implements Physical behaviour (using the jBullet library). You, for example, could write an Artificial Intelligence AppState to control all your enemy units. Existing examples in the code base include: class="col1">Test whether AppState is enabled or disabled.</td></tr><tr
class="row2"><td
</p> class="col0">stateAttached(asm) <br/> stateDetached(asm)</td><td
<ul> class="col1">The AppState knows when it is attached to, or detached from, the AppStateManager. Then it triggers these methods that you implement.</td></tr><tr
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/jbullet/com/jme3/bullet/"><param name="text" value="<html><u>BulletAppState</u></html>"><param name="textColor" value="blue"></object> controls physical behaviour in PhysicsControl&#039;ed Spatials.</div> class="row3"><td
</li> class="col0">isInitialized()</td><td
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/app/state/TestAppStates.java"><param name="text" value="<html><u>TestAppStates.java</u></html>"><param name="textColor" value="blue"></object> an example of a custom AppState</div> class="col1">Your implementations of this interface should return the correct respective boolean value.</td></tr><tr
<ul> class="row4"><td
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/app/state/RootNodeState.java"><param name="text" value="<html><u>RootNodeState.java</u></html>"><param name="textColor" value="blue"></object></div> class="col0">initialize(asm,app)</td><td
</li> class="col1">The RenderThread initialized the AppState and then calls this method.</td></tr><tr
</ul> class="row5"><td
</li> class="col0">setActive(true) <br/> setActive(false)</td><td
</ul> class="col1">Temporarily enables or disables an AppState.</td></tr><tr
class="row6"><td
</div> class="col0">update(float tpf)</td><td
class="col1">Here you implement the behaviour that you want to hook into the main update loop.</td></tr><tr
<h2><a>AppState</a></h2> class="row7"><td
<div> class="col0">cleanup()</td><td
class="col1">Called when when the AppState is de-initialized.</td></tr><tr
<p> class="row8"><td
class="col0">render(RenderManager rm)</td><td
The AppState interface allows you to hook a continously executing piece of code into the main loop. class="col1">Renders the state.</td></tr><tr
class="row9"><td
</p> class="col0">postRender()</td><td
<table> class="col1">Called after all rendering commands are flushed.</td></tr></table></div></div><h2><a
<tr> name="abstractappstate">AbstractAppState</a></h2><div
<th>AppState Method</th><th>Usage</th> class="level2"><p> The AbstractAppState class already implements some common methods and makes creation of custom AppStates a bit easier: isInitialized(), setActive(), isActive(), cleanUp(). Just extend it and override the remaining AppState methods.</p><p> Definition:</p><pre>public class MyAppState extends AbstractAppState &#123;
</tr>
<tr>
<td>isActive()</td><td>Test whether AppState is enabled or disabled.</td>
</tr>
<tr>
<td>stateAttached(asm) <br/>
stateDetached(asm)</td><td>The AppState knows when it is attached to, or detached from, the AppStateManager. Then it triggers these methods that you implement.</td>
</tr>
<tr>
<td>isInitialized()</td><td>Your implementations of this interface should return the correct respective boolean value.</td>
</tr>
<tr>
<td>initialize(asm,app)</td><td>The RenderThread initialized the AppState and then calls this method.</td>
</tr>
<tr>
<td>setActive(true) <br/>
setActive(false)</td><td>Temporarily enables or disables an AppState.</td>
</tr>
<tr>
<td>update(float tpf)</td><td>Here you implement the behaviour that you want to hook into the main update loop.</td>
</tr>
<tr>
<td>cleanup()</td><td>Called when when the AppState is de-initialized.</td>
</tr>
<tr>
<td>render(RenderManager rm)</td><td>Renders the state.</td>
</tr>
<tr>
<td>postRender()</td><td>Called after all rendering commands are flushed.</td>
</tr>
</table>
</div>
<h2><a>AbstractAppState</a></h2>
<div>
<p>
The AbstractAppState class already implements some common methods and makes creation of custom AppStates a bit easier: isInitialized(), setActive(), isActive(), cleanUp(). Just extend it and override the remaining AppState methods.
</p>
<p>
Definition:
</p>
<pre>public class MyAppState extends AbstractAppState &#123;
private Node x = new Node&#40;&quot;x&quot;&#41;; // some class field private Node x = new Node&#40;&quot;x&quot;&#41;; // some class field
&nbsp; &nbsp;
public Node getX&#40;&#41;&#123; public Node getX&#40;&#41;&#123;
@ -114,11 +67,7 @@ Definition:
public void update&#40;float tpf&#41; &#123; public void update&#40;float tpf&#41; &#123;
x.doSomething&#40;&#41;; // implement behaviour x.doSomething&#40;&#41;; // implement behaviour
&#125; &#125;
&#125;</pre> &#125;</pre><p> Usage:</p><pre>public class TestAppStates extends Application &#123;
<p>
Usage:
</p>
<pre>public class TestAppStates extends Application &#123;
public static void main&#40;String&#91;&#93; args&#41;&#123; public static void main&#40;String&#91;&#93; args&#41;&#123;
TestAppStates app = new TestAppStates&#40;&#41;; TestAppStates app = new TestAppStates&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
@ -139,73 +88,20 @@ Usage:
stateManager.render&#40;renderManager&#41;; stateManager.render&#40;renderManager&#41;;
renderManager.render&#40;tpf&#41;; renderManager.render&#40;tpf&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> <strong>Note:</strong> If you use the AppState together with a SimpleApplication-based class, then this <code>update()</code> loop is already set up.</p></div><h2><a
<p> name="appstatemanager">AppStateManager</a></h2><div
<strong>Note:</strong> If you use the AppState together with a SimpleApplication-based class, then this <code>update()</code> loop is already set up. class="level2"><p> The com.jme3.app.state.AppStateManager holds the list of AppStates for an application. AppStateManager ensures that active AppStates are updated and rendered. When an AppState is attached, AppStateManager calls its stateAttached() method. When an AppState is detached, AppStateManager calls its stateDetached() method.</p><p> There is one AppStateManager per application. You can attach several AppStates to one AppStateManager, but the same state can only be attached once.</p><div
</p> class="table sectionedit2"><table
class="inline"><tr
</div> class="row0"><th
class="col0">AppStateManager Method</th><th
<h2><a>AppStateManager</a></h2> class="col1">Usage</th></tr><tr
<div> class="row1"><td
class="col0">hasState(s)</td><td
<p> class="col1">Is AppState s attached?</td></tr><tr
class="row2"><td
The com.jme3.app.state.AppStateManager holds the list of AppStates for an application. AppStateManager ensures that active AppStates are updated and rendered. When an AppState is attached, AppStateManager calls its stateAttached() method. When an AppState is detached, AppStateManager calls its stateDetached() method. class="col0">getState(Class&lt;T&gt; stateClass)</td><td
</p> class="col1">Returns the first state that is an instance of a subclass of the specified class.</td></tr></table></div><p> The AppStateManager&#039;s update(), render(), postRender(), and cleanUp() methods are internal, users never call them directly.</p></div><h2><a
name="best_practices">Best Practices</a></h2><div
<p> class="level2"><p> You can only change AppStates, or read and write to them, from certain places: In a Control&#039;s update() method, in an AppState&#039;s update() method, and it the SimpleApplication&#039;s simpleUpdate() loop (or the Application&#039;s update() loop).</p><p> To get data from the AppState <code>MyAppState</code>:</p><pre>app.getState&#40;MyAppState.class&#41;.getInfoAboutSomething&#40;&#41;;</pre><p> To pass new data into the AppState <code>MyAppState</code>:</p><pre>app.getState&#40;MyAppState.class&#41;.setSomething&#40;blah&#41;;</pre><p> To trigger a one-off method in the AppState <code>MyAppState</code>:</p><pre>app.getState&#40;MyAppState.class&#41;.doSomeMoreStuff&#40;&#41;;</pre><p> Don&#039;t mess with the AppState from other places, because from other methods you have no control over the order of updates. You don&#039;t know when (during which half-finished step of an update), your call was received.</p></div>
There is one AppStateManager per application. You can attach several AppStates to one AppStateManager, but the same state can only be attached once.
</p>
<table>
<tr>
<th>AppStateManager Method</th><th>Usage</th>
</tr>
<tr>
<td>hasState(s)</td><td>Is AppState s attached?</td>
</tr>
<tr>
<td>getState(Class&lt;T&gt; stateClass)</td><td>Returns the first state that is an instance of a subclass of the specified class.</td>
</tr>
</table>
<p>
The AppStateManager&#039;s update(), render(), postRender(), and cleanUp() methods are internal, users never call them directly.
</p>
</div>
<h2><a>Best Practices</a></h2>
<div>
<p>
You can only change AppStates, or read and write to them, from certain places: In a Control&#039;s update() method, in an AppState&#039;s update() method, and it the SimpleApplication&#039;s simpleUpdate() loop (or the Application&#039;s update() loop).
</p>
<p>
To get data from the AppState <code>MyAppState</code>:
</p>
<pre>app.getState&#40;MyAppState.class&#41;.getInfoAboutSomething&#40;&#41;;</pre>
<p>
To pass new data into the AppState <code>MyAppState</code>:
</p>
<pre>app.getState&#40;MyAppState.class&#41;.setSomething&#40;blah&#41;;</pre>
<p>
To trigger a one-off method in the AppState <code>MyAppState</code>:
</p>
<pre>app.getState&#40;MyAppState.class&#41;.doSomeMoreStuff&#40;&#41;;</pre>
<p>
Don&#039;t mess with the AppState from other places, because from other methods you have no control over the order of updates. You don&#039;t know when (during which half-finished step of an update), your call was received.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:application_states?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:application_states?do=export_xhtmlbody">view online version</a></em></p>

@ -1,38 +1,7 @@
<h1><a
<h1><a>AssetManager</a></h1> name="assetmanager">AssetManager</a></h1><div
<div> class="level1"><p> JME3 has an integrated an asset manager that helps you keep your project assets organized. By assets we mean media files, such as 3D models, materials, textures, scenes, shaders, sounds, and fonts. Think of the asset manager as the filesystem of your game, independent of the actual deployment platform. It also manages the appropriate managing of OpenGL objects like textures so that they are e.g. not uploaded to the graphics card multiple times when multiple models use them.</p><p> The <code>assetManager</code> object is an com.jme3.asset.AssetManager instance that every com.jme3.app.Application can access. It maintains a root that also includes your project&#039;s classpath by default, so you can load any asset that&#039;s on the classpath, that is, the top level of your project directory.</p><p> You can use the inherited <code>assetManager</code> object directly, or use the accessor <code>getAssetManager()</code>.</p><p> Here is an example how you load assets using the AssetManager. This lines loads a default Material from the Common directory:</p><pre>Material mat = &#40;Material&#41; assetManager.loadAsset&#40;
new AssetKey&#40;&quot;Common/Materials/RedColor.j3m&quot;&#41;&#41;;</pre><p> The Material is &quot;somewhere&quot; in the jME3 JAR, but the default Asset Manager is configured to handle a <code>Common/…</code> path correctly, so you don&#039;t have to specify the whole path.</p><p> Additionally, You can configure the Asset Manager and add any path to its root. This means, you can load assets from any project directory you specify.</p><p> <strong>In project created with jMonkeyPlatform, jME3 searches for models in the <code>assets</code> directory of your project by default.</strong> This is our recommended directory structure for storing assets:</p><pre>MyGame/assets/Interface/
<p>
JME3 has an integrated an asset manager that helps you keep your project assets organized. By assets we mean media files, such as 3D models, materials, textures, scenes, shaders, sounds, and fonts. Think of the asset manager as the filesystem of your game, independent of the actual deployment platform. It also manages the appropriate managing of OpenGL objects like textures so that they are e.g. not uploaded to the graphics card multiple times when multiple models use them.
</p>
<p>
The <code>assetManager</code> object is an com.jme3.asset.AssetManager instance that every com.jme3.app.Application can access. It maintains a root that also includes your project&#039;s classpath by default, so you can load any asset that&#039;s on the classpath, that is, the top level of your project directory.
</p>
<p>
You can use the inherited <code>assetManager</code> object directly, or use the accessor <code>getAssetManager()</code>.
</p>
<p>
Here is an example how you load assets using the AssetManager. This lines loads a default Material from the Common directory:
</p>
<pre>Material mat = &#40;Material&#41; assetManager.loadAsset&#40;
new AssetKey&#40;&quot;Common/Materials/RedColor.j3m&quot;&#41;&#41;;</pre>
<p>
The Material is “somewhere” in the jME3 JAR, but the default Asset Manager is configured to handle a <code>Common/…</code> path correctly, so you don&#039;t have to specify the whole path.
</p>
<p>
Additionally, You can configure the Asset Manager and add any path to its root. This means, you can load assets from any project directory you specify.
</p>
<p>
<strong>In project created with jMonkeyPlatform, jME3 searches for models in the <code>assets</code> directory of your project by default.</strong> This is our recommended directory structure for storing assets:
</p>
<pre>
MyGame/assets/Interface/
MyGame/assets/MatDefs/ MyGame/assets/MatDefs/
MyGame/assets/Materials/ MyGame/assets/Materials/
MyGame/assets/Models/ MyGame/assets/Models/
@ -41,18 +10,9 @@ MyGame/assets/Shaders/
MyGame/assets/Sounds/ MyGame/assets/Sounds/
MyGame/assets/Textures/ MyGame/assets/Textures/
MyGame/build.xml MyGame/build.xml
MyGame/src/... MyGame/src/...</pre><p> These are just the most common examples, you can name the directories inside the assets directory how you like.</p></div><h2><a
</pre> name="loading_assets">Loading Assets</a></h2><div
class="level2"><pre>// Creating a material instance with the definition &quot;Unshaded.j3md&quot;.
<p>
These are just the most common examples, you can name the directories inside the assets directory how you like.
</p>
</div>
<h2><a>Loading Assets</a></h2>
<div>
<pre>// Creating a material instance with the definition &quot;Unshaded.j3md&quot;.
Material mat_brick = new Material&#40; Material mat_brick = new Material&#40;
assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
&nbsp; &nbsp;
@ -69,86 +29,45 @@ Spatial ninja = assetManager.loadModel&#40;&quot;Models/Ninja/Ninja.mesh.xml&quo
// Loading a scene from an Ogre3D dotScene file stored inside a zip // Loading a scene from an Ogre3D dotScene file stored inside a zip
assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;; assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre> rootNode.attachChild&#40;scene&#41;;</pre><p> Here is a HttpZipLocator that can stream models from a zip file online:</p><pre> assetManager.registerLocator&#40;&quot;http://jmonkeyengine.googlecode.com/files/wildhouse.zip&quot;,
<p>
Here is a HttpZipLocator that can stream models from a zip file online:
</p>
<pre> assetManager.registerLocator&#40;&quot;http://jmonkeyengine.googlecode.com/files/wildhouse.zip&quot;,
HttpZipLocator.class.getName&#40;&#41;&#41;; HttpZipLocator.class.getName&#40;&#41;&#41;;
Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre> rootNode.attachChild&#40;scene&#41;;</pre><p> JME3 offers ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see <code>com.jme3.asset.plugins</code>).</p><div
<p> class="table sectionedit1"><table
JME3 offers ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see <code>com.jme3.asset.plugins</code>). class="inline"><tr
</p> class="row0"><th
<table> class="col0"> Task?</th><th
<tr> class="col1"> Solution!</th></tr><tr
<th> Task? </th><th> Solution! </th> class="row1"><td
</tr> class="col0"> Load a model with materials</td><td
<tr> class="col1"> Use the asset managers <code>loadModel()</code> method and attach the Spatial to the rootNode.<pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.mesh.xml&quot;&#41;;
<td> Load a model with materials </td><td> Use the asset managers <code>loadModel()</code> method and attach the Spatial to the rootNode. <pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.mesh.xml&quot;&#41;;
rootNode.attachChild&#40;elephant&#41;;</pre><pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.j3o&quot;&#41;; rootNode.attachChild&#40;elephant&#41;;</pre><pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.j3o&quot;&#41;;
rootNode.attachChild&#40;elephant&#41;;</pre></td> rootNode.attachChild&#40;elephant&#41;;</pre></td></tr><tr
</tr> class="row2"><td
<tr> class="col0"> Load a model without materials</td><td
<td> Load a model without materials </td><td> If you have a model without materials, you have to add a default material to make it visible. <pre>Spatial teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;; class="col1"> If you have a model without materials, you have to add a default material to make it visible.<pre>Spatial teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;;
teapot.setMaterial&#40;mat&#41;; teapot.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;teapot&#41;;</pre></td> rootNode.attachChild&#40;teapot&#41;;</pre></td></tr><tr
</tr> class="row3"><td
<tr> class="col0"> Load a scene</td><td
<td> Load a scene </td><td> You load scenes just like you load models: <pre>Spatial scene = assetManager.loadModel&#40;&quot;Scenes/house/main.scene&quot;&#41;; class="col1"> You load scenes just like you load models:<pre>Spatial scene = assetManager.loadModel&#40;&quot;Scenes/house/main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre></td> rootNode.attachChild&#40;scene&#41;;</pre></td></tr></table></div></div><h2><a
</tr> name="nullpointerexceptioncannot_locate_resource">NullPointerException: Cannot locate resource?</a></h2><div
</table> class="level2"><p> An error mesage similar to the following can occur in the console when you run executables, even if the game runs fine when started from the jMoneykPlatform.</p><pre>com.jme3.asset.DesktopAssetManager loadAsset
</div>
<h2><a>NullPointerException: Cannot locate resource?</a></h2>
<div>
<p>
An error mesage similar to the following can occur in the console when you run executables, even if the game runs fine when started from the jMoneykPlatform.
</p>
<pre>com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Scenes/town/main.scene WARNING: Cannot locate resource: Scenes/town/main.scene
com.jme3.app.Application handleError com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main] SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException java.lang.NullPointerException</pre><p> Reason: If you use the default build script created by the jMonkeyPlatform then <strong>the original OgreXML files are not included in the executable.</strong></p><p> For a stand-alone build, you <strong>work with .j3o files only</strong>. The default build script makes sure to include .j3o files in the executable.</p><p> You must use the jMonkeyPlatform&#039;s context menu action to <a
</pre> href="/com/jme3/gde/core/docs/jme3/jmonkeyplatform/model_loader_and_viewer.html">convert OgreXML models to .j3o format</a> to get rid of this error.</p><ol><li
class="level1"><div
<p> class="li"> Open the JME3 Project in the jMonkeyplatform.</div></li><li
Reason: If you use the default build script created by the jMonkeyPlatform then <strong>the original OgreXML files are not included in the executable.</strong> class="level1"><div
</p> class="li"> Browse the Assets directory in the Projects window.</div></li><li
class="level1"><div
<p> class="li"> Right-click a .mesh.xml file, and choose &quot;convert to JME3 binary&quot;.</div></li><li
For a stand-alone build, you <strong>work with .j3o files only</strong>. The default build script makes sure to include .j3o files in the executable. class="level1"><div
</p> class="li"> The converted file appears in the same directory as the .mesh.xml file. It has the same name and a .j3o suffix.</div></li></ol></div><h2><a
name="asset_handlingcodeless_projects">Asset Handling: Codeless Projects</a></h2><div
<p> class="level2"><p> If you are using another IDE than jMonkeyPlatform, you can create a codeless project in the jMonkeyPlatform to maintain assets. This method will not meddle with your sources or custom build scripts, but you can still browse your assets, and preview, arrange, and convert models. You can, for example, give the designers in your team access to such a codeless project.</p></div>
You must use the jMonkeyPlatform&#039;s context menu action to <a href="/com/jme3/gde/core/docs/jme3/jmonkeyplatform/model_loader_and_viewer.html">convert OgreXML models to .j3o format</a> to get rid of this error.
</p>
<ol>
<li><div> Open the JME3 Project in the jMonkeyplatform.</div>
</li>
<li><div> Browse the Assets directory in the Projects window. </div>
</li>
<li><div> Right-click a .mesh.xml file, and choose “convert to JME3 binary”. </div>
</li>
<li><div> The converted file appears in the same directory as the .mesh.xml file. It has the same name and a .j3o suffix. </div>
</li>
</ol>
</div>
<h2><a>Asset Handling: Codeless Projects</a></h2>
<div>
<p>
If you are using another IDE than jMonkeyPlatform, you can create a codeless project in the jMonkeyPlatform to maintain assets. This method will not meddle with your sources or custom build scripts, but you can still browse your assets, and preview, arrange, and convert models. You can, for example, give the designers in your team access to such a codeless project.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:asset_manager?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:asset_manager?do=export_xhtmlbody">view online version</a></em></p>

@ -1,148 +1,141 @@
<h1><a
<h1><a>Audio in jME3</a></h1> name="audio_in_jme3">Audio in jME3</a></h1><div
<div> class="level1"><p> There are two ways to handle audio data: Short audio files are to be stored entirely in memory, while long audio files (music) is streamed from the hard drive as it is played.
Place audio files in the <code>assets/Sound/</code> directory of your project. jME3 supports Ogg Vorbis (.ogg) and Wave (.wav) formats.</p></div><h2><a
<p> name="creating_audio_nodes">Creating Audio Nodes</a></h2><div
class="level2"><p> The main class to look at is <code>com.jme3.audio.AudioNode</code>.
There are two ways to handle audio data: Short audio files are to be stored entirely in memory, while long audio files (music) is streamed from the hard drive as it is played. By default, a new audio node is buffered, i.e. JME loads the whole file into memory before playing:</p><pre>AudioNode boom = new AudioNode&#40;audioRenderer, assetManager, &quot;Sound/boom.wav&quot;&#41;;</pre><p> If it is a long file, you set the boolean to true to stream the audio.</p><pre>AudioNode music = new AudioNode&#40;audioRenderer, assetManager, &quot;Sound/music.wav&quot;, true&#41;;</pre></div><h2><a
</p> name="setting_audionode_properties">Setting AudioNode Properties</a></h2><div
class="level2"><div
<p> class="table sectionedit1"><table
Place audio files in the <code>assets/Sound/</code> directory of your project. jME3 supports Ogg Vorbis (.ogg) and Wave (.wav) formats. class="inline"><tr
</p> class="row0"><th
class="col0">AudioNode Method</th><th
</div> class="col1">Usage</th></tr><tr
class="row1"><td
<h2><a>Creating Audio Nodes</a></h2> class="col0">getStatus()</td><td
<div> class="col1">Returns either Status.Playing, Status.Stopped, or Status.Paused.</td></tr><tr
class="row2"><td
<p> class="col0">setVolume(1)</td><td
class="col1">Sets the volume gain. 1 is the default volume, 2 is twice as loud, 0 is mute.</td></tr><tr
The main class to look at is <code>com.jme3.audio.AudioNode</code>. class="row3"><td
</p> class="col0">setPitch(1)</td><td
class="col1">Makes the sound play in a higher or lower pitch. Default is 1.</td></tr><tr
<p> class="row4"><th
By default, a new audio node loads the whole file into memory: class="col0">AudioNode Method</th><th
class="col1">Usage</th></tr><tr
</p> class="row5"><td
<pre>AudioNode boom = new AudioNode&#40;assetManager, &quot;Sound/boom.wav&quot;&#41;;</pre> class="col0">setLooping(false)</td><td
<p> class="col1">Configures the sound that, if it is played, it plays once and stops. This is the default.</td></tr><tr
If it is a long file, you set the boolean to true to stream the audio. class="row6"><td
class="col0">setLooping(true)</td><td
</p> class="col1 leftalign">Configures the sound that, if it is played, it plays repeats from the beginning, until stop() or pause() are called. Good for ambient background noises.</td></tr><tr
<pre>AudioNode music = new AudioNode&#40;assetManager, &quot;Sound/music.wav&quot;, true&#41;;</pre> class="row7"><td
</div> class="col0">setPositional(false) <br/> setDirectional(false)</td><td
class="col1">All 3D effects switched off. This sound is global and comes from everywhere. Good for environmental ambient sounds and background music.</td></tr><tr
<h2><a>Setting AudioNode Properties</a></h2> class="row8"><td
<div> class="col0">setTimeOffset(0.5f)</td><td
<table> class="col1">Start playing the sound after waiting the given amount of seconds. Default is 0.</td></tr><tr
<tr> class="row9"><td
<th>AudioNode method</th><th>Usage</th> class="col0">setMaxDistance(100f)</td><td
</tr> class="col1">Maximum distance the sound can be heard, in world units. Default is 20.</td></tr><tr
<tr> class="row10"><th
<td>getStatus()</td><td>Returns either Status.Playing, Status.Stopped, or Status.Paused.</td> class="col0">AudioNode Method</th><th
</tr> class="col1">Usage</th></tr><tr
<tr> class="row11"><td
<td>setVolume(5)</td><td>Set the volume between 0 (mute) and 10 (loud).</td> class="col0">setPositional(true) <br/> setLocalTranslation(new Vector 3f(0,0,0))</td><td
</tr> class="col1">Activates 3D audio, the sound appears to come from a certain position, where it is loudest. Position the AudioNode in the 3D scene if you have setPositional() true. Position it with mobile players or NPCs.</td></tr><tr
<tr> class="row12"><td
<td>setPitch(1)</td><td>Make the sound play higher or lower.</td> class="col0">setReverbEnabled(true)</td><td
</tr> class="col1">A 3D echo effect that only makes sense to use with moving positional AudioNodes. The reverb effect is influenced by the environment that the audio renderer is in. See &quot;Setting Environment Properties&quot; below.</td></tr><tr
<tr> class="row13"><th
<td>setLooping(false)</td><td>Play it once and stop.</td> class="col0">AudioNode Method</th><th
</tr> class="col1">Usage</th></tr><tr
<tr> class="row14"><td
<td>setLooping(true)</td><td>Play it over and over again from the beginning, until stopSource() or pauseSource() is called. E.g. for background noises.</td> class="col0">setDirectional(true) <br/> setDirection(new Vector3f(0,0,1))</td><td
</tr> class="col1">Activates 3D audio. This sound can only be heard from a certain direction. Specify the direction and angle in the 3D scene if you have setDirectional() true. Good for noises that should not be heard through a wall.</td></tr><tr
<tr> class="row15"><td
<td>setPositional(true) <br/> class="col0">setInnerAngle() <br/> setOuterAngle()</td><td
setLocalTranslation()</td><td>Activates 3D audio, the sound appears to come from a certain position. Good for Players or NPCs.</td> class="col1">Set the angle in degrees for the directional audio. The angle is relative to the direction. By default, both angles are 360° and the sound can be heard from all directions.</td></tr></table></div></div><h2><a
</tr> name="play_pause_stop">Play, Pause, Stop</a></h2><div
<tr> class="level2"><p> You play, pause, and stop a node called myAudioNode by using the respective of the following three methods:</p><pre>myAudioNode.play&#40;&#41;;</pre><pre>myAudioNode.pause&#40;&#41;;</pre><pre>myAudioNode.stop&#40;&#41;;</pre><p> <strong>Note:</strong> Whether an Audio Node plays continuously or only once, depends on the Loop properties you have set above!</p></div><h2><a
<td>setReverbEnabled(true)</td><td>A 3D echo effect that only makes sense to use with moving positional AudioNodes.</td> name="setting_environment_properties">Setting Environment Properties</a></h2><div
</tr> class="level2"><p> Optionally, You can choose from the following environmental presets from <code>com.jme3.audio.Environment</code>. This presets influence subtle echo effects that evoke associations of different environments in your users. You use it together with setReverbEnbaled(true) mentioned above.</p><div
<tr> class="table sectionedit2"><table
<td>setDirectional(true) <br/> class="inline"><tr
setDirection() </td><td>Activates 3D audio, sound can only be heard from a certain direction. Good for noises that should not be heard through a wall.</td> class="row0"><th
</tr> class="col0">Environment</th><th
<tr> class="col1">density</th><th
<td>setInnerAngle() <br/> class="col2">diffusion</th><th
setOuterAngle()</td><td>?</td> class="col3">gain</th><th
</tr> class="col4">gainHf</th><th
<tr> class="col5">decayTime</th><th
<td>setPositional(false) <br/> class="col6">decayHf</th><th
setDirectional(false)</td><td>The sound comes from a everywhere. Good for environmental background sounds and music.</td> class="col7">reflGain</th><th
</tr> class="col8">reflDelay</th><th
<tr> class="col9">lateGain</th><th
<td>setLocalTranslation()</td><td>Position the AudioNode in the 3D scene if you have set setPositional() to true.</td> class="col10">lateDelay</th></tr><tr
</tr> class="row1"><td
<tr> class="col0 leftalign">Garage</td><td
<td>setTimeOffset(0.5f)</td><td>Start playing after a pause?</td> class="col1">1.00f</td><td
</tr> class="col2">1.0f</td><td
<tr> class="col3">1.0f</td><td
<td>setMaxDistance(100f)</td><td>Maximum distance the sound can be heard, in world units.</td> class="col4">1.00f</td><td
</tr> class="col5">0.90f</td><td
</table> class="col6">0.5f</td><td
class="col7">0.751f</td><td
</div> class="col8">0.0039f</td><td
class="col9">0.661f</td><td
<h2><a>Playing Audio Nodes</a></h2> class="col10">0.0137f</td></tr><tr
<div> class="row2"><td
class="col0 leftalign">Dungeon</td><td
<p> class="col1">0.75f</td><td
class="col2">1.0f</td><td
For playing you use the <code>com.jme3.audio.AudioRenderer</code>. A default <code>audioRenderer</code> object is provided by the com.jme3.app.Application class. class="col3">1.0f</td><td
</p> class="col4">0.75f</td><td
<pre>audioRenderer.playSource&#40; myAudioNode &#41;;</pre> class="col5">1.60f</td><td
<p> class="col6">1.0f</td><td
<strong>Note:</strong> Whether the AudioNode plays continuously or only once, depends on the Loop properties you have set. class="col7">0.950f</td><td
</p> class="col8">0.0026f</td><td
class="col9">0.930f</td><td
<p> class="col10">0.0103f</td></tr><tr
You pause and stop music with the following methods: class="row3"><td
</p> class="col0 leftalign">Cavern</td><td
<pre>audioRenderer.pauseSource&#40; myAudioNode &#41;;</pre><pre>audioRenderer.stopSource&#40; myAudioNode &#41;;</pre> class="col1">0.50f</td><td
</div> class="col2">1.0f</td><td
class="col3">1.0f</td><td
<h2><a>Setting Environment Properties</a></h2> class="col4">0.50f</td><td
<div> class="col5">2.25f</td><td
class="col6">1.0f</td><td
<p> class="col7">0.908f</td><td
class="col8">0.0103f</td><td
You can choose from the following environmental presets from <code>com.jme3.audio.Environment</code>. class="col9">0.930f</td><td
class="col10">0.0410f</td></tr><tr
</p> class="row4"><td
<table> class="col0">AcousticLab</td><td
<tr> class="col1">0.50f</td><td
<th>Environment</th><th>density</th><th>diffusion</th><th>gain</th><th>gainHf</th><th>decayTime</th><th>decayHf</th><th>reflGain</th><th>reflDelay</th><th>lateGain</th><th>lateDelay</th> class="col2">1.0f</td><td
</tr> class="col3">1.0f</td><td
<tr> class="col4">1.00f</td><td
<td>Garage </td><td>1.00f</td><td>1.0f</td><td>1.0f</td><td>1.00f</td><td>0.90f</td><td>0.5f</td><td>0.751f</td><td>0.0039f</td><td>0.661f</td><td>0.0137f</td> class="col5">0.28f</td><td
</tr> class="col6">1.0f</td><td
<tr> class="col7">0.870f</td><td
<td>Dungeon </td><td>0.75f</td><td>1.0f</td><td>1.0f</td><td>0.75f</td><td>1.60f</td><td>1.0f</td><td>0.950f</td><td>0.0026f</td><td>0.930f</td><td>0.0103f</td> class="col8">0.0020f</td><td
</tr> class="col9">0.810f</td><td
<tr> class="col10">0.0080f</td></tr><tr
<td>Cavern </td><td>0.50f</td><td>1.0f</td><td>1.0f</td><td>0.50f</td><td>2.25f</td><td>1.0f</td><td>0.908f</td><td>0.0103f</td><td>0.930f</td><td>0.0410f</td> class="row5"><td
</tr> class="col0 leftalign">Closet</td><td
<tr> class="col1">1.00f</td><td
<td>AcousticLab </td><td>0.50f</td><td>1.0f</td><td>1.0f</td><td>1.00f</td><td>0.28f</td><td>1.0f</td><td>0.870f</td><td>0.0020f</td><td>0.810f</td><td>0.0080f</td> class="col2">1.0f</td><td
</tr> class="col3">1.0f</td><td
<tr> class="col4">1.00f</td><td
<td>Closet </td><td>1.00f</td><td>1.0f</td><td>1.0f</td><td>1.00f</td><td>0.15f</td><td>1.0f</td><td>0.600f</td><td>0.0025f</td><td>0.500f</td><td>0.0006f</td> class="col5">0.15f</td><td
</tr> class="col6">1.0f</td><td
</table> class="col7">0.600f</td><td
class="col8">0.0025f</td><td
<p> class="col9">0.500f</td><td
class="col10">0.0006f</td></tr></table></div><p> Activate the preset with setEnvironment(). E.g. in a dungeon environment:</p><pre>audioRenderer.setEnvironment&#40;new Environment.Dungeon&#41;&#41;;</pre><p> A sound engineer can create a custom <code>com.jme3.audio.Environment</code> object and specify custom environment factors. Activate your custom environment settings in the Environment constructor:</p><pre>audioRenderer.setEnvironment&#40;
Activate the preset with:
</p>
<pre>audioRenderer.setEnvironment&#40;new Environment.Dungeon&#41;&#41;;</pre>
<p>
Alternatively you can create a <code>com.jme3.audio.Environment</code> object to specify custom environment factors. Activate your custom environment settings in the Environment constructor:
</p>
<pre>audioRenderer.setEnvironment&#40;
new Environment&#40; density, diffusion, gain, gainHf, decayTime, decayHf, new Environment&#40; density, diffusion, gain, gainHf, decayTime, decayHf,
reflGain, reflDelay, lateGain, lateDelay &#41; &#41;;</pre> reflGain, reflDelay, lateGain, lateDelay &#41; &#41;;</pre><p> You can find more info about OpenAL and its advanced features here: <a
</div> href="http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.pdf">OpenAL 1.1 Specification</a></p></div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:audio?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:audio?do=export_xhtmlbody">view online version</a></em></p>

@ -1,96 +1,61 @@
<h1><a
<h1><a>Bloom and Glow</a></h1> name="bloom_and_glow">Bloom and Glow</a></h1><div
<div> class="level1"><p> Bloom is a popular shader effect in 3D games industry. It usually consist in displaying a glowing halo around light sources or bright areas of a scene.
In practice, the bright areas are extracted from the rendered scene, blurred and finally added up to the render.</p><p> Those images gives an idea of what bloom does. The left image has no bloom effect, the right image does. <br/> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:nobloomsky.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nobloomsky.png" class="media" title="No bloom" alt="No bloom" /></a><a
Bloom is a popular shader effect in 3D games industry. It usually consist in displaying a glowing halo around light sources or bright areas of a scene. href="/wiki/lib/exe/detail.php/jme3:advanced:blomsky.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
In practice, the bright areas are extracted from the rendered scene, blurred and finally added up to the render. src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/blomsky.png" class="media" title="Bloom" alt="Bloom" /></a></p></div><h1><a
</p> name="bloom_usage">Bloom Usage</a></h1><div
class="level1"><ol><li
<p> class="level1"><div
Those images gives an idea of what bloom does. The left image has no bloom effect, the right image does. <br/> class="li"> Create a FilterPostProcessor</div></li><li
class="level1"><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nobloomsky.png"><img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/blomsky.png"> class="li"> Create a BloomFilter</div></li><li
</p> class="level1"><div
class="li"> Add the filter to the processor</div></li><li
</div> class="level1"><div
class="li"> Add the processor to the viewPort</div></li></ol><pre> FilterPostProcessor fpp=new FilterPostProcessor&#40;assetManager&#41;;
<h1><a>Bloom Usage</a></h1>
<div>
<ol>
<li><div> Create a FilterPostProcessor</div>
</li>
<li><div> Create a BloomFilter</div>
</li>
<li><div> Add the filter to the processor</div>
</li>
<li><div> Add the processor to the viewPort</div>
</li>
</ol>
<pre> FilterPostProcessor fpp=new FilterPostProcessor&#40;assetManager&#41;;
BloomFilter bloom=new BloomFilter&#40;&#41;; BloomFilter bloom=new BloomFilter&#40;&#41;;
fpp.addFilter&#40;bloom&#41;; fpp.addFilter&#40;bloom&#41;;
viewPort.addProcessor&#40;fpp&#41;;</pre> viewPort.addProcessor&#40;fpp&#41;;</pre><p> Here are the parameters that you can tweak :</p><div
<p> class="table sectionedit1"><table
Here are the parameters that you can tweak : class="inline"><tr
</p> class="row0"><th
<table> class="col0 leftalign"> Parameter</th><th
<tr> class="col1 leftalign"> Method</th><th
<th> Parameter </th><th> Method </th><th> Default </th><th> Description </th> class="col2"> Default</th><th
</tr> class="col3"> Description</th></tr><tr
<tr> class="row1"><td
<td> blur scale </td><td> <code>setBlurScale(float)</code> </td><td>1.5f </td><td> the scale of the bloom effect, but be careful, high values does artifacts </td> class="col0 leftalign"> blur scale</td><td
</tr> class="col1"> <code>setBlurScale(float)</code></td><td
<tr> class="col2 leftalign">1.5f</td><td
<td> exposure Power </td><td> <code>setExposurePower(float)</code> </td><td>5.0f </td><td> the glowing channel color is raised to the value power </td> class="col3"> the scale of the bloom effect, but be careful, high values does artifacts</td></tr><tr
</tr> class="row2"><td
<tr> class="col0 leftalign"> exposure Power</td><td
<td> exposure cut-off </td><td> <code>setExposureCutOff(float)</code> </td><td>0.0f </td><td> the threshold of color to bloom during extraction </td> class="col1"> <code>setExposurePower(float)</code></td><td
</tr> class="col2 leftalign">5.0f</td><td
<tr> class="col3"> the glowing channel color is raised to the value power</td></tr><tr
<td> bloom intensity </td><td> <code>setBloomIntensity(float)</code> </td><td>2.0f </td><td> the resulting bloom value is multiplied by this intensity </td> class="row3"><td
</tr> class="col0 leftalign"> exposure cut-off</td><td
</table> class="col1"> <code>setExposureCutOff(float)</code></td><td
class="col2 leftalign">0.0f</td><td
<p> class="col3"> the threshold of color to bloom during extraction</td></tr><tr
class="row4"><td
You&#039;ll probably need to adjust those parameters depending on your scene. class="col0 leftalign"> bloom intensity</td><td
</p> class="col1"> <code>setBloomIntensity(float)</code></td><td
class="col2 leftalign">2.0f</td><td
</div> class="col3"> the resulting bloom value is multiplied by this intensity</td></tr></table></div><p> You&#039;ll probably need to adjust those parameters depending on your scene.</p></div><h1><a
name="bloom_with_a_glow_map">Bloom with a glow map</a></h1><div
<h1><a>Bloom with a glow map</a></h1> class="level1"><p> Sometimes, you want to have more control over what glows and does not glow.
<div> The bloom filter supports a glow map or a glow color.</p></div><h5><a
name="creating_a_glow-map">Creating a glow-map</a></h5><div
<p> class="level5"><p> Let&#039;s take the hover tank example bundled with JME3 test data.<br/> Here you can see the diffuse map of the tank, and the associated glow map that only contains the parts of the texture that will glow and their glowing color: <br/> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:tank_diffuse_ss.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
Sometimes, you want to have more control over what glows and does not glow. src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tank_diffuse_ss.png" class="media" title="Tank diffuse map" alt="Tank diffuse map" /></a> <a
The bloom filter supports a glow map or a glow color. href="/wiki/lib/exe/detail.php/jme3:advanced:tank_glow_map_ss.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tank_glow_map_ss.png" class="media" title="Tank glow map" alt="Tank glow map" /></a></p><p> Glow maps works with Lighting.j3md, Particles.j3md and SolidColor.j3md material definitions.
The tank material looks like that :</p><pre>Material My Material : Common/MatDefs/Light/Lighting.j3md {
</div>
<h5><a>Creating a glow-map</a></h5>
<div>
<p>
Let&#039;s take the hover tank example bundled with JME3 test data.<br/>
Here you can see the diffuse map of the tank, and the associated glow map that only contains the parts of the texture that will glow and their glowing color: <br/>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tank_diffuse_ss.png">
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tank_glow_map_ss.png">
</p>
<p>
Glow maps works with Lighting.j3md, Particles.j3md and SolidColor.j3md material definitions.
The tank material looks like that :
</p>
<pre>
Material My Material : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters { MaterialParameters {
SpecularMap : Models/HoverTank/tank_specular.png SpecularMap : Models/HoverTank/tank_specular.png
Shininess : 8 Shininess : 8
@ -102,194 +67,77 @@ Material My Material : Common/MatDefs/Light/Lighting.j3md {
Diffuse : 1.0 1.0 1.0 1.0 Diffuse : 1.0 1.0 1.0 1.0
Specular : 1.0 1.0 1.0 1.0 Specular : 1.0 1.0 1.0 1.0
} }
} }</pre><p> The glow map is defined here : <strong>GlowMap : Models/HoverTank/tank_glow_map_highres.png</strong></p></div><h5><a
</pre> name="usage">Usage</a></h5><div
class="level5"><ol><li
<p> class="level1"><div
class="li"> Create a FilterPostProcessor</div></li><li
The glow map is defined here : <strong>GlowMap : Models/HoverTank/tank_glow_map_highres.png</strong> class="level1"><div
</p> class="li"> Create a BloomFilter with the GlowMode.Objects parameter</div></li><li
class="level1"><div
</div> class="li"> Add the filter to the processor</div></li><li
class="level1"><div
<h5><a>Usage</a></h5> class="li"> Add the processor to the viewPort</div></li></ol><pre> FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
<div>
<ol>
<li><div> Create a FilterPostProcessor</div>
</li>
<li><div> Create a BloomFilter with the GlowMode.Objects parameter</div>
</li>
<li><div> Add the filter to the processor</div>
</li>
<li><div> Add the processor to the viewPort</div>
</li>
</ol>
<pre>
FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
BloomFilter bf=new BloomFilter(BloomFilter.GlowMode.Objects); BloomFilter bf=new BloomFilter(BloomFilter.GlowMode.Objects);
fpp.addFilter(bf); fpp.addFilter(bf);
viewPort.addProcessor(fpp); viewPort.addProcessor(fpp);</pre><p> Here is the result : <br/> <a
</pre> href="/wiki/lib/exe/detail.php/jme3:advanced:tanlglow1.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tanlglow1.png" class="media" title="Glowing hover tank" alt="Glowing hover tank" /></a></p></div><h1><a
<p> name="bloom_with_a_glow_color">Bloom with a glow color</a></h1><div
Here is the result : <br/> class="level1"><p> Sometimes you need an entire object to glow, not just parts of it.
In this case you&#039;ll need to use the glow color parameter.</p></div><h5><a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/tanlglow1.png"> name="usage1">Usage</a></h5><div
</p> class="level5"><ol><li
class="level1"><div
</div> class="li"> Create a material for your object and set the GlowColor parameter</div></li><li
class="level1"><div
<h1><a>Bloom with a glow color</a></h1> class="li"> Create a FilterPostProcessor</div></li><li
<div> class="level1"><div
class="li"> Create a BloomFilter with the GlowMode.Objects parameter</div></li><li
<p> class="level1"><div
class="li"> Add the filter to the processor</div></li><li
Sometimes you need an entire object to glow, not just parts of it. class="level1"><div
In this case you&#039;ll need to use the glow color parameter. class="li"> Add the processor to the viewPort</div></li></ol><pre> Material mat = new Material(getAssetManager(), &quot;Common/MatDefs/Misc/SolidColor.j3md&quot;);
</p>
</div>
<h5><a>Usage</a></h5>
<div>
<ol>
<li><div> Create a material for your object and set the GlowColor parameter</div>
</li>
<li><div> Create a FilterPostProcessor</div>
</li>
<li><div> Create a BloomFilter with the GlowMode.Objects parameter</div>
</li>
<li><div> Add the filter to the processor</div>
</li>
<li><div> Add the processor to the viewPort</div>
</li>
</ol>
<pre>
Material mat = new Material(getAssetManager(), &quot;Common/MatDefs/Misc/SolidColor.j3md&quot;);
mat.setColor(&quot;Color&quot;, ColorRGBA.Green); mat.setColor(&quot;Color&quot;, ColorRGBA.Green);
mat.setColor(&quot;GlowColor&quot;, ColorRGBA.Green); mat.setColor(&quot;GlowColor&quot;, ColorRGBA.Green);
fpp=new FilterPostProcessor(assetManager); fpp=new FilterPostProcessor(assetManager);
bloom= new BloomFilter(BloomFilter.GlowMode.Objects); bloom= new BloomFilter(BloomFilter.GlowMode.Objects);
fpp.addFilter(bloom); fpp.addFilter(bloom);
viewPort.addProcessor(fpp); viewPort.addProcessor(fpp);</pre><p> Here is the result on Oto&#039;s plasma ball (before and after) : <br/> <a
</pre> href="/wiki/lib/exe/detail.php/jme3:advanced:otonobloom.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/otonobloom.png?w=400" class="medialeft" align="left" title="Oto&#039;s plasma ball is just a big pea" alt="Oto&#039;s plasma ball is just a big pea" width="400" /></a> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:otoglow.png?id=jme3%3Aadvanced%3Abloom_and_glow"><img
Here is the result on Oto&#039;s plasma ball (before and after) : <br/> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/otoglow.png?w=400" class="medialeft" align="left" title="Oto&#039;s plasma ball radiates incredible power!!!" alt="Oto&#039;s plasma ball radiates incredible power!!!" width="400" /></a></p></div><h1><a
name="hints_and_tricks">Hints and tricks</a></h1><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/otonobloom.png"> class="level1"></div><h5><a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/otoglow.png"> name="increasing_the_blur_range_and_reducing_fps_cost">Increasing the blur range and reducing fps cost</a></h5><div
</p> class="level5"><p> The glow render is sampled on a texture that has the same dimensions as the viewport.
You can reduce the size of the bloom sampling just by using the setDownSamplingFactor method like this : <br/></p><pre> BloomFilter bloom=new BloomFilter&#40;&#41;;
</div> bloom.setDownSamplingFactor&#40;2.0f&#41;; </pre><p> In this example the sampling size is divided by 4 (width/2,height/2), resulting in less work to blur the scene.
The resulting texture is then up sampled to the screen size using hardware bilinear filtering. this results in a wider blur range.</p></div><h5><a
<h1><a>Hints and tricks</a></h1> name="using_classic_bloom_combined_with_a_glow_map">Using classic bloom combined with a glow map</a></h5><div
<div> class="level5"><p> let&#039;s say you want a global bloom on your scene, but you have also a glowing object on it.
You can use only one bloom filter for both effects like that</p><pre>BloomFilter bloom=new BloomFilter&#40;BloomFilter.GlowMode.SceneAndObjects&#41;;</pre><p> However, note that both effects will share the same values of attribute, and sometimes, it won&#039;t be what you need.</p></div><h5><a
</div> name="making_your_home_brewed_material_definition_support_glow">Making your home brewed material definition support Glow</a></h5><div
class="level5"><p> Let&#039;s say you have made a custom material on your own, and that you want it to support glow maps and glow color.
<h5><a>Increasing the blur range and reducing fps cost</a></h5> In your material definition you need to add those lines in the MaterialParameters section :</p><pre> MaterialParameters {
<div>
<p>
The glow render is sampled on a texture that has the same dimensions as the viewport.
You can reduce the size of the bloom sampling just by using the setDownSamplingFactor method like this : <br/>
</p>
<pre> BloomFilter bloom=new BloomFilter&#40;&#41;;
bloom.setDownSamplingFactor&#40;2.0f&#41;;</pre>
<p>
In this example the sampling size is divided by 4 (width/2,height/2), resulting in less work to blur the scene.
The resulting texture is then up sampled to the screen size using hardware bilinear filtering. this results in a wider blur range.
</p>
</div>
<h5><a>Using classic bloom combined with a glow map</a></h5>
<div>
<p>
let&#039;s say you want a global bloom on your scene, but you have also a glowing object on it.
You can use only one bloom filter for both effects like that
</p>
<pre>BloomFilter bloom=new BloomFilter&#40;BloomFilter.GlowMode.SceneAndObjects&#41;;</pre>
<p>
However, note that both effects will share the same values of attribute, and sometimes, it won&#039;t be what you need.
</p>
</div>
<h5><a>Making your home brewed material definition support Glow</a></h5>
<div>
<p>
Let&#039;s say you have made a custom material on your own, and that you want it to support glow maps and glow color.
In your material definition you need to add those lines in the MaterialParameters section :
</p>
<pre>
MaterialParameters {
.... ....
// Texture of the glowing parts of the material // Texture of the glowing parts of the material
Texture2D GlowMap Texture2D GlowMap
// The glow color of the object // The glow color of the object
Color GlowColor Color GlowColor
} }</pre><p> Then add the following technique :</p><pre> Technique Glow {
</pre>
<p>
Then add the following technique :
</p>
<pre>
Technique Glow {
LightMode SinglePass LightMode SinglePass
VertexShader GLSL100: Common/MatDefs/Misc/SimpleTextured.vert VertexShader GLSL100: Common/MatDefs/Misc/SimpleTextured.vert
FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag
WorldParameters { WorldParameters {
WorldViewProjectionMatrix WorldViewProjectionMatrix
} }
Defines { Defines {
HAS_GLOWMAP : GlowMap HAS_GLOWMAP : GlowMap
HAS_GLOWCOLOR : GlowColor HAS_GLOWCOLOR : GlowColor
} }
} }</pre><p> Then you can use this material with the BloomFilter</p></div><h5><a
</pre> name="make_a_glowing_object_stop_to_glow">Make a glowing object stop to glow</a></h5><div
class="level5"><p> If you are using a glow map, remove the texture from the material.</p><pre>material.clearTextureParam(&quot;GlowMap&quot;);</pre><p> If you are using a glow color, set it to black</p><pre>material.setColor(&quot;GlowColor&quot;,ColorRGBA.Black);</pre></div>
<p>
Then you can use this material with the BloomFilter
</p>
</div>
<h5><a>Make a glowing object stop to glow</a></h5>
<div>
<p>
If you are using a glow map, remove the texture from the material.
</p>
<pre>
material.clearTextureParam(&quot;GlowMap&quot;);
</pre>
<p>
If you are using a glow color, set it to black
</p>
<pre>
material.setColor(&quot;GlowColor&quot;,ColorRGBA.Black);
</pre>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:bloom_and_glow?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:bloom_and_glow?do=export_xhtmlbody">view online version</a></em></p>

@ -1,172 +1,132 @@
<h1><a
<h1><a>The jME3 Camera</a></h1> name="the_jme3_camera">The jME3 Camera</a></h1><div
<div> class="level1"></div><h2><a
name="default_camera">Default Camera</a></h2><div
</div> class="level2"><p> The default com.jme3.renderer.Camera object is <code>cam</code> in com.jme3.app.Application.</p><p> The camera object is created with the following defaults:</p><ul><li
class="level1"><div
<h2><a>Default Camera</a></h2> class="li"> Width and height are set to the current Application&#039;s settings.getWidth() and settings.getHeight() values.</div></li><li
<div> class="level1"><div
class="li"> Frustum Perspective:</div><ul><li
<p> class="level2"><div
class="li"> Frame of view angle of 45° along the Y axis</div></li><li
The default com.jme3.renderer.Camera object is <code>cam</code> in com.jme3.app.Application. class="level2"><div
</p> class="li"> Aspect ratio of width divided by height</div></li><li
class="level2"><div
<p> class="li"> Near view plane of 1 wu</div></li><li
The camera object is created with the following defaults: class="level2"><div
</p> class="li"> Far view plane of 1000 wu</div></li></ul></li><li
<ul> class="level1"><div
<li><div> Width and height are set to the current Application&#039;s settings.getWidth() and settings.getHeight() values. </div> class="li"> Start location at (0f, 0f, 10f).</div></li><li
</li> class="level1"><div
<li><div> Frustum Perspective:</div> class="li"> Start direction is looking at the origin.</div></li></ul><div
<ul> class="table sectionedit1"><table
<li><div> Frame of view angle of 45° along the Y axis</div> class="inline"><tr
</li> class="row0"><th
<li><div> Aspect ratio of width divided by height</div> class="col0">Method</th><th
</li> class="col1">Usage</th></tr><tr
<li><div> Near view plane of 1 wu</div> class="row1"><td
</li> class="col0">cam.getLocation(), setLocation()</td><td
<li><div> Far view plane of 1000 wu</div> class="col1">The camera position</td></tr><tr
</li> class="row2"><td
</ul> class="col0">cam.getRotation(), setRotation()</td><td
</li> class="col1">The camera rotation</td></tr><tr
<li><div> Start location at (0f, 0f, 10f).</div> class="row3"><td
</li> class="col0">cam.getLeft(), setLeft()</td><td
<li><div> Start direction is looking at the origin.</div> class="col1">The left axis of the camera</td></tr><tr
</li> class="row4"><td
</ul> class="col0">cam.getUp(), setUp()</td><td
<table> class="col1">The up axis of the camera, usually Vector3f(0,1,0)</td></tr><tr
<tr> class="row5"><td
<th>Method</th><th>Usage</th> class="col0">cam.getDirection(), setDirection()</td><td
</tr> class="col1">The vector the camera is facing</td></tr><tr
<tr> class="row6"><td
<td>cam.getLocation(), setLocation()</td><td>The camera position</td> class="col0">cam.getAxes(), setAxes(left,up,dir)</td><td
</tr> class="col1">One accessor for the three properties left/up/direction.</td></tr><tr
<tr> class="row7"><td
<td>cam.getRotation(), setRotation()</td><td>The camera rotation</td> class="col0">cam.getFrame(), setFrame(loc,left,up,dir)</td><td
</tr> class="col1">One accessor for the four properties location/left/up/direction.</td></tr><tr
<tr> class="row8"><td
<td>cam.getLeft(), setLeft()</td><td>The left axis of the camera</td> class="col0">cam.resize(width, height, fixAspect)</td><td
</tr> class="col1">Resize an existing camera object while keeping all other settings. Set fixAspect to true to adjust the aspect ratio (?)</td></tr><tr
<tr> class="row9"><td
<td>cam.getUp(), setUp()</td><td>The up axis of the camera, usually Vector3f(0,1,0)</td> class="col0">cam.setFrustum( near, far, left, right, top, bottom )</td><td
</tr> class="col1">The frustrum is defined by the near/far plane, left/rught plane, top/bottom plane (all distances as float values)</td></tr><tr
<tr> class="row10"><td
<td>cam.getDirection(), setDirection()</td><td>The vector the camera is facing</td> class="col0">cam.setFrustumPerspective( fovY, aspect ratio, near, far)</td><td
</tr> class="col1">The frustrum is defined by view angle along the Y axis (in degrees), aspect ratio, and the near/far plane.</td></tr><tr
<tr> class="row11"><td
<td>cam.getAxes(), setAxes(left,up,dir)</td><td>One accessor for the three properties left/up/direction.</td> class="col0">cam.lookAt(target,up)</td><td
</tr> class="col1">Turn the camera to look at Coordinate target, and rotate it around the up axis.</td></tr><tr
<tr> class="row12"><td
<td>cam.getFrame(), setFrame(loc,left,up,dir)</td><td>One accessor for the four properties location/left/up/direction.</td> class="col0">cam.setParallelProjection(false)</td><td
</tr> class="col1">Normal perspective</td></tr><tr
<tr> class="row13"><td
<td>cam.resize(width, height, fixAspect)</td><td>Resize an existing camera object while keeping all other settings. Set fixAspect to true to adjust the aspect ratio (?)</td> class="col0">cam.setParallelProjection(true)</td><td
</tr> class="col1">Parallel projection perspective</td></tr><tr
<tr> class="row14"><td
<td>cam.setFrustum( near, far, left, right, top, bottom )</td><td>The frustrum is defined by the near/far plane, left/rught plane, top/bottom plane (all distances as float values)</td> class="col0">cam.getScreenCoordinates()</td><td
</tr> class="col1">?</td></tr></table></div><p> <strong>Tip:</strong> After you change view port, frustrum, or frame, call <code>cam.update();</code></p></div><h2><a
<tr> name="flyby_camera">FlyBy Camera</a></h2><div
<td>cam.setFrustumPerspective( fovY, aspect ratio, near, far)</td><td>The frustrum is defined by view angle along the Y axis (in degrees), aspect ratio, and the near/far plane.</td> class="level2"><p> The flyby camera is an extension of the default camera in com.jme3.app.SimpleApplication. It is preconfigured to respond to the WASD keys for walking forwards and backwards, and for strafing to the sides. Move the mouse to rotate the camera, scroll the mouse wheel for zooming in or out. The QZ keys raise or lower the camera.</p><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td>cam.lookAt(target,up)</td><td>Turn the camera to look at Coordinate target, and rotate it around the up axis.</td> class="row0"><th
</tr> class="col0">Method</th><th
<tr> class="col1">Usage</th></tr><tr
<td>cam.setParallelProjection(false)</td><td>Normal perspective</td> class="row1"><td
</tr> class="col0">flyCam.setEnabled(true);</td><td
<tr> class="col1">Activate the flyby cam</td></tr><tr
<td>cam.setParallelProjection(true)</td><td>Parallel projection perspective</td> class="row2"><td
</tr> class="col0">flyCam.setMoveSpeed(10);</td><td
<tr> class="col1">Control the move speed</td></tr><tr
<td>cam.getScreenCoordinates()</td><td>?</td> class="row3"><td
</tr> class="col0">flyCam.setRotationSpeed(10);</td><td
</table> class="col1">Control the rotation speed</td></tr><tr
class="row4"><td
<p> class="col0">flyCam.setDragToRotate(true)</td><td
<strong>Tip:</strong> After you change view port, frustrum, or frame, call <code>cam.update();</code> class="col1">Must keep mouse button pressed to rotate camera. Used e.g. for Applets. if false, all mouse movement will be captured and interpreted as rotations.</td></tr></table></div></div><h2><a
</p> name="chase_camera">Chase Camera</a></h2><div
class="level2"><p> jME3 also supports a Chase Cam that can follow a moving target Spatial (<code>com.jme3.input.ChaseCamera</code>). Click and hold the mouse button to rotate around the target.</p><pre>flyCam.setEnabled&#40;false&#41;;
</div> ChaseCamera chaseCam = new ChaseCamera&#40;cam, target, inputManager&#41;;</pre><div
class="table sectionedit3"><table
<h2><a>FlyBy Camera</a></h2> class="inline"><tr
<div> class="row0"><th
class="col0">Method</th><th
<p> class="col1">Usage</th></tr><tr
class="row1"><td
The flyby camera is an extension of the default camera in com.jme3.app.SimpleApplication. It is preconfigured to respond to the WASD keys for walking forwards and backwards, and for strafing to the sides. Move the mouse to rotate the camera, scroll the mouse wheel for zooming in or out. The QZ keys raise or lower the camera. class="col0">chaseCam.setSmoothMotion(true);</td><td
class="col1">Interpolates a smoother acceleration/deceleration when the camera moves.</td></tr><tr
</p> class="row2"><td
<table> class="col0">chaseCam.setChasingSensitivity(5f)</td><td
<tr> class="col1">The lower the chasing sensitivity, the slower the camera will follow the target when it moves.</td></tr><tr
<th>Method</th><th>Usage</th> class="row3"><td
</tr> class="col0">chaseCam.setTrailingSensitivity(0.5f)</td><td
<tr> class="col1">The lower the traling sensitivity, the slower the camera will begin to go after the target when it moves. Default is 0.5;</td></tr><tr
<td>flyCam.setEnabled(true);</td><td>Activate the flyby cam</td> class="row4"><td
</tr> class="col0">chaseCam.setRotationSensitivity(5f)</td><td
<tr> class="col1">The lower the sensitivity, the slower the camera will rotate around the target when the mosue is dragged. Default is 5.</td></tr><tr
<td>flyCam.setMoveSpeed(10);</td><td>Control the move speed</td> class="row5"><td
</tr> class="col0">chaseCam.setTrailingRotationInertia(0.1f)</td><td
<tr> class="col1">This prevents the camera to stop too abruptly when the target stops rotating before the camera has reached the target&#039;s trailing position. Default is 0.1f.</td></tr><tr
<td>flyCam.setRotationSpeed(10);</td><td>Control the rotation speed</td> class="row6"><td
</tr> class="col0">chaseCam.setDefaultDistance(40);</td><td
<tr> class="col1">The default distance to the target at the start of the application.</td></tr><tr
<td>flyCam.setDragToRotate(true)</td><td>Must keep mouse button pressed to rotate camera. Used e.g. for Applets. if false, all mouse movement will be captured and interpreted as rotations.</td> class="row7"><td
</tr> class="col0">chaseCam.setMaxDistance(40);</td><td
</table> class="col1">The maximum zoom distance. Default is 40f.</td></tr><tr
class="row8"><td
</div> class="col0">chaseCam.setMinDistance(1);</td><td
class="col1">The minimum zoom distance. Default is 1f.</td></tr><tr
<h2><a>Chase Camera</a></h2> class="row9"><td
<div> class="col0">chaseCam.setMinVerticalRotation(-FastMath.PI/2);</td><td
class="col1">The minimal vertical rotation angle of the camera around the target. Default is 0.</td></tr><tr
<p> class="row10"><td
class="col0">chaseCam.setDefaultVerticalRotation(-FastMath.PI/2);</td><td
jME3 also supports a Chase Cam that can follow a moving target Spatial (<code>com.jme3.input.ChaseCamera</code>). Click and hold the mouse button to rotate around the target. class="col1">The default vertical rotation angle of the camera around the target at the start of the application.</td></tr><tr
</p> class="row11"><td
<pre>flyCam.setEnabled&#40;false&#41;; class="col0">chaseCam.setDefaultHorizontalRotation(-FastMath.PI/2);</td><td
ChaseCamera chaseCam = new ChaseCamera&#40;cam, target, inputManager&#41;;</pre><table> class="col1">The default horizontal rotation angle of the camera around the target at the start of the application.</td></tr></table></div><div
<tr> class="tags"><span> <a
<th>Method</th><th>Usage</th> href="/wiki/doku.php/tag:camera?do=showtag&amp;tag=tag%3Acamera">camera</a>, <a
</tr> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
<tr>
<td>chaseCam.setSmoothMotion(true);</td><td>Interpolates a smoother acceleration/deceleration when the camera moves.</td>
</tr>
<tr>
<td>chaseCam.setChasingSensitivity(5f)</td><td>The lower the chasing sensitivity, the slower the camera will follow the target when it moves.</td>
</tr>
<tr>
<td>chaseCam.setTrailingSensitivity(0.5f)</td><td>The lower the traling sensitivity, the slower the camera will begin to go after the target when it moves. Default is 0.5;</td>
</tr>
<tr>
<td>chaseCam.setRotationSensitivity(5f)</td><td>The lower the sensitivity, the slower the camera will rotate around the target when the mosue is dragged. Default is 5.</td>
</tr>
<tr>
<td>chaseCam.setTrailingRotationInertia(0.1f)</td><td>This prevents the camera to stop too abruptly when the target stops rotating before the camera has reached the target&#039;s trailing position. Default is 0.1f.</td>
</tr>
<tr>
<td>chaseCam.setDefaultDistance(40);</td><td>The default distance to the target at the start of the application.</td>
</tr>
<tr>
<td>chaseCam.setMaxDistance(40);</td><td>The maximum zoom distance. Default is 40f.</td>
</tr>
<tr>
<td>chaseCam.setMinDistance(1);</td><td>The minimum zoom distance. Default is 1f.</td>
</tr>
<tr>
<td>chaseCam.setMinVerticalRotation(-FastMath.PI/2);</td><td>The minimal vertical rotation angle of the camera around the target. Default is 0.</td>
</tr>
<tr>
<td>chaseCam.setDefaultVerticalRotation(-FastMath.PI/2);</td><td>The default vertical rotation angle of the camera around the target at the start of the application.</td>
</tr>
<tr>
<td>chaseCam.setDefaultHorizontalRotation(-FastMath.PI/2);</td><td>The default horizontal rotation angle of the camera around the target at the start of the application.</td>
</tr>
</table>
<div><span>
<a href="/wiki/doku.php/tag:camera?do=showtag&amp;tag=tag%3Acamera">camera</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:camera?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:camera?do=export_xhtmlbody">view online version</a></em></p>

@ -1,184 +1,128 @@
<h1><a
<h1><a>jME3 Cinematics</a></h1> name="jme3_cinematics">jME3 Cinematics</a></h1><div
<div> class="level1"><p> JME3 cinematics (com.jme.cinematic) allow you to remote control nodes and cameras in a 3D game. You use cinematics to script and record scenes. Use it for example to create <a
href="http://en.wikipedia.org/wiki/Cutscene">cutscenes</a> of your game.</p><p> Cinematics are implemented as AppStates. Attach the scene that you want to be visible in the cinematic to one Node. You create a Cinematic object, and add individual CinematicEvents to it.</p></div><h2><a
<p> name="overview">Overview</a></h2><div
class="level2"><pre>Cinematic cinematic = new Cinematic&#40;sceneNode, duration&#41;;
JME3 cinematics (com.jme.cinematic) allow you to remote control nodes and cameras in a 3D game. You use cinematics to script and record scenes. Use it for example to create <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/Cutscene"><param name="text" value="<html><u>cutscenes</u></html>"><param name="textColor" value="blue"></object> of your game. cinematic.addCinematicEvent&#40;triggerTime, cinematicEvent&#41;;</pre><ol><li
</p> class="level1"><div
class="li"> Create one Cinematic per scene.</div><ul><li
<p> class="level2"><div
Cinematics are implemented as AppStates. Attach the scene that you want to be visible in the cinematic to one Node. You create a Cinematic object, and add individual CinematicEvents to it. class="li"> sceneNode is the node containing the scene</div></li><li
</p> class="level2"><div
class="li"> duration is the duration of the cinematic scene in seconds</div></li></ul></li><li
</div> class="level1"><div
class="li"> Create CinematicEvents to script your &quot;movie&quot;. Each Cinematic is a set of CinematicEvents, that are triggered at a given time.</div><ul><li
<h2><a>Overview</a></h2> class="level2"><div
<div> class="li"> cinematicEvent is the cinematic event. More details below.</div></li><li
<pre>Cinematic cinematic = new Cinematic&#40;sceneNode, duration&#41;; class="level2"><div
cinematic.addCinematicEvent&#40;triggerTime, cinematicEvent&#41;;</pre><ol> class="li"> triggerTime is the time when this particular cinematic event starts. Specify the start time in seconds since the beginning of the scene.</div></li></ul></li><li
<li><div> Create one Cinematic per scene.</div> class="level1"><div
<ul> class="li"> Play and pause the Cinematic using <code>cinematic.pause()</code> and <code>cinematic.play();</code></div></li></ol></div><h2><a
<li><div> sceneNode is the node containing the scene</div> name="cinematicevents">CinematicEvents</a></h2><div
</li> class="level2"><p> There are several kinds of cinematic events:</p><div
<li><div> duration is the duration of the cinematic scene in seconds</div> class="table sectionedit1"><table
</li> class="inline"><tr
</ul> class="row0"><th
</li> class="col0">CinematicEvent</th><th
<li><div> Create CinematicEvents to script your “movie”. Each Cinematic is a set of CinematicEvents, that are triggered at a given time. </div> class="col1">Description</th></tr><tr
<ul> class="row1"><td
<li><div> cinematicEvent is the cinematic event. More details below.</div> class="col0">MotionTrack</td><td
</li> class="col1">Use this to move a Spatial non-linearly over time. A motionPath is a list of several waypoints added to a MotionPath. The path is interpolated using Catmull-Rom Splines between waypoints.</td></tr><tr
<li><div> triggerTime is the time when this particular cinematic event starts. Specify the start time in seconds since the beginning of the scene.</div> class="row2"><td
</li> class="col0">PositionTrack</td><td
</ul> class="col1">Use this to move a Spatial linearly over time. It translates the Spatial to a destination in the given amount of time by linearly interpolating the positions.</td></tr><tr
</li> class="row3"><td
<li><div> Play and pause the Cinematic using <code>cinematic.pause()</code> and <code>cinematic.play();</code></div> class="col0">RotationTrack</td><td
</li> class="col1">Use this to change the rotation of a Spatial over time. It rotates the Spatial in the given amount of time by linearly interpolating the rotation.</td></tr><tr
</ol> class="row4"><td
class="col0">ScaleTrack</td><td
</div> class="col1">Use this to change the size of a Spatial over time. It scales the Spatial in the given amount of time by linearly interpolating the scale.</td></tr><tr
class="row5"><td
<h2><a>CinematicEvents</a></h2> class="col0">SoundTrack</td><td
<div> class="col1">Use this to play a sound at a given time for the given duration.</td></tr><tr
class="row6"><td
<p> class="col0">GuiTrack</td><td
class="col1">Displays a <a
There are several kinds of cinematic events: href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a> at a given time for the given duration. Use it to display subtitles or HUD elements. Bind the Nifty <acronym
title="Graphical User Interface">GUI</acronym> <acronym
</p> title="Extensible Markup Language">XML</acronym> to the cinematic using <code>cinematic.bindUi(&quot;path/to/nifty/file.xml&quot;);</code></td></tr><tr
<table> class="row7"><td
<tr> class="col0">AnimationTrack</td><td
<th>CinematicEvent</th><th>Description</th> class="col1">Use this to start playing a model animation at a given time (a character walking animation for example)</td></tr></table></div><p> We will add more types of track implementions over time.</p><p> Each CinematicEvent supports the following methods to control the event.</p><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td>MotionTrack</td><td>Use this to move a Spatial non-linearly over time. A motionPath is a list of several waypoints added to a MotionPath. The path is interpolated using Catmull-Rom Splines between waypoints.</td> class="row0"><th
</tr> class="col0">CinematicEvent method</th><th
<tr> class="col1">Usage</th></tr><tr
<td>PositionTrack</td><td>Use this to move a Spatial linearly over time. It translates the Spatial to a destination in the given amount of time by linearly interpolating the positions.</td> class="row1"><td
</tr> class="col0">play()</td><td
<tr> class="col1">Starts playing the cinematic.</td></tr><tr
<td>RotationTrack</td><td>Use this to change the rotation of a Spatial over time. It rotates the Spatial in the given amount of time by linearly interpolating the rotation.</td> class="row2"><td
</tr> class="col0">stop()</td><td
<tr> class="col1">Stops playing the cinematic.</td></tr><tr
<td>ScaleTrack</td><td>Use this to change the size of a Spatial over time. It scales the Spatial in the given amount of time by linearly interpolating the scale.</td> class="row3"><td
</tr> class="col0">pause()</td><td
<tr> class="col1">Pauses the cinematic.</td></tr></table></div><p> Those methods, must be called on the Cinematic and are propagated to the events. Don&#039;t use them directly on a sub cinematic event</p></div><h3><a
<td>SoundTrack</td><td>Use this to play a sound at a given time for the given duration.</td> name="motiontrack_motionpath">MotionTrack &amp; MotionPath</a></h3><div
</tr> class="level3"><p> A motion track is made up of MotionPaths.</p><pre>MotionPath path = new MotionPath&#40;&#41;;</pre><div
<tr> class="table sectionedit3"><table
<td>GuiTrack</td><td>Displays a <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a> at a given time for the given duration. Use it to display subtitles or HUD elements. Bind the Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> to the cinematic using <code>cinematic.bindUi(“path/to/nifty/file.xml”);</code></td> class="inline"><tr
</tr> class="row0"><th
<tr> class="col0"> MotionPath Method</th><th
<td>AnimationTrack</td><td>Use this to start playing a model animation at a given time (a character walking animation for example)</td> class="col1"> Usage</th></tr><tr
</tr> class="row1"><td
</table> class="col0">setCycle(true)</td><td
class="col1">Sets whether the motion along this path should be closed (true) or not (false).</td></tr><tr
<p> class="row2"><td
class="col0">addWayPoint(vector)</td><td
We will add more types of track implementions over time. class="col1">Adds individual waypoints to this path. The order is relevant.</td></tr><tr
</p> class="row3"><td
class="col0">removeWayPoint(vector) <br/> removeWayPoint(index)</td><td
<p> class="col1">Removes individual waypoints from this path. You can specify a vector or the integer index.</td></tr><tr
Each CinematicEvent supports the following methods to control the event. class="row4"><td
class="col0">setCurveTension(0.83f)</td><td
</p> class="col1">Sets the tension of the curve (only for Catmull Rom Spline). A value of 0.0f will give a straight linear line, 1.0 a round curve.</td></tr><tr
<table> class="row5"><td
<tr> class="col0">enableDebugShape(assetManager,rootNode)</td><td
<th>CinematicEvent method</th><th>Usage</th> class="col1">Shows a line to visualize the path. Used for debugging.</td></tr><tr
</tr> class="row6"><td
<tr> class="col0">disableDebugShape()</td><td
<td>play()</td><td>Starts playing the cinematic.</td> class="col1">Hides the line that visualizes the path. Used for debugging.</td></tr><tr
</tr> class="row7"><td
<tr> class="col0">getNbWayPoints()</td><td
<td>stop()</td><td>Stops playing the cinematic.</td> class="col1">Returns the number of waypoints in this path.</td></tr></table></div><pre>MotionTrack thingMotionControl = new MotionTrack&#40;thingNode, path&#41;;</pre><div
</tr> class="table sectionedit4"><table
<tr> class="inline"><tr
<td>pause()</td><td>Pauses the cinematic.</td> class="row0"><th
</tr> class="col0">MotionTrack method</th><th
</table> class="col1">Usage</th></tr><tr
class="row1"><td
<p> class="col0">setLoopMode(LoopMode.Loop)</td><td
class="col1">Sets whether the animation along this path should loop (true) or play only once (false).</td></tr><tr
Those methods, must be called on the Cinematic and are propagated to the events. Don&#039;t use them directly on a sub cinematic event class="row2"><td
</p> class="col0">setDirectionType(MotionTrack.Direction.None)</td><td
class="col1">Sets the direction behavior type of the controled node. Direction.None deactivates this feature. See the following options:</td></tr><tr
</div> class="row3"><td
class="col0">setDirectionType(MotionTrack.Direction.LookAt)</td><td
<h3><a>MotionTrack &amp; MotionPath</a></h3> class="col1">Rotate to keep facing a point. Specify the point with setLookAt().</td></tr><tr
<div> class="row4"><td
class="col0">setDirectionType(MotionTrack.Direction.Path)</td><td
<p> class="col1">Face the direction of the path.</td></tr><tr
class="row5"><td
A motion track is made up of MotionPaths. class="col0">setDirectionType(MotionTrack.Direction.PathAndRotation)</td><td
</p> class="col1">Face the direction of the path, plus an added rotation. Use together with the setRotation() method.</td></tr><tr
<pre>MotionPath path = new MotionPath&#40;&#41;;</pre><table> class="row6"><td
<tr> class="col0">setDirectionType(MotionTrack.Direction.Rotation)</td><td
<th> MotionPath Method </th><th> Usage </th> class="col1">Rotate while moving. Use together with the setRotation() method.</td></tr><tr
</tr> class="row7"><td
<tr> class="col0">setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y)</td><td
<td>setCycle(true)</td><td>Sets whether the motion along this path should be closed (true) or not (false). </td> class="col1">Optional: Make the moving face towards a certain location. Use together with setDirectionType().</td></tr><tr
</tr> class="row8"><td
<tr> class="col0">setRotation(quaternion)</td><td
<td>addWayPoint(vector)</td><td>Adds individual waypoints to this path. The order is relevant.</td> class="col1">Optional: Sets the rotation. Use together with MotionTrack.Direction.Rotation or MotionTrack.Direction.PathAndRotation.</td></tr></table></div></div><h3><a
</tr> name="motionpathlistener">MotionPathListener</a></h3><div
<tr> class="level3"><p> You can register a MotionPathListener to the MotionPath to track whether waypoints have been reached, and then trigger a custom action. In this example we just print the status. The onWayPointReach() method of the interface gives you access to the MotionTrack object <code>control</code>, and an integer value representing the current wayPointIndex.</p><pre>path.addListener&#40; new MotionPathListener&#40;&#41; &#123;
<td>removeWayPoint(vector) <br/>
removeWayPoint(index)</td><td>Removes individual waypoints from this path. You can specify a vector or the integer index.</td>
</tr>
<tr>
<td>setCurveTension(0.83f)</td><td>Sets the tension of the curve (only for Catmull Rom Spline). A value of 0.0f will give a straight linear line, 1.0 a round curve.</td>
</tr>
<tr>
<td>enableDebugShape(assetManager,rootNode)</td><td>Shows a line to visualize the path. Used for debugging.</td>
</tr>
<tr>
<td>disableDebugShape()</td><td>Hides the line that visualizes the path. Used for debugging.</td>
</tr>
<tr>
<td>getNbWayPoints()</td><td>Returns the number of waypoints in this path.</td>
</tr>
</table>
<pre>MotionTrack thingMotionControl = new MotionTrack&#40;thingNode, path&#41;;</pre><table>
<tr>
<th>MotionTrack method</th><th>Usage</th>
</tr>
<tr>
<td>setLoopMode(LoopMode.Loop)</td><td>Sets whether the animation along this path should loop (true) or play only once (false).</td>
</tr>
<tr>
<td>setDirectionType(MotionTrack.Direction.None)</td><td>Sets the direction behavior type of the controled node. Direction.None deactivates this feature. See the following options:</td>
</tr>
<tr>
<td>setDirectionType(MotionTrack.Direction.LookAt)</td><td>Rotate to keep facing a point. Specify the point with setLookAt().</td>
</tr>
<tr>
<td>setDirectionType(MotionTrack.Direction.Path)</td><td>Face the direction of the path.</td>
</tr>
<tr>
<td>setDirectionType(MotionTrack.Direction.PathAndRotation)</td><td>Face the direction of the path, plus an added rotation. Use together with the setRotation() method.</td>
</tr>
<tr>
<td>setDirectionType(MotionTrack.Direction.Rotation)</td><td>Rotate while moving. Use together with the setRotation() method.</td>
</tr>
<tr>
<td>setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y)</td><td>Optional: Make the moving face towards a certain location. Use together with setDirectionType().</td>
</tr>
<tr>
<td>setRotation(quaternion)</td><td>Optional: Sets the rotation. Use together with MotionTrack.Direction.Rotation or MotionTrack.Direction.PathAndRotation.</td>
</tr>
</table>
</div>
<h3><a>MotionPathListener</a></h3>
<div>
<p>
You can register a MotionPathListener to the MotionPath to track whether waypoints have been reached, and then trigger a custom action. In this example we just print the status. The onWayPointReach() method of the interface gives you access to the MotionTrack object <code>control</code>, and an integer value representing the current wayPointIndex.
</p>
<pre>path.addListener&#40; new MotionPathListener&#40;&#41; &#123;
public void onWayPointReach&#40;MotionTrack control, int wayPointIndex&#41; &#123; public void onWayPointReach&#40;MotionTrack control, int wayPointIndex&#41; &#123;
if &#40;path.getNbWayPoints&#40;&#41; == wayPointIndex + 1&#41; &#123; if &#40;path.getNbWayPoints&#40;&#41; == wayPointIndex + 1&#41; &#123;
println&#40;control.getSpatial&#40;&#41;.getName&#40;&#41; + &quot;Finished!!! &quot;&#41;; println&#40;control.getSpatial&#40;&#41;.getName&#40;&#41; + &quot;Finished!!! &quot;&#41;;
@ -186,175 +130,88 @@ You can register a MotionPathListener to the MotionPath to track whether waypoin
println&#40;control.getSpatial&#40;&#41;.getName&#40;&#41; + &quot; Reached way point &quot; + wayPointIndex&#41;; println&#40;control.getSpatial&#40;&#41;.getName&#40;&#41; + &quot; Reached way point &quot; + wayPointIndex&#41;;
&#125; &#125;
&#125; &#125;
&#125;&#41;;</pre> &#125;&#41;;</pre></div><h3><a
</div> name="positiontrack">PositionTrack</a></h3><div
class="level3"><pre>PositionTrack thingPositionControl = new PositionTrack&#40;
<h3><a>PositionTrack</a></h3> thingNode, endPosition, duration, loopMode&#41;;</pre><p> Details of the constructor:</p><ul><li
<div> class="level1"><div
<pre>PositionTrack thingPositionControl = new PositionTrack&#40; class="li"> thingNode is the Spatial to be moved.</div></li><li
thingNode, endPosition, duration, loopMode&#41;;</pre> class="level1"><div
<p> class="li"> endPosition is the target location as Vector3f.</div></li><li
Details of the constructor: class="level1"><div
</p> class="li"> duration is the time that it should take from start to end point.</div></li><li
<ul> class="level1"><div
<li><div> thingNode is the Spatial to be moved.</div> class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul><p> The start location is always the current location of the Spatial.</p></div><h3><a
</li> name="rotationtrack">RotationTrack</a></h3><div
<li><div> endPosition is the target location as Vector3f. </div> class="level3"><pre>RotationTrack thingRotationControl = new RotationTrack&#40;
</li> thingNode, endRotation, duration, loopMode&#41;;</pre><p> Details of the constructor:</p><ul><li
<li><div> duration is the time that it should take from start to end point.</div> class="level1"><div
</li> class="li"> thingNode is the Spatial to be rotated.</div></li><li
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div> class="level1"><div
</li> class="li"> endRotation is the target rotation in Quaternion format.</div></li><li
</ul> class="level1"><div
class="li"> duration is the time that it should take from start to target rotation.</div></li><li
<p> class="level1"><div
class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul></div><h3><a
The start location is always the current location of the Spatial. name="scaletrack">ScaleTrack</a></h3><div
</p> class="level3"><pre>ScaleTrack thingScaleControl = new ScaleTrack&#40;
thingNode, endScale, duration, loopMode&#41;;</pre><p> Details of the constructor:</p><ul><li
</div> class="level1"><div
class="li"> thingNode is the Spatial to be resized.</div></li><li
<h3><a>RotationTrack</a></h3> class="level1"><div
<div> class="li"> endScale is the target Scale in Vector3f format.</div></li><li
<pre>RotationTrack thingRotationControl = new RotationTrack&#40; class="level1"><div
thingNode, endRotation, duration, loopMode&#41;;</pre> class="li"> duration is the time that it should take from start to target scale.</div></li><li
<p> class="level1"><div
Details of the constructor: class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul></div><h3><a
</p> name="soundtrack">SoundTrack</a></h3><div
<ul> class="level3"><pre>SoundTrack&#40; audioPath, isStream, duration, loopMode &#41;</pre><p> Details of the constructor:</p><ul><li
<li><div> thingNode is the Spatial to be rotated.</div> class="level1"><div
</li> class="li"> audioPath is the path to an audio file as String, e.g. &quot;Sounds/mySound.wav&quot;.</div></li><li
<li><div> endRotation is the target rotation in Quaternion format. </div> class="level1"><div
</li> class="li"> isStream Set this to true to play a longer audio file as stream, or to false to play a short sound without streaming.</div></li><li
<li><div> duration is the time that it should take from start to target rotation.</div> class="level1"><div
</li> class="li"> duration is the time that it should take to play.</div></li><li
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div> class="level1"><div
</li> class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul></div><h3><a
</ul> name="guitrack">GuiTrack</a></h3><div
class="level3"><pre>GuiTrack&#40; screen, duration, loopMode &#41;</pre><p> You must use this together with bindUI() to specify the Nifty <acronym
</div> title="Graphical User Interface">GUI</acronym> <acronym
title="Extensible Markup Language">XML</acronym> file that you want to load:</p><pre>cinematic.bindUi&#40;&quot;Interface/subtitle.xml&quot;&#41;;</pre><p> Details of the constructor:</p><ul><li
<h3><a>ScaleTrack</a></h3> class="level1"><div
<div> class="li"> screen is the name of the Nifty <acronym
<pre>ScaleTrack thingScaleControl = new ScaleTrack&#40; title="Graphical User Interface">GUI</acronym> screen to load, as String.</div></li><li
thingNode, endScale, duration, loopMode&#41;;</pre> class="level1"><div
<p> class="li"> duration is the time that it should take to play.</div></li><li
Details of the constructor: class="level1"><div
</p> class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul></div><h3><a
<ul> name="animationtrack">AnimationTrack</a></h3><div
<li><div> thingNode is the Spatial to be resized.</div> class="level3"><pre>AnimationTrack&#40; thingNode, animationName, duration, loopMode &#41;</pre><p> Details of the constructor:</p><ul><li
</li> class="level1"><div
<li><div> endScale is the target Scale in Vector3f format. </div> class="li"> thingNode is the Spatial whose animation you want to play.</div></li><li
</li> class="level1"><div
<li><div> duration is the time that it should take from start to target scale.</div> class="li"> AnimationName the animation of the animated model that you want to trigger, as a String.</div></li><li
</li> class="level1"><div
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div> class="li"> duration is the time that it should take to play.</div></li><li
</li> class="level1"><div
</ul> class="li"> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div></li></ul></div><h3><a
name="customizations">Customizations</a></h3><div
</div> class="level3"><p> You can extend individual CinematicEvents. The <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/SubtitleTrack.java">SubtitleTrack.java example</a> shows how to extend a GuiTrack to script subtitles. See how the subtitles are used in the <a
<h3><a>SoundTrack</a></h3> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java">TestCinematic.java example</a>.</p><p> You can also create new CinematicEvent by extending <a
<div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java">AbstractCinematicEvent</a>. An AbstractCinematicEvent implements the CinematicEvent interface and provides duration, time, speed, etc… management. Look at the <a
<pre>SoundTrack&#40; audioPath, isStream, duration, loopMode &#41;</pre> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java">TestCinematic.java example</a> is to use this for a custom fadeIn/fadeOut effect in combination with a com.jme3.post.filters.FadeFilter.</p></div><h2><a
<p> name="camera_handling">Camera Handling</a></h2><div
class="level2"><p> The camera management is handled as follows:</p><ol><li
Details of the constructor: class="level1"><div
</p> class="li"> Create a camera Node and bind the camera object to the cinematic. Note that we also give the camera node a name in this step.<pre>CameraNode camNode = cinematic.bindCamera&#40;&quot;topView&quot;, cam&#41;;</pre></div></li><li
<ul> class="level1"><div
<li><div> audioPath is the path to an audio file as String, e.g. “Sounds/mySound.wav”.</div> class="li"> Position the camera node in its start location.</div></li><li
</li> class="level1"><div
<li><div> isStream Set this to true to play a longer audio file as stream, or to false to play a short sound without streaming.</div> class="li"> Use activateCamera() to give the control of the camera to this node. You now see the scene from this camera&#039;s point of view. For example to see through the camera node named &quot;top view&quot;, 6 seconds after the start of the cinematic, you&#039;d write<pre>cinematic.activateCamera&#40;6, &quot;topView&quot;&#41;;</pre></div></li><li
</li> class="level1"><div
<li><div> duration is the time that it should take to play.</div> class="li"> If desired, attach the camNode to a MotionTrack to let it travel along waypoints. This is demonstrated in the <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java">TestCameraMotionPath.java example</a>.</div></li></ol><p> Code samples:</p><pre>flyCam.setEnabled&#40;false&#41;;
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div>
</li>
</ul>
</div>
<h3><a>GuiTrack</a></h3>
<div>
<pre>GuiTrack&#40; screen, duration, loopMode &#41;</pre>
<p>
You must use this together with bindUI() to specify the Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> file that you want to load:
</p>
<pre>cinematic.bindUi&#40;&quot;Interface/subtitle.xml&quot;&#41;;</pre>
<p>
Details of the constructor:
</p>
<ul>
<li><div> screen is the name of the Nifty <acronym title="Graphical User Interface">GUI</acronym> screen to load, as String. </div>
</li>
<li><div> duration is the time that it should take to play.</div>
</li>
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div>
</li>
</ul>
</div>
<h3><a>AnimationTrack</a></h3>
<div>
<pre>AnimationTrack&#40; thingNode, animationName, duration, loopMode &#41;</pre>
<p>
Details of the constructor:
</p>
<ul>
<li><div> thingNode is the Spatial whose animation you want to play.</div>
</li>
<li><div> AnimationName the animation of the animated model that you want to trigger, as a String.</div>
</li>
<li><div> duration is the time that it should take to play.</div>
</li>
<li><div> loopMode can be LoopMode.Loop, LoopMode.DontLoop, LoopMode.Cycle.</div>
</li>
</ul>
</div>
<h3><a>Customizations</a></h3>
<div>
<p>
You can extend individual CinematicEvents. The <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/SubtitleTrack.java"><param name="text" value="<html><u>SubtitleTrack.java example</u></html>"><param name="textColor" value="blue"></object> shows how to extend a GuiTrack to script subtitles. See how the subtitles are used in the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java"><param name="text" value="<html><u>TestCinematic.java example</u></html>"><param name="textColor" value="blue"></object>.
</p>
<p>
You can also create new CinematicEvent by extending <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java"><param name="text" value="<html><u>AbstractCinematicEvent</u></html>"><param name="textColor" value="blue"></object>. An AbstractCinematicEvent implements the CinematicEvent interface and provides duration, time, speed, etc… management. Look at the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java"><param name="text" value="<html><u>TestCinematic.java example</u></html>"><param name="textColor" value="blue"></object> is to use this for a custom fadeIn/fadeOut effect in combination with a com.jme3.post.filters.FadeFilter.
</p>
</div>
<h2><a>Camera Handling</a></h2>
<div>
<p>
The camera management is handled as follows:
</p>
<ol>
<li><div> Create a camera Node and bind the camera object to the cinematic. Note that we also give the camera node a name in this step. <pre>CameraNode camNode = cinematic.bindCamera&#40;&quot;topView&quot;, cam&#41;;</pre></div>
</li>
<li><div> Position the camera node in its start location.</div>
</li>
<li><div> Use activateCamera() to give the control of the camera to this node. You now see the scene from this camera&#039;s point of view. For example to see through the camera node named “top view”, 6 seconds after the start of the cinematic, you&#039;d write <pre>cinematic.activateCamera&#40;6, &quot;topView&quot;&#41;;</pre></div>
</li>
<li><div> If desired, attach the camNode to a MotionTrack to let it travel along waypoints. This is demonstrated in the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/animation/TestCinematic.java"><param name="text" value="<html><u>TestCameraMotionPath.java example</u></html>"><param name="textColor" value="blue"></object>.</div>
</li>
</ol>
<p>
Code samples:
</p>
<pre>flyCam.setEnabled&#40;false&#41;;
&nbsp; &nbsp;
CameraNode camNodeTop = cinematic.bindCamera&#40;&quot;topView&quot;, cam&#41;; CameraNode camNodeTop = cinematic.bindCamera&#40;&quot;topView&quot;, cam&#41;;
camNodeTop.setControlDir&#40;ControlDirection.SpatialToCamera&#41;; camNodeTop.setControlDir&#40;ControlDirection.SpatialToCamera&#41;;
@ -362,26 +219,10 @@ camNodeTop.getControl&#40;0&#41;.setEnabled&#40;false&#41;;
&nbsp; &nbsp;
CameraNode camNodeSide = cinematic.bindCamera&#40;&quot;sideView&quot;, cam&#41;; CameraNode camNodeSide = cinematic.bindCamera&#40;&quot;sideView&quot;, cam&#41;;
camNodeSide.setControlDir&#40;ControlDirection.CameraToSpatial&#41;; camNodeSide.setControlDir&#40;ControlDirection.CameraToSpatial&#41;;
camNodeSide.getControl&#40;0&#41;.setEnabled&#40;false&#41;;</pre> camNodeSide.getControl&#40;0&#41;.setEnabled&#40;false&#41;;</pre></div><h2><a
</div> name="physics_interaction">Physics Interaction</a></h2><div
class="level2"><p> Upcoming.</p></div><h2><a
<h2><a>Physics Interaction</a></h2> name="more_information">More Information</a></h2><div
<div> class="level2"><p> See also: <a
href="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/cinematics-system-for-jme3/">Cinematics by Nehon</a></p></div>
<p>
Upcoming.
</p>
</div>
<h2><a>More Information</a></h2>
<div>
<p>
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/cinematics-system-for-jme3/"><param name="text" value="<html><u>Cinematics by Nehon</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:cinematics?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:cinematics?do=export_xhtmlbody">view online version</a></em></p>

@ -1,125 +1,66 @@
<h1><a
<h1><a>Collision and Intersection</a></h1> name="collision_and_intersection">Collision and Intersection</a></h1><div
<div> class="level1"><p> The term collision can be used to refer to physical interactions (where physical objects collide and bump off one another), and also to non-physical intersections. This article is about non-physical (mathematical) collisions.
<p>
The term collision can be used to refer to physical interactions (where physical objects collide and bump off one another), and also to non-physical intersections. This article is about non-physical (mathematical) collisions.
</p>
<p>
Non-physical collisions are interesting because they take less resources than physical ones. You cn optimize your game if you find a way to simulate a certain effect in a non-physical way, using mathematical techniques such as ray casting. Non-physical collisions are interesting because they take less resources than physical ones. You cn optimize your game if you find a way to simulate a certain effect in a non-physical way, using mathematical techniques such as ray casting.
</p> One example for an optimization is a physical vehicle&#039;s wheels. You could make the wheels fully physical disks, and have jME calculate every tiny force – sounds very accurate, but is total overkill. An more performant solution is to cast four rays down from the vehicle and calculate the intersections with the floor and other obstacles. These non-physical wheels require (in the simplest case) only four calculations to achieve an effect that players can hardly distinguish from the real thing.</p></div><h2><a
name="bounding_volumes">Bounding Volumes</a></h2><div
<p> class="level2"><p> A com.jme3.bounding.BoundingVolume is an interface for dealing with containment of a collection of points. All BoundingVolumes are Collidable and are used as optimization to calculate non-physical collisions more quickly: It&#039;s faster to calculate an intersection between simple shapes like spheres and boxes than between complex shapes. In cases where precision is not relevant, you wrap a complex model in a simpler shape to improve collision detection performance.</p><ul><li
One example for an optimization is a physical vehicle&#039;s wheels. You could make the wheels fully physical disks, and have jME calculate every tiny force – sounds very accurate, but is total overkill. An more performant solution is to cast four rays down from the vehicle and calculate the intersections with the floor and other obstacles. These non-physical wheels require (in the simplest case) only four calculations to achieve an effect that players can hardly distinguish from the real thing. class="level1"><div
</p> class="li"> Type.Sphere: com.jme3.bounding.BoundingSphere is a sphere used as a container for a group of vertices of a piece of geometry. A BoundingSphere has a center and a radius.</div></li><li
class="level1"><div
</div> class="li"> Type.AABB = Axis-aligned bounding box. A com.jme3.bounding.BoundingBox is an axis-aligned cuboid used as a container for a group of vertices of a piece of geometry. A BoundingBox has a center and extents from that center along the x, y and z axis.</div></li><li
class="level1"><div
<h2><a>Bounding Volumes</a></h2> class="li"> Type.OBB = Oriented bounding box. (not in use)</div></li><li
<div> class="level1"><div
class="li"> Type.Capsule</div></li></ul><p> Note: Physical objects have their own &quot;bounding volumes&quot; called CollisionShapes.</p></div><h2><a
<p> name="collisions">Collisions</a></h2><div
class="level2"><p> The interface com.jme3.collision.Collidable declares one method that returns how many collisions were found between two Collidables: <code>collideWith(Collidable other, CollisionResults results)</code>.
A com.jme3.bounding.BoundingVolume is an interface for dealing with containment of a collection of points. All BoundingVolumes are Collidable and are used as optimization to calculate non-physical collisions more quickly: It&#039;s faster to calculate an intersection between simple shapes like spheres and boxes than between complex shapes. In cases where precision is not relevant, you wrap a complex model in a simpler shape to improve collision detection performance.
</p>
<ul>
<li><div> Type.Sphere: com.jme3.bounding.BoundingSphere is a sphere used as a container for a group of vertices of a piece of geometry. A BoundingSphere has a center and a radius.</div>
</li>
<li><div> Type.AABB = Axis-aligned bounding box. A com.jme3.bounding.BoundingBox is an axis-aligned cuboid used as a container for a group of vertices of a piece of geometry. A BoundingBox has a center and extents from that center along the x, y and z axis.</div>
</li>
<li><div> Type.OBB = Oriented bounding box. (not in use)</div>
</li>
<li><div> Type.Capsule </div>
</li>
</ul>
<p>
Note: Physical objects have their own “bounding volumes” called CollisionShapes.
</p>
</div>
<h2><a>Collisions</a></h2>
<div>
<p>
The interface com.jme3.collision.Collidable declares one method that returns how many collisions were found between two Collidables: <code>collideWith(Collidable other, CollisionResults results)</code>.
</p>
<p>
A <code>com.jme3.collision.CollisionResults</code> object is an ArrayList of comparable <code>com.jme3.collision.CollisionResult</code> objects. A <code>com.jme3.collision.CollisionResults</code> object is an ArrayList of comparable <code>com.jme3.collision.CollisionResult</code> objects.
</p> You can iterate over the CollisionResults to identify the other parties involved in the collision. Note that jME counts <em>all</em> collisions, this means a ray intersecting a box will be counted as two hits, one on the front where the ray enters, and one on the back where the ray exits.</p><div
class="table sectionedit1"><table
<p> class="inline"><tr
You can iterate over the CollisionResults to identify the other parties involved in the collision. Note that jME counts <em>all</em> collisions, this means a ray intersecting a box will be counted as two hits, one on the front where the ray enters, and one on the back where the ray exits. class="row0"><th
class="col0">CollisionResults Method</th><th
</p> class="col1">Usage</th></tr><tr
<table> class="row1"><td
<tr> class="col0 leftalign">size()</td><td
<th>CollisionResults Method</th><th>Usage</th> class="col1">Returns the number of CollisionResult objects.</td></tr><tr
</tr> class="row2"><td
<tr> class="col0">getClosestCollision()</td><td
<td>size() </td><td>Returns the number of CollisionResult objects.</td> class="col1">Returns the CollisionResult with the lowest distance.</td></tr><tr
</tr> class="row3"><td
<tr> class="col0">getFarthestCollision()</td><td
<td>getClosestCollision() </td><td>Returns the CollisionResult with the lowest distance.</td> class="col1">Returns the CollisionResult with the farthest distance.</td></tr><tr
</tr> class="row4"><td
<tr> class="col0 leftalign">getCollision(i)</td><td
<td>getFarthestCollision()</td><td>Returns the CollisionResult with the farthest distance.</td> class="col1">Returns the CollisionResult at index i.</td></tr></table></div><p> A CollisionResult object contains information about the second party of the collision event.</p><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td>getCollision(i) </td><td>Returns the CollisionResult at index i.</td> class="row0"><th
</tr> class="col0">CollisionResult Method</th><th
</table> class="col1">Usage</th></tr><tr
class="row1"><td
<p> class="col0">getContactPoint()</td><td
class="col1">Returns the contact point coordinate on the second party, as Vector3f.</td></tr><tr
A CollisionResult object contains information about the second party of the collision event. class="row2"><td
class="col0">getContactNormal()</td><td
</p> class="col1">Returns the Normal vector at the contact point, as Vector3f.</td></tr><tr
<table> class="row3"><td
<tr> class="col0">getDistance()</td><td
<th>CollisionResult Method</th><th>Usage</th> class="col1">Returns the distance between the Collidable and the second party, as float.</td></tr><tr
</tr> class="row4"><td
<tr> class="col0">getGeometry()</td><td
<td>getContactPoint()</td><td>Returns the contact point coordinate on the second party, as Vector3f.</td> class="col1">Returns the Geometry of the second party.</td></tr><tr
</tr> class="row5"><td
<tr> class="col0">getTriangle(t)</td><td
<td>getContactNormal()</td><td>Returns the Normal vector at the contact point, as Vector3f.</td> class="col1">Binds t to the triangle t on the second party&#039;s mesh that was hit.</td></tr><tr
</tr> class="row6"><td
<tr> class="col0">getTriangleIndex()</td><td
<td>getDistance()</td><td>Returns the distance between the Collidable and the second party, as float.</td> class="col1">Returns the index of the triangle on the second party&#039;s mesh that was hit. (?)</td></tr></table></div><p> Assume you have two collidables a and b and want to detect collisions between them. The collision parties can be Geometries, Nodes with Geometries attached (including the rootNode), Planes, Quads, Lines, or Rays. <br/> The following code snippet can be triggered by listeners (e.g. after an input action such as a click), or timed in the update loop.</p><pre> // Calculate Results
</tr>
<tr>
<td>getGeometry()</td><td>Returns the Geometry of the second party.</td>
</tr>
<tr>
<td>getTriangle(t)</td><td>Binds t to the triangle t on the second party&#039;s mesh that was hit.</td>
</tr>
<tr>
<td>getTriangleIndex()</td><td>Returns the index of the triangle on the second party&#039;s mesh that was hit. (?)</td>
</tr>
</table>
<p>
Assume you have two collidables a and b and want to detect collisions between them. The collision parties can be Geometries, Nodes with Geometries attached (including the rootNode), Planes, Quads, Lines, or Rays.
</p>
<p>
The following code snippet can be triggered by listeners (e.g. after an input action such as a click), or timed in the update loop.
</p>
<pre> // Calculate Results
CollisionResults results = new CollisionResults&#40;&#41;; CollisionResults results = new CollisionResults&#40;&#41;;
a.collideWith&#40;b, results&#41;; a.collideWith&#40;b, results&#41;;
&nbsp;
System.out.println&#40;&quot;Number of Collisions between&quot; + a.getName&#40;&#41;+ &quot; and &quot; System.out.println&#40;&quot;Number of Collisions between&quot; + a.getName&#40;&#41;+ &quot; and &quot;
+ b.getName&#40;&#41; &quot; : &quot; + results.size&#40;&#41;&#41;; + b.getName&#40;&#41; &quot; : &quot; + results.size&#40;&#41;&#41;;
&nbsp;
// Use the results // Use the results
if &#40;results.size&#40;&#41; &gt; 0&#41; &#123; if &#40;results.size&#40;&#41; &gt; 0&#41; &#123;
CollisionResult closest = results.getClosestCollision&#40;&#41;; CollisionResult closest = results.getClosestCollision&#40;&#41;;
@ -129,17 +70,11 @@ The following code snippet can be triggered by listeners (e.g. after an input ac
&#125; else &#123; &#125; else &#123;
// how to react when no collision occured // how to react when no collision occured
&#125; &#125;
&#125;</pre> &#125;</pre><p> You can also loop over all results and trigger different reactions depending on what was hit and where it was hit. In this example, we simply print info about them.</p><pre> // Calculate Results
<p>
You can also loop over all results and trigger different reactions depending on what was hit and where it was hit. In this example, we simply print info about them.
</p>
<pre> // Calculate Results
CollisionResults results = new CollisionResults&#40;&#41;; CollisionResults results = new CollisionResults&#40;&#41;;
a.collideWith&#40;b, results&#41;; a.collideWith&#40;b, results&#41;;
&nbsp;
System.out.println&#40;&quot;Number of Collisions between&quot; + a.getName&#40;&#41;+ &quot; and &quot; System.out.println&#40;&quot;Number of Collisions between&quot; + a.getName&#40;&#41;+ &quot; and &quot;
+ b.getName&#40;&#41; &quot; : &quot; + results.size&#40;&#41;&#41;; + b.getName&#40;&#41; &quot; : &quot; + results.size&#40;&#41;&#41;;
&nbsp;
// Use the results // Use the results
for &#40;int i = 0; i &lt; results.size&#40;&#41;; i++&#41; &#123; for &#40;int i = 0; i &lt; results.size&#40;&#41;; i++&#41; &#123;
// For each hit, we know distance, impact point, name of geometry. // For each hit, we know distance, impact point, name of geometry.
@ -148,64 +83,90 @@ You can also loop over all results and trigger different reactions depending on
String party = results.getCollision&#40;i&#41;.getGeometry&#40;&#41;.getName&#40;&#41;; String party = results.getCollision&#40;i&#41;.getGeometry&#40;&#41;.getName&#40;&#41;;
int tri = results.getCollision&#40;i&#41;.getTriangleIndex&#40;&#41;; int tri = results.getCollision&#40;i&#41;.getTriangleIndex&#40;&#41;;
Vector3f norm = results.getCollision&#40;i&#41;.getTriangle&#40;new Triangle&#40;&#41;&#41;.getNormal&#40;&#41;; Vector3f norm = results.getCollision&#40;i&#41;.getTriangle&#40;new Triangle&#40;&#41;&#41;.getNormal&#40;&#41;;
&nbsp;
System.out.println&#40;&quot;Details of Collision #&quot; + i + &quot;:&quot;&#41;; System.out.println&#40;&quot;Details of Collision #&quot; + i + &quot;:&quot;&#41;;
System.out.println&#40;&quot; Party &quot; + party + &quot; was hit at &quot; + pt + &quot;, &quot; + dist + &quot; wu away.&quot;&#41;; System.out.println&#40;&quot; Party &quot; + party + &quot; was hit at &quot; + pt + &quot;, &quot; + dist + &quot; wu away.&quot;&#41;;
System.out.println&#40;&quot; The hit triangle #&quot; + tri + &quot; has a normal vector of &quot; + norm&#41;; System.out.println&#40;&quot; The hit triangle #&quot; + tri + &quot; has a normal vector of &quot; + norm&#41;;
&#125;</pre> &#125;</pre><p> Knowing the distance of the collisions is useful for example when you intersect Lines and Rays with other objects.</p></div><h2><a
<p> name="intersection">Intersection</a></h2><div
Knowing the distance of the collisions is useful for example when you intersect Lines and Rays with other objects. class="level2"><p> A com.jme3.math.Ray is an infinite line with a beginning, a direction, and no end; whereas a com.jme3.math.Line is an infinite line with only a direction (no beginning, no end).
</p> Rays are used to detect where a 3D object is &quot;looking&quot; and whether one object can &quot;see&quot; the other.</p><ul><li
class="level1"><div
</div> class="li"> You can determine where a user has clicked by casting a ray from the camera in the direction of the camera. Now identify the closest collision of the ray with e.g. the rootNode.</div></li><li
class="level1"><div
<h2><a>Intersection</a></h2> class="li"> Or you cast a ray from a player in the direction of another player. Then you detect all collisions of this ray with other entities (walls, foliage, window panes) and use this to calculate whether one can see the other.</div></li></ul><p> These simple ray-surface intersection tests are called Ray Casting. (As opposed to the more advanced Ray Tracing, Ray Casting does not follow a ray&#039;s reflection after the first hit, but the ray goes straight on.)</p></div><h3><a
<div> name="usecasepicking_a_target_with_crosshairs">Usecase: Picking a target with crosshairs</a></h3><div
class="level3"><p> This <code>pick target</code> input mapping implements an action that determines what a user clicked (if you map this to a mouse click). It assumes that there are crosshairs in the center of the screen, and the user aims the crosshairs at an object in the scene. We use a ray casting approach to determine the geometry that was picked by the user. You can extend this code to do whatever with the identified target (shoot it, take it, move it, …)
<p> Use this together with <code>inputManager.setCursorVisible(false)</code>.</p><pre> private AnalogListener analogListener = new AnalogListener&#40;&#41; &#123;
public void onAnalog&#40;String name, float intensity, float tpf&#41; &#123;
A com.jme3.math.Ray is an infinite line with a beginning, a direction, and no end; whereas a com.jme3.math.Line is an infinite line with only a direction (no beginning, no end). if &#40;name.equals&#40;&quot;pick target&quot;&#41;&#41; &#123;
</p> // Reset results list.
CollisionResults results = new CollisionResults&#40;&#41;;
<p> // Aim the ray from camera location in camera direction
Rays are used to detect where a 3D object is “looking” and whether one object can “see” the other. // (assuming crosshairs in center of screen).
</p> Ray ray = new Ray&#40;cam.getLocation&#40;&#41;, cam.getDirection&#40;&#41;&#41;;
<ul> // Collect intersections between ray and all nodes in results list.
<li><div> You can determine where a user has clicked by casting a ray from the camera in the direction of the camera. Now identify the closest collision of the ray with e.g. the rootNode.</div> rootNode.collideWith&#40;ray, results&#41;;
</li> // Print the results so we see what is going on
<li><div> Or you cast a ray from a player in the direction of another player. Then you detect all collisions of this ray with other entities (walls, foliage, window panes) and use this to calculate whether one can see the other.</div> for &#40;int i = 0; i &lt; results.size&#40;&#41;; i++&#41; &#123;
</li> // For each “hit”, we know distance, impact point, geometry.
</ul> float dist = results.getCollision&#40;i&#41;.getDistance&#40;&#41;;
Vector3f pt = results.getCollision&#40;i&#41;.getContactPoint&#40;&#41;;
<p> String target = results.getCollision&#40;i&#41;.getGeometry&#40;&#41;.getName&#40;&#41;;
System.out.println&#40;&quot;Selection #&quot; + i + &quot;: &quot; + target + &quot; at &quot; + pt + &quot;, &quot; + dist + &quot; WU away.&quot;&#41;;
These simple ray-surface intersection tests are called Ray Casting. (As opposed to the more advanced Ray Tracing, Ray Casting does not follow a ray&#039;s reflection after the first hit, but the ray goes straight on.) &#125;
</p> // 5. Use the results -- we rotate the selected geometry.
if &#40;results.size&#40;&#41; &gt; 0&#41; &#123;
</div> // The closest result is the target that the player picked:
Geometry target = results.getClosestCollision&#40;&#41;.getGeometry&#40;&#41;;
<h2><a>Bounding Interval Hierarchy</a></h2> // Here comes the action:
<div> if&#40;target.getName&#40;&#41;.equals&#40;&quot;Red Box&quot;&#41;&#41;
target.rotate&#40;0, - intensity, 0&#41;;
<p> else if&#40;target.getName&#40;&#41;.equals&#40;&quot;Blue Box&quot;&#41;&#41;
target.rotate&#40;0, intensity, 0&#41;;
com.jme3.collision.bih.BIHNode &#125;
com.jme3.scene.CollisionData &#125; // else if ...
</p> &#125;
&#125;;</pre></div><h3><a
</div> name="usecasepicking_a_target_with_mouse_cursor">Usecase: Picking a target with mouse cursor</a></h3><div
class="level3"><p> This <code>pick target</code> input mapping implements an action that determines what a user clicked (if you map this to a mouse click). It assumes that the cursor is visible, and the user aims the cursor at an object in the scene. We use a ray casting approach to determine the geometry that was picked by the user. You can extend this code to do whatever with the identified target (shoot it, take it, move it, …) Use this together with <code>inputManager.setCursorVisible(true)</code>.</p><pre>private AnalogListener analogListener = new AnalogListener&#40;&#41; &#123;
<h2><a>SweepSphere</a></h2> public void onAnalog&#40;String name, float intensity, float tpf&#41; &#123;
<div> if &#40;name.equals&#40;&quot;pick target&quot;&#41;&#41; &#123;
// Reset results list.
<p> CollisionResults results = new CollisionResults&#40;&#41;;
// Convert screen click to 3d position
A com.jme3.collision.SweepSphere implements a collidable “stretched” sphere that is shaped like a capsule (an upright cylinder with half a sphere on top and the second half at the bottom). Vector2f click2d = inputManager.getCursorPosition&#40;&#41;;
</p> Vector3f click3d = cam.getWorldCoordinates&#40;new Vector2f&#40;click2d.x, click2d.y&#41;, 0f&#41;.clone&#40;&#41;;
Vector3f dir = cam.getWorldCoordinates&#40;new Vector2f&#40;click2d.x, click2d.y&#41;, 1f&#41;.subtractLocal&#40;click3d&#41;;
<p> // Aim the ray from the clicked spot forwards.
This shape is usually used to simulate simple non-physcial collisions for character entities in games. The sweep sphere can be used to check collision against a triangle or another sweep sphere. Ray ray = new Ray&#40;click3d, dir&#41;;
</p> // Collect intersections between ray and all nodes in results list.
rootNode.collideWith&#40;ray, results&#41;;
</div> // (Print the results so we see what is going on:)
for &#40;int i = 0; i &lt; results.size&#40;&#41;; i++&#41; &#123;
// (For each “hit”, we know distance, impact point, geometry.)
float dist = results.getCollision&#40;i&#41;.getDistance&#40;&#41;;
Vector3f pt = results.getCollision&#40;i&#41;.getContactPoint&#40;&#41;;
String target = results.getCollision&#40;i&#41;.getGeometry&#40;&#41;.getName&#40;&#41;;
System.out.println&#40;&quot;Selection #&quot; + i + &quot;: &quot; + target + &quot; at &quot; + pt + &quot;, &quot; + dist + &quot; WU away.&quot;&#41;;
&#125;
// Use the results -- we rotate the selected geometry.
if &#40;results.size&#40;&#41; &gt; 0&#41; &#123;
// The closest result is the target that the player picked:
Geometry target = results.getClosestCollision&#40;&#41;.getGeometry&#40;&#41;;
// Here comes the action:
if &#40;target.getName&#40;&#41;.equals&#40;&quot;Red Box&quot;&#41;&#41; &#123;
target.rotate&#40;0, -intensity, 0&#41;;
&#125; else if &#40;target.getName&#40;&#41;.equals&#40;&quot;Blue Box&quot;&#41;&#41; &#123;
target.rotate&#40;0, intensity, 0&#41;;
&#125;
&#125;
&#125; // else if ...
&#125;
&#125;;</pre></div><h2><a
name="bounding_interval_hierarchy">Bounding Interval Hierarchy</a></h2><div
class="level2"><p> com.jme3.collision.bih.BIHNode
com.jme3.scene.CollisionData</p></div><h2><a
name="sweepsphere">SweepSphere</a></h2><div
class="level2"><p> A com.jme3.collision.SweepSphere implements a collidable &quot;stretched&quot; sphere that is shaped like a capsule (an upright cylinder with half a sphere on top and the second half at the bottom).
This shape is usually used to simulate simple non-physcial collisions for character entities in games. The sweep sphere can be used to check collision against a triangle or another sweep sphere.</p></div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:collision_and_intersection?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:collision_and_intersection?do=export_xhtmlbody">view online version</a></em></p>

@ -1,174 +1,83 @@
<h1><a
<h1><a>Combo Moves</a></h1> name="combo_moves">Combo Moves</a></h1><div
<div> class="level1"><p> The ComboMoves class allows you to define combinations of inputs that trigger special actions. Entering an input combo correctly can bring the player incremental rewards, such as an increased chance to hit, an increased effectiveness, or decreased change of being blocked, whatever the game designer chooses. <a
href="http://en.wikipedia.org/wiki/Combo_%28video_gaming%29">More background info</a></p><p> Combos are usually a series of inputs, in a fixed order: For example a keyboard combo can look like: &quot;press Down, then Down+Right together, then Right&quot;.</p><p> Usage:</p><ol><li
<p> class="level1"><div
The ComboMoves class allows you to define combinations of inputs that trigger special actions. Entering an input combo correctly can bring the player incremental rewards, such as an increased chance to hit, an increased effectiveness, or decreased change of being blocked, whatever the game designer chooses. <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/Combo_%28video_gaming%29"><param name="text" value="<html><u>More background info</u></html>"><param name="textColor" value="blue"></object> class="li"> Create input triggers</div></li><li
</p> class="level1"><div
class="li"> Define combos</div></li><li
<p> class="level1"><div
Combos are usually a series of inputs, in a fixed order: For example a keyboard combo can look like: “press Down, then Down+Right together, then Right”. class="li"> Detect combos in ActionListener</div></li><li
</p> class="level1"><div
class="li"> Execute combos in update loop</div></li></ol><p> Copy the two classes ComboMoveExecution.java and ComboMove.java into your application and adjust them to your package paths.</p></div><h2><a
<p> name="example_code">Example Code</a></h2><div
Usage: class="level2"><ul><li
</p> class="level1"><div
<ol> class="li"> <a
<li><div> Create input triggers </div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/TestComboMoves.java">TestComboMoves.java</a></div></li><li
</li> class="level1"><div
<li><div> Define combos</div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMoveExecution.java">ComboMoveExecution.java</a> ← required</div></li><li
<li><div> Detect combos in ActionListener </div> class="level1"><div
</li> class="li"> <a
<li><div> Execute combos in update loop </div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMove.java">ComboMove.java</a> ← required</div></li></ul></div><h2><a
</li> name="create_input_triggers">Create Input Triggers</a></h2><div
</ol> class="level2"><p> First you <a
href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">define your game&#039;s inputs</a> as you usually do: Implement the com.jme3.input.controls.ActionListener interface for your class, and add triggers mappings such as com.jme3.input.controls.KeyTrigger and com.jme3.input.KeyInput.</p><p> For example:</p><pre>inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_LEFT&#41;&#41;;
<p>
Copy the two classes ComboMoveExecution.java and ComboMove.java into your application and adjust them to your package paths.
</p>
</div>
<h2><a>Example Code</a></h2>
<div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/TestComboMoves.java"><param name="text" value="<html><u>TestComboMoves.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMoveExecution.java"><param name="text" value="<html><u>ComboMoveExecution.java</u></html>"><param name="textColor" value="blue"></object> ← required</div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/input/combomoves/ComboMove.java"><param name="text" value="<html><u>ComboMove.java</u></html>"><param name="textColor" value="blue"></object> ← required</div>
</li>
</ul>
</div>
<h2><a>Create Input Triggers</a></h2>
<div>
<p>
First you <a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">define your game&#039;s inputs</a> as you usually do: Implement the com.jme3.input.controls.ActionListener interface for your class, and add triggers mappings such as com.jme3.input.controls.KeyTrigger and com.jme3.input.KeyInput.
</p>
<p>
For example:
</p>
<pre>inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_LEFT&#41;&#41;;
inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_RIGHT&#41;&#41;; inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_RIGHT&#41;&#41;;
inputManager.addMapping&#40;&quot;Up&quot;, new KeyTrigger&#40;KeyInput.KEY_UP&#41;&#41;; inputManager.addMapping&#40;&quot;Up&quot;, new KeyTrigger&#40;KeyInput.KEY_UP&#41;&#41;;
inputManager.addMapping&#40;&quot;Down&quot;, new KeyTrigger&#40;KeyInput.KEY_DOWN&#41;&#41;; inputManager.addMapping&#40;&quot;Down&quot;, new KeyTrigger&#40;KeyInput.KEY_DOWN&#41;&#41;;
inputManager.addMapping&#40;&quot;Attack1&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;; inputManager.addMapping&#40;&quot;Attack1&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;
... ...
inputManager.addListener&#40;this, &quot;Left&quot;, &quot;Right&quot;, &quot;Up&quot;, &quot;Down&quot;, &quot;Attack1&quot;&#41;;</pre> inputManager.addListener&#40;this, &quot;Left&quot;, &quot;Right&quot;, &quot;Up&quot;, &quot;Down&quot;, &quot;Attack1&quot;&#41;;</pre></div><h2><a
</div> name="define_combos">Define Combos</a></h2><div
class="level2"><p> For each of your combo moves, you specify the series of inputs that will trigger it. The order in which you define them is the order the player has to press them for the step to be recorded. When all steps have been recorded, the combo is triggered.</p><p> The following example shows how a fireball combo move is triggered by pressing the navigation keys for &quot;down, down+right, right&quot;, in this order.</p><pre>ComboMove fireball = new ComboMove&#40;&quot;Fireball&quot;&#41;;
<h2><a>Define Combos</a></h2>
<div>
<p>
For each of your combo moves, you specify the series of inputs that will trigger it. The order in which you define them is the order the player has to press them for the step to be recorded. When all steps have been recorded, the combo is triggered.
</p>
<p>
The following example shows how a fireball combo move is triggered by pressing the navigation keys for “down, down+right, right”, in this order.
</p>
<pre>ComboMove fireball = new ComboMove&#40;&quot;Fireball&quot;&#41;;
fireball.press&#40;&quot;Down&quot;&#41;.notPress&#40;&quot;Right&quot;&#41;.done&#40;&#41;; fireball.press&#40;&quot;Down&quot;&#41;.notPress&#40;&quot;Right&quot;&#41;.done&#40;&#41;;
fireball.press&#40;&quot;Right&quot;, &quot;Down&quot;&#41;.done&#40;&#41;; fireball.press&#40;&quot;Right&quot;, &quot;Down&quot;&#41;.done&#40;&#41;;
fireball.press&#40;&quot;Right&quot;&#41;.notPress&#40;&quot;Down&quot;&#41;.done&#40;&#41;; fireball.press&#40;&quot;Right&quot;&#41;.notPress&#40;&quot;Down&quot;&#41;.done&#40;&#41;;
fireball.notPress&#40;&quot;Right&quot;, &quot;Down&quot;&#41;.done&#40;&#41;; fireball.notPress&#40;&quot;Right&quot;, &quot;Down&quot;&#41;.done&#40;&#41;;
fireball.setUseFinalState&#40;false&#41;;</pre> fireball.setUseFinalState&#40;false&#41;;</pre><p> Also create a ComboMoveExecution object for each ComboMove. You need it later to execute the detected combo.</p><pre>ComboMoveExecution fireballExec = new ComboMoveExecution&#40;fireball&#41;;</pre></div><h3><a
<p> name="combomove_class_methods">ComboMove Class Methods</a></h3><div
Also create a ComboMoveExecution object for each ComboMove. You need it later to execute the detected combo. class="level3"><p> Use the following ComboMove methods to specify the combo:</p><div
</p> class="table sectionedit1"><table
<pre>ComboMoveExecution fireballExec = new ComboMoveExecution&#40;fireball&#41;;</pre> class="inline"><tr
</div> class="row0"><th
class="col0">ComboMove Method</th><th
<h3><a>ComboMove Class Methods</a></h3> class="col1">Description</th></tr><tr
<div> class="row1"><td
class="col0">press(&quot;A&quot;).done(); <br/> press(&quot;A&quot;,&quot;B&quot;).done();</td><td
<p> class="col1">Combo step is recorded if A is entered. <br/> Combo step is recorded if A and B are entered simultaneously.</td></tr><tr
class="row2"><td
Use the following ComboMove methods to specify the combo: class="col0">notPress(&quot;A&quot;).done(); <br/> notPress(&quot;A&quot;,&quot;B&quot;).done();</td><td
class="col1">Combo step is recorded if A is released. <br/> Combo step is recorded if A and B are both released.</td></tr><tr
</p> class="row3"><td
<table> class="col0">press(&quot;A&quot;).notPress(&quot;B&quot;).done();</td><td
<tr> class="col1">Combo step is recorded if A is entered, and not B</td></tr><tr
<th>ComboMove Method</th><th>Description</th> class="row4"><td
</tr> class="col0">press(&quot;A&quot;).notPress(&quot;B&quot;).timeElapsed(0.11f).done();</td><td
<tr> class="col1">Combo step is recorded a certain time after A and not B is entered. <br/> etc, etc …</td></tr><tr
<td>press(“A”).done(); <br/> class="row5"><td
press(“A”,”B”).done();</td><td>Combo step is recorded if A is entered. <br/> class="col0">setPriority(0.5f);</td><td
Combo step is recorded if A and B are entered simultaneously.</td> class="col1">If there is an ambiguity, a high-priority combo will trigger instead of a low-priority combo. This prevents that a similar looking combo step &quot;hijacks&quot; another Combo. Use only once per ComboMove.</td></tr><tr
</tr> class="row6"><td
<tr> class="col0">setUseFinalState(false); <br/> setUseFinalState(true);</td><td
<td>notPress(“A”).done(); <br/> class="col1">This is the final command of the series. <br/> False: Do not wait on a final state, chain combo steps. (?) <br/> True: This is the final state, do not chain combo steps. (?)</td></tr></table></div><p> The <code>press()</code> and <code>notPress()</code> methods accept sets of Input Triggers, e.g. <code>fireball.press(&quot;A&quot;,&quot;B&quot;,&quot;C&quot;).done()</code>.</p><p> The following getters give you more information about the game state:</p><div
notPress(“A”,”B”).done();</td><td>Combo step is recorded if A is released. <br/> class="table sectionedit2"><table
Combo step is recorded if A and B are both released.</td> class="inline"><tr
</tr> class="row0"><th
<tr> class="col0">ComboMove Method</th><th
<td>press(“A”).notPress(“B”).done();</td><td>Combo step is recorded if A is entered, and not B</td> class="col1">Usage</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">getCastTime()</td><td
<td>press(“A”).notPress(“B”).timeElapsed(0.11f).done();</td><td>Combo step is recorded a certain time after A and not B is entered. <br/> class="col1">Returns the time since the last step has been recorded. (?)</td></tr><tr
etc, etc …</td> class="row2"><td
</tr> class="col0">getMoveName()</td><td
<tr> class="col1">Returns the string of the current combo</td></tr><tr
<td>setPriority(0.5f);</td><td>If there is an ambiguity, a high-priority combo will trigger instead of a low-priority combo. This prevents that a similar looking combo step “hijacks” another Combo. Use only once per ComboMove.</td> class="row3"><td
</tr> class="col0">getPriority()</td><td
<tr> class="col1">Returns the priority of this move</td></tr></table></div></div><h2><a
<td>setUseFinalState(false); <br/> name="detect_combos_in_actionlistener">Detect Combos in ActionListener</a></h2><div
setUseFinalState(true);</td><td>This is the final command of the series. <br/> class="level2"><p> Now that you have specified the combo steps, you want to detect them. You do that in the onAction() method that you get from the ActionListener interface.</p><p> Create a HashSet <code>pressMappings</code> to track curently pressed mappings, and a ComboMove object <code>currentMove</code> to track the current move.</p><p> We also track the cast time of a combo to determine if it has timed out (see update loop below).</p><pre>private HashSet&lt;String&gt; pressedMappings = new HashSet&lt;String&gt;&#40;&#41;;
False: Do not wait on a final state, chain combo steps. (?) <br/>
True: This is the final state, do not chain combo steps. (?)</td>
</tr>
</table>
<p>
The <code>press()</code> and <code>notPress()</code> methods accept sets of Input Triggers, e.g. <code>fireball.press(“A”,”B”,”C”).done()</code>.
</p>
<p>
The following getters give you more information about the game state:
</p>
<table>
<tr>
<th>ComboMove Method</th><th>Usage</th>
</tr>
<tr>
<td>getCastTime()</td><td>Returns the time since the last step has been recorded. (?)</td>
</tr>
<tr>
<td>getMoveName()</td><td>Returns the string of the current combo</td>
</tr>
<tr>
<td>getPriority()</td><td>Returns the priority of this move</td>
</tr>
</table>
</div>
<h2><a>Detect Combos in ActionListener</a></h2>
<div>
<p>
Now that you have specified the combo steps, you want to detect them. You do that in the onAction() method that you get from the ActionListener interface.
</p>
<p>
Create a HashSet <code>pressMappings</code> to track curently pressed mappings, and a ComboMove object <code>currentMove</code> to track the current move.
</p>
<p>
We also track the cast time of a combo to determine if it has timed out (see update loop below).
</p>
<pre>private HashSet&lt;String&gt; pressedMappings = new HashSet&lt;String&gt;&#40;&#41;;
private ComboMove currentMove = null; private ComboMove currentMove = null;
private float currentMoveCastTime = 0; private float currentMoveCastTime = 0;
private float time = 0; private float time = 0;
@ -208,17 +117,9 @@ public void onAction&#40;String name, boolean isPressed, float tpf&#41; &#123;
currentMove = toExec; currentMove = toExec;
currentMoveCastTime = currentMove.getCastTime&#40;&#41;; currentMoveCastTime = currentMove.getCastTime&#40;&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="execute_combos_in_the_update_loop">Execute Combos in the Update Loop</a></h2><div
class="level2"><p> Now that you have detected the current move, you want to execute it. You do that in the update loop.</p><pre>@Override
<h2><a>Execute Combos in the Update Loop</a></h2>
<div>
<p>
Now that you have detected the current move, you want to execute it. You do that in the update loop.
</p>
<pre>@Override
public void simpleUpdate&#40;float tpf&#41;&#123; public void simpleUpdate&#40;float tpf&#41;&#123;
time += tpf; time += tpf;
fireballExec.updateExpiration&#40;time&#41;; fireballExec.updateExpiration&#40;time&#41;;
@ -233,32 +134,15 @@ public void simpleUpdate&#40;float tpf&#41;&#123;
currentMove = null; currentMove = null;
&#125; &#125;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Test <code>currentMove.getMoveName()</code> and proceed to call methods that implement any special actions and bonuses. This is up to you and depends individually on your game.</p></div><h2><a
<p> name="why_combos">Why Combos?</a></h2><div
Test <code>currentMove.getMoveName()</code> and proceed to call methods that implement any special actions and bonuses. This is up to you and depends individually on your game. class="level2"><p> Depending on the game genre, the designer can reward the players&#039; intrinsical or extrinsical skills:</p><ul><li
</p> class="level1"><div
class="li"> (intrinsical:) RPGs typically calculate the success of an attack from the character&#039;s in-game training level: The player plays the role of a character whose skill level is defined in numbers. RPGs typically do not offer any Combos.</div></li><li
</div> class="level1"><div
class="li"> (extrinsical:) Sport and fighter games typically choose to reward the player&#039;s &quot;manual&quot; skills: The success of a special move solely depends on the player&#039;s own dexterity. These games typically offer optional Combos.</div></li></ul><div
<h2><a>Why Combos?</a></h2> class="tags"><span> <a
<div> href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
Depending on the game genre, the designer can reward the players&#039; intrinsical or extrinsical skills:
</p>
<ul>
<li><div> (intrinsical:) RPGs typically calculate the success of an attack from the character&#039;s in-game training level: The player plays the role of a character whose skill level is defined in numbers. RPGs typically do not offer any Combos.</div>
</li>
<li><div> (extrinsical:) Sport and fighter games typically choose to reward the player&#039;s “manual” skills: The success of a special move solely depends on the player&#039;s own dexterity. These games typically offer optional Combos.</div>
</li>
</ul>
<div><span>
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:combo_moves?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:combo_moves?do=export_xhtmlbody">view online version</a></em></p>

@ -1,107 +1,48 @@
<h1><a
<h1><a>Custom Controls</a></h1> name="custom_controls">Custom Controls</a></h1><div
<div> class="level1"><p> A <code>com.jme3.scene.control.Control</code> is a customizable jME3 interface that allows you to cleanly implement game logic, such as game rules, or artificially intelligent behaviour in NPCs. You use Controls to control the behaviour of types of spatials. To control global game behaviour see <a
href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> – you can use both together.
<p> To control the behaviour of types of entities:</p><ol><li
class="level1"><div
A <code>com.jme3.scene.control.Control</code> is a customizable jME3 interface that allows you to cleanly implement game logic, such as game rules, or artificially intelligent behaviour in NPCs. You use Controls to control the behaviour of types of spatials. To control global game behaviour see <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> – you can use both together. class="li"> Create one control for each type of behavior. When you add several controls to one spatial, they will be executed in the order they were added. <br/> For example, an NPC can be controlled by a PhysicsControl and an AIControl.</div></li><li
</p> class="level1"><div
class="li"> You define a custom control and implement its behaviour in the Control&#039;s update() method.</div><ul><li
<p> class="level2"><div
To control the behaviour of types of entities: class="li"> In the control, you can pass arguments and manipulate the spatial in any way: Modify its transformation (move, scale, rotate), play animations, check for enemies around it and react, etc.</div></li></ul></li><li
</p> class="level1"><div
<ol> class="li"> Add the control to a spatial and the Spatial&#039;s game state is updated automatically from now on. <br/> <code>spatial.addControl(myControl)</code></div></li></ol><p> To implement game logic for a type of spatial, you will either extend AbstractControl, or implement the Control interface, as explained in this article.</p></div><h2><a
<li><div> Create one control for each type of behavior. When you add several controls to one spatial, they will be executed in the order they were added. <br/> name="usage_examples">Usage Examples</a></h2><div
For example, an NPC can be controlled by a PhysicsControl and an AIControl. </div> class="level2"><p> For example, you could write a CharacterAnimControl that animates a character accordingly while it is being moved by a CharacterControl. Or you can write an AIControl that remote-controls NPC behaviour in fight situatons. Or you could write a DestructionControl that automatically replaces a structure with an appropriate piece of debris after collision with a projectile… The possibilities are endless. <img
</li> src="/wiki/lib/images/smileys/icon_smile.gif" class="middle" alt=":-)" /> Existing examples in the code base include:</p><ul><li
<li><div> You define a custom control and implement its behaviour in the Control&#039;s update() method.</div> class="level1"><div
<ul> class="li"> <a
<li><div> In the control, you can pass arguments and manipulate the spatial in any way: Modify its transformation (move, scale, rotate), play animations, check for enemies around it and react, etc. </div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/animation/AnimControl.java">AnimControl.java</a> allows manipulation of skeletal animation, including blending and multiple channels.</div></li><li
</li> class="level1"><div
</ul> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/control/CameraControl.java">CameraControl.java</a> allows you to sync the camera position with the position of a given spatial.</div></li><li
<li><div> Add the control to a spatial and the Spatial&#039;s game state is updated automatically from now on. <br/> class="level1"><div
<code>spatial.addControl(myControl)</code></div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/control/BillboardControl.java">BillboardControl.java</a> displays a flat picture orthogonally, e.g. a speech bubble or informational dialog.</div></li><li
</ol> class="level1"><div
class="li"> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/#src%2Fjbullet%2Fcom%2Fjme3%2Fbullet%2Fcontrol">PhysicsControl</a> subclasses (such as CharacterControl, RigidBodyControl, VehicleControl) allow you to add physical properties to any spatial. PhysicsControls tie into capabilities provided by the BulletAppState.</div></li></ul></div><h2><a
name="the_control_interface">The Control Interface</a></h2><div
To implement game logic for a type of spatial, you will either extend AbstractControl, or implement the Control interface, as explained in this article. class="level2"><p> The interface can be found under <code>com.jme3.scene.control.Control</code>. It has the following method signatures:</p><ul><li
</p> class="level1"><div
class="li"> <code>cloneForSpatial(Spatial)</code>: Clones the Control and attaches it to a clone of the given Spatial. The AssetManager uses this method if the same spatial is loaded twice. You can specify which fields you want your object to reuse (e.g. collisionshapes) in this case.</div></li><li
</div> class="level1"><div
class="li"> <code>setEnabled(boolean)</code>: Enable or disable the control. If disabled, update() does nothing. Goes with accessor <code>isEnabled();</code>.</div></li><li
<h2><a>Usage Examples</a></h2> class="level1"><div
<div> class="li"> There are also some internal methods that you do not call from user code: <code>setSpatial(Spatial s)</code>, <code>update(float tpf);</code>, <code>render(RenderManager rm, ViewPort vp)</code>.</div></li></ul><p> If you want to create a Control that also extends an existing class, then create a custom extension of the Control Interface. Usage example:
1. Create a custom control interface</p><pre>public interface MyControl extends Control &#123;
<p>
For example, you could write a CharacterAnimControl that animates a character accordingly while it is being moved by a CharacterControl. Or you can write an AIControl that remote-controls NPC behaviour in fight situatons. Or you could write a DestructionControl that automatically replaces a structure with an appropriate piece of debris after collision with a projectile… The possibilities are endless. <img src="/wiki/lib/images/smileys/icon_smile.gif" class="middle" alt=":-)" />
</p>
<p>
Existing examples in the code base include:
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/animation/AnimControl.java"><param name="text" value="<html><u>AnimControl.java</u></html>"><param name="textColor" value="blue"></object> allows manipulation of skeletal animation, including blending and multiple channels.</div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/control/CameraControl.java"><param name="text" value="<html><u>CameraControl.java</u></html>"><param name="textColor" value="blue"></object> allows you to sync the camera position with the position of a given spatial.</div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/control/BillboardControl.java"><param name="text" value="<html><u>BillboardControl.java</u></html>"><param name="textColor" value="blue"></object> displays a flat picture orthogonally, e.g. a speech bubble or informational dialog.</div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/#src%2Fjbullet%2Fcom%2Fjme3%2Fbullet%2Fcontrol"><param name="text" value="<html><u>PhysicsControl</u></html>"><param name="textColor" value="blue"></object> subclasses (such as CharacterControl, RigidBodyControl, VehicleControl) allow you to add physical properties to any spatial. PhysicsControls tie into capabilities provided by the BulletAppState. </div>
</li>
</ul>
</div>
<h2><a>The Control Interface</a></h2>
<div>
<p>
The interface can be found under <code>com.jme3.scene.control.Control</code>. It has the following method signatures:
</p>
<ul>
<li><div> <code>cloneForSpatial(Spatial)</code>: Clones the Control and attaches it to a clone of the given Spatial.</div>
</li>
<li><div> <code>setEnabled(boolean)</code>: Enable or disable the control. If disabled, update() does nothing. Goes with accessor <code>isEnabled();</code>.</div>
</li>
<li><div> There are also some internal methods that you do not call from user code: <code>setSpatial(Spatial s)</code>, <code>update(float tpf);</code>, <code>render(RenderManager rm, ViewPort vp)</code>.</div>
</li>
</ul>
<p>
If you want to create a Control that also extends an existing class, then create a custom extension of the Control Interface. Usage example:
</p>
<p>
1. Create a custom control interface
</p>
<pre>public interface MyControl extends Control &#123;
public void setSomething&#40;int x&#41;; // add your custom methods public void setSomething&#40;int x&#41;; // add your custom methods
&#125;</pre> &#125;</pre><p> 2. Create custom classes implementing your control interface</p><pre>public class ControlledThing extends MyThing implements MyControl &#123;
<p>
2. Create custom classes implementing your control interface
</p>
<pre>public class ControlledThing extends MyThing implements MyControl &#123;
&nbsp;
protected Spatial spatial; protected Spatial spatial;
protected boolean enabled = true; protected boolean enabled = true;
&nbsp;
public ControlledThing&#40;&#41; &#123; &#125; public ControlledThing&#40;&#41; &#123; &#125;
&nbsp;
public ControlledThing&#40;int x&#41; &#123; public ControlledThing&#40;int x&#41; &#123;
super&#40;x&#41;; super&#40;x&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void update&#40;float tpf&#41; &#123; public void update&#40;float tpf&#41; &#123;
if &#40;enabled &amp;&amp; spatial != null&#41; &#123; if &#40;enabled &amp;&amp; spatial != null&#41; &#123;
@ -109,12 +50,10 @@ If you want to create a Control that also extends an existing class, then create
// Write custom code to control the spatial here! // Write custom code to control the spatial here!
&#125; &#125;
&#125; &#125;
&nbsp;
@Override @Override
public void render&#40;RenderManager rm, ViewPort vp&#41; &#123; public void render&#40;RenderManager rm, ViewPort vp&#41; &#123;
// optional, e.g. to display a debug shape // optional, e.g. to display a debug shape
&#125; &#125;
&nbsp;
@Override @Override
public Control cloneForSpatial&#40;Spatial spatial&#41; &#123; public Control cloneForSpatial&#40;Spatial spatial&#41; &#123;
ControlledThing control = new ControlledThing&#40;y&#41;; ControlledThing control = new ControlledThing&#40;y&#41;;
@ -122,23 +61,19 @@ If you want to create a Control that also extends an existing class, then create
spatial.setControl&#40;control&#41;; spatial.setControl&#40;control&#41;;
return control; return control;
&#125; &#125;
&nbsp;
@Override @Override
public void setEnabled&#40;boolean enabled&#41; &#123; public void setEnabled&#40;boolean enabled&#41; &#123;
this.enabled = enabled; this.enabled = enabled;
// ... // ...
&#125; &#125;
&nbsp;
@Override @Override
public boolean isEnabled&#40;&#41; &#123; public boolean isEnabled&#40;&#41; &#123;
return enabled; return enabled;
&#125; &#125;
&nbsp;
@Override @Override
public void setSomething&#40;int z&#41; &#123; public void setSomething&#40;int z&#41; &#123;
// your custom method ... // your custom method ...
&#125; &#125;
&nbsp;
@Override @Override
public void write&#40;JmeExporter ex&#41; throws IOException &#123; public void write&#40;JmeExporter ex&#41; throws IOException &#123;
super.write&#40;ex&#41;; super.write&#40;ex&#41;;
@ -147,7 +82,6 @@ If you want to create a Control that also extends an existing class, then create
oc.write&#40;spatial, &quot;spatial&quot;, null&#41;; oc.write&#40;spatial, &quot;spatial&quot;, null&#41;;
// write custom variables .... // write custom variables ....
&#125; &#125;
&nbsp;
@Override @Override
public void read&#40;JmeImporter im&#41; throws IOException &#123; public void read&#40;JmeImporter im&#41; throws IOException &#123;
super.read&#40;im&#41;; super.read&#40;im&#41;;
@ -156,86 +90,52 @@ If you want to create a Control that also extends an existing class, then create
spatial = &#40;Spatial&#41; ic.readSavable&#40;&quot;spatial&quot;, null&#41;; spatial = &#40;Spatial&#41; ic.readSavable&#40;&quot;spatial&quot;, null&#41;;
// read custom variables .... // read custom variables ....
&#125; &#125;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="abstractcontrol">AbstractControl</a></h2><div
class="level2"><p> This class can be found under <code>com.jme3.scene.control.AbstractControl</code>.</p><ul><li
<h2><a>AbstractControl</a></h2> class="level1"><div
<div> class="li"> This is a default abstract class that implements the Control interface.</div></li><li
class="level1"><div
<p> class="li"> It gives you access to a boolean <code>enabled</code>, and a Spatial <code>spatial</code>.</div></li><li
class="level1"><div
This class can be found under <code>com.jme3.scene.control.AbstractControl</code>. class="li"> Extend AbstractControl to create a custom Control.</div></li></ul><p> Usage: Your custom subclass must implement the three methods <code>controlUpdate()</code>, <code>controlRender()</code>, and <code>cloneForSpatial()</code> as shown here:</p><pre>public class MyControl extends AbstractControl implements Savable, Cloneable &#123;
</p>
<ul>
<li><div> This is a default abstract class that implements the Control interface.</div>
</li>
<li><div> It gives you access to a boolean <code>enabled</code>, and a Spatial <code>spatial</code>.</div>
</li>
<li><div> Extend AbstractControl to create a custom Control.</div>
</li>
</ul>
<p>
Usage: Your custom subclass must implement the three methods <code>controlUpdate()</code>, <code>controlRender()</code>, and <code>cloneForSpatial()</code> as shown here:
</p>
<pre>public class MyControl extends AbstractControl implements Savable, Cloneable &#123;
&nbsp;
private Thing thing; // some custom class of yours private Thing thing; // some custom class of yours
&nbsp;
public MyControl&#40;&#41;&#123;&#125; // empty serialization constructor public MyControl&#40;&#41;&#123;&#125; // empty serialization constructor
&nbsp;
public MyControl&#40;thing&#41; &#123; // some custom constructor public MyControl&#40;thing&#41; &#123; // some custom constructor
super&#40;spatial&#41;; super&#40;spatial&#41;;
this.thing = thing; this.thing = thing;
&#125; &#125;
&nbsp;
@Override @Override
protected void controlUpdate&#40;float tpf&#41;&#123; protected void controlUpdate&#40;float tpf&#41;&#123;
if&#40;spatial != null &amp;&amp; thing != null&#41; &#123; if&#40;spatial != null &amp;&amp; thing != null&#41; &#123;
// Implement your custom control here ... // Implement your custom control here ...
&#125; &#125;
&#125; &#125;
&nbsp;
@Override @Override
protected void controlRender&#40;RenderManager rm, ViewPort vp&#41;&#123; protected void controlRender&#40;RenderManager rm, ViewPort vp&#41;&#123;
// ... optional // ... optional
&#125; &#125;
&nbsp;
@Override @Override
public Control cloneForSpatial&#40;Spatial spatial&#41;&#123; public Control cloneForSpatial&#40;Spatial spatial&#41;&#123;
final MyControl control = new MyControl&#40;...&#41;; final MyControl control = new MyControl&#40;...&#41;;
spatial.setControl&#40;control&#41;; spatial.setControl&#40;control&#41;;
return control; return control;
&#125; &#125;
&nbsp;
@Override @Override
public void read&#40;JmeImporter im&#41; throws IOException &#123; public void read&#40;JmeImporter im&#41; throws IOException &#123;
super.read&#40;im&#41;; super.read&#40;im&#41;;
// im.getCapsule(this).read(...); // im.getCapsule(this).read(...);
&#125; &#125;
&nbsp;
@Override @Override
public void write&#40;JmeExporter ex&#41; throws IOException &#123; public void write&#40;JmeExporter ex&#41; throws IOException &#123;
super.write&#40;ex&#41;; super.write&#40;ex&#41;;
// ex.getCapsule(this).write(...); // ex.getCapsule(this).write(...);
&#125; &#125;
&nbsp; &#125;</pre></div><h2><a
&#125;</pre> name="best_practices">Best Practices</a></h2><div
</div> class="level2"><p> <strong>Tip:</strong> Use the getControl() accessor to get Control objects from Spatials. No need to pass around lots of object references.
Here an example from the <a
<h2><a>Best Practices</a></h2> href="http://code.google.com/p/monkeyzone/">MonkeyZone</a> code:</p><pre>public class CharacterAnimControl implements Control &#123;
<div>
<p>
<strong>Tip:</strong> Use the getControl() accessor to get Control objects from Spatials. No need to pass around lots of object references.
</p>
<p>
Here an example from the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/monkeyzone/"><param name="text" value="<html><u>MonkeyZone</u></html>"><param name="textColor" value="blue"></object> code:
</p>
<pre>public class CharacterAnimControl implements Control &#123;
... ...
public void setSpatial&#40;Spatial spatial&#41; &#123; public void setSpatial&#40;Spatial spatial&#41; &#123;
... ...
@ -243,38 +143,16 @@ Here an example from the <object classid="java:org.netbeans.modules.javahelp.Bro
characterControl = spatial.getControl&#40;CharacterControl.class&#41;; characterControl = spatial.getControl&#40;CharacterControl.class&#41;;
... ...
&#125; &#125;
&#125;</pre> &#125;</pre><p> <strong>Tip:</strong> You can create custom Control interfaces so a set of different Controls provide the same methods and can be accessed with the interface class type.</p><pre>public interface ManualControl extends Control &#123;
<p>
<strong>Tip:</strong> You can create custom Control interfaces so a set of different Controls provide the same methods and can be accessed with the interface class type.
</p>
<pre>public interface ManualControl extends Control &#123;
public void steerX&#40;float value&#41;; public void steerX&#40;float value&#41;;
public void steerY&#40;float value&#41;; public void steerY&#40;float value&#41;;
public void moveX&#40;float value&#41;; public void moveX&#40;float value&#41;;
public void moveY&#40;float value&#41;; public void moveY&#40;float value&#41;;
public void moveZ&#40;float value&#41;; public void moveZ&#40;float value&#41;;
... ...
&#125;</pre> &#125;</pre><p> Then you create custom sub-Controls and implement the methods accordingly to the context:</p><pre>public class ManualVehicleControl extends ManualControl &#123;...&#125;</pre><p> and</p><pre>public class ManualCharacterControl extends ManualControl &#123;...&#125;</pre><p> Then add the appropriate controls to spatials:</p><pre>characterSpatial.addControl&#40;new ManualCharacterControl&#40;&#41;&#41;;
<p>
Then you create custom sub-Controls and implement the methods accordingly to the context:
</p>
<pre>public class ManualVehicleControl extends ManualControl &#123;...&#125;</pre>
<p>
and
</p>
<pre>public class ManualCharacterControl extends ManualControl &#123;...&#125;</pre>
<p>
Then add the appropriate controls to spatials:
</p>
<pre>characterSpatial.addControl&#40;new ManualCharacterControl&#40;&#41;&#41;;
... ...
vehicleSpatial.addControl&#40;new ManualVehicleControl&#40;&#41;&#41;; vehicleSpatial.addControl&#40;new ManualVehicleControl&#40;&#41;&#41;;
...</pre> ...</pre><p> <strong>Tip:</strong> Use the getControl() method on a Spatial to get a specific Control object, and activate its behaviour!</p><pre>ManualControl c = mySpatial.getControl&#40;ManualControl.class&#41;;
<p> c.steerX&#40;steerX&#41;;</pre></div>
<strong>Tip:</strong> Use the getControl() method on a Spatial to get a specific Control object, and activate its behaviour!
</p>
<pre>ManualControl c = mySpatial.getControl&#40;ManualControl.class&#41;;
c.steerX&#40;steerX&#41;;</pre>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_controls?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_controls?do=export_xhtmlbody">view online version</a></em></p>

@ -1,210 +1,77 @@
<h1><a
<h1><a>Custom Mesh Shapes</a></h1> name="custom_mesh_shapes">Custom Mesh Shapes</a></h1><div
<div> class="level1"><p> <a
href="/wiki/lib/exe/fetch.php?hash=f71f7a&amp;media=http%3A%2F%2Fimg821.imageshack.us%2Fimg821%2F1829%2Fhellomesh.png"><img
<p> src="/wiki/lib/exe/fetch.php?hash=f71f7a&amp;w=200&amp;h=150&amp;media=http%3A%2F%2Fimg821.imageshack.us%2Fimg821%2F1829%2Fhellomesh.png" class="medialeft" align="left" alt="" width="200" height="150" /></a></p><p> Use the Mesh class to create custom shapes that go beyond Quad, Box, Cylinder, and Sphere, even procedural shapes are possible. Thank you to KayTrance for providing the sample code!</p><p> In this tutorial, we (re)create a very simple rectangular mesh, and we have a look at different ways of coloring it. A flat rectangle may not look useful because it&#039;s exactly the same as a <code>com.jme3.scene.shape.Quad</code>. We choose this simple example in order to show you how to build any shape out of triangles – without the distractions of more complex shapes.</p><ul><li
class="level1"><div
<img src="/wiki/lib/exe/fetch.php"> class="li"> Full code sample: <a
</p> href="http://jmonkeyengine.googlecode.com/svn/branches/stable-alpha4/engine/src/test/jme3test/model/shape/TestCustomMesh.java">TestCustomMesh.java</a></div></li></ul></div><h2><a
name="polygon_meshes">Polygon Meshes</a></h2><div
<p> class="level2"><p> Polygon meshes are made up of triangles. The corners of the triangles are vertices. So, when ever you create a new shape, you break it down into triangles.</p><p> Let&#039;s look at a cube. A cube is made up of 6 rectangles. Each rectangle can be broken down into two triangles. This means you need 12 triangles to create a cube mesh. You also need to know the 8 corner coordinates (vertices). The trick is that you have to specify the vertices in a certain order: Each triangle separately, counter-clockwise.</p><p> Sounds worse than it is – here is an example:</p></div><h2><a
Use the Mesh class to create custom shapes that go beyond Quad, Box, Cylinder, and Sphere, even procedural shapes are possible. Thank you to KayTrance for providing the sample code! name="creating_a_quad_mesh">Creating a Quad Mesh</a></h2><div
</p> class="level2"><p> Okay, we want to create a Quad. A quad has four vertices, and is made up of two triangles.</p><p> The base class for creating meshes is <code>com.jme3.scene.Mesh</code>.</p><pre>Mesh m = new Mesh&#40;&#41;;</pre></div><h3><a
name="vertices">Vertices</a></h3><div
<p> class="level3"><p> To define your own shape, determine its vertex positions in space. Store them in an array using com.jme3.math.Vector3f. For a Quad, we need four vertices: Bottom left, bottom right, top left, top right. We name the array <code>vertices[]</code>.</p><pre>Vector3f &#91;&#93; vertices = new Vector3f&#91;4&#93;;
In this tutorial, we (re)create a very simple rectangular mesh, and we have a look at different ways of coloring it. A flat rectangle may not look useful because it&#039;s exactly the same as a <code>com.jme3.scene.shape.Quad</code>. We choose this simple example in order to show you how to build any shape out of triangles – without the distractions of more complex shapes.
</p>
<ul>
<li><div> Full code sample: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/branches/stable-alpha4/engine/src/test/jme3test/model/shape/TestCustomMesh.java"><param name="text" value="<html><u>TestCustomMesh.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<h2><a>Polygon Meshes</a></h2>
<div>
<p>
Polygon meshes are made up of triangles. The corners of the triangles are vertices. So, when ever you create a new shape, you break it down into triangles.
</p>
<p>
Let&#039;s look at a cube. A cube is made up of 6 rectangles. Each rectangle can be broken down into two triangles. This means you need 12 triangles to create a cube mesh. You also need to know the 8 corner coordinates (vertices). The trick is that you have to specify the vertices in a certain order: Each triangle separately, counter-clockwise.
</p>
<p>
Sounds worse than it is – here is an example:
</p>
</div>
<h2><a>Creating a Quad Mesh</a></h2>
<div>
<p>
Okay, we want to create a Quad. A quad has four vertices, and is made up of two triangles.
</p>
<p>
The base class for creating meshes is <code>com.jme3.scene.Mesh</code>.
</p>
<pre>Mesh m = new Mesh&#40;&#41;;</pre>
</div>
<h3><a>Vertices</a></h3>
<div>
<p>
To define your own shape, determine its vertex positions in space. Store them in an array using com.jme3.math.Vector3f. For a Quad, we need four vertices: Bottom left, bottom right, top left, top right. We name the array <code>vertices[]</code>.
</p>
<pre>Vector3f &#91;&#93; vertices = new Vector3f&#91;4&#93;;
vertices&#91;0&#93; = new Vector3f&#40;0,0,0&#41;; vertices&#91;0&#93; = new Vector3f&#40;0,0,0&#41;;
vertices&#91;1&#93; = new Vector3f&#40;3,0,0&#41;; vertices&#91;1&#93; = new Vector3f&#40;3,0,0&#41;;
vertices&#91;2&#93; = new Vector3f&#40;0,3,0&#41;; vertices&#91;2&#93; = new Vector3f&#40;0,3,0&#41;;
vertices&#91;3&#93; = new Vector3f&#40;3,3,0&#41;;</pre> vertices&#91;3&#93; = new Vector3f&#40;3,3,0&#41;;</pre></div><h3><a
</div> name="texture_coordinates">Texture Coordinates</a></h3><div
class="level3"><p> Next, define the Quad&#039;s 2D texture coordinates for each vertex, in the same order: Bottom left, bottom right, top left, top right. We name this array <code>texCoord[]</code></p><pre>Vector2f&#91;&#93; texCoord = new Vector2f&#91;4&#93;;
<h3><a>Texture Coordinates</a></h3>
<div>
<p>
Next, define the Quad&#039;s 2D texture coordinates for each vertex, in the same order: Bottom left, bottom right, top left, top right. We name this array <code>texCoord[]</code>
</p>
<pre>Vector2f&#91;&#93; texCoord = new Vector2f&#91;4&#93;;
texCoord&#91;0&#93; = new Vector2f&#40;0,0&#41;; texCoord&#91;0&#93; = new Vector2f&#40;0,0&#41;;
texCoord&#91;1&#93; = new Vector2f&#40;1,0&#41;; texCoord&#91;1&#93; = new Vector2f&#40;1,0&#41;;
texCoord&#91;2&#93; = new Vector2f&#40;0,1&#41;; texCoord&#91;2&#93; = new Vector2f&#40;0,1&#41;;
texCoord&#91;3&#93; = new Vector2f&#40;1,1&#41;;</pre> texCoord&#91;3&#93; = new Vector2f&#40;1,1&#41;;</pre></div><h3><a
</div> name="connecting_the_dots">Connecting the Dots</a></h3><div
class="level3"><p> Next we turn the unrelated coordinates into triangles – We define the order in which the mesh is constructed. Think of these indexes as coming in groups of three. Each group of indexes describes one triangle. Note that you must specify the vertices counter-clockwise!</p><pre>int &#91;&#93; indexes = &#123; 2,0,1, 1,3,2 &#125;;</pre><ul><li
<h3><a>Connecting the Dots</a></h3> class="level1"><div
<div> class="li"> The 2,0,1 triangle starts at top left, continues bottom left, and ends at bottom right.</div></li><li
class="level1"><div
<p> class="li"> The 1,3,2 triangle start at bottom right, continues top right, and ends at top left.</div></li></ul><pre>2\2--3
Next we turn the unrelated coordinates into triangles – We define the order in which the mesh is constructed. Think of these indexes as coming in groups of three. Each group of indexes describes one triangle. Note that you must specify the vertices counter-clockwise!
</p>
<pre>int &#91;&#93; indexes = &#123; 2,0,1, 1,3,2 &#125;;</pre><ul>
<li><div> The 2,0,1 triangle starts at top left, continues bottom left, and ends at bottom right. </div>
</li>
<li><div> The 1,3,2 triangle start at bottom right, continues top right, and ends at top left.</div>
</li>
</ul>
<pre>
2\2--3
| \ | Counter-clockwise | \ | Counter-clockwise
| \ | | \ |
0--1\1 0--1\1</pre></div><h3><a
</pre> name="setting_the_mesh_buffer">Setting the Mesh Buffer</a></h3><div
class="level3"><p> The Mesh data is stored in a buffer.</p><ol><li
</div> class="level1"><div
class="li"> Using <code>com.jme3.util.BufferUtils</code>, we create three buffers for the three types of information we have:</div><ul><li
<h3><a>Setting the Mesh Buffer</a></h3> class="level2"><div
<div> class="li"> vertex positions,</div></li><li
class="level2"><div
<p> class="li"> texture coordinates,</div></li><li
class="level2"><div
The Mesh data is stored in a buffer. class="li"> indices.</div></li></ul></li><li
</p> class="level1"><div
<ol> class="li"> We assign the data to the appropriate type of buffer inside the mesh object. The three buffer types are taken from an enum in <code>com.jme3.scene.VertexBuffer.Type</code>.</div></li><li
<li><div> Using <code>com.jme3.util.BufferUtils</code>, we create three buffers for the three types of information we have: </div> class="level1"><div
<ul> class="li"> The third parameter describes the number of components of the values. Vertex postions are 3 float values, texture coordinates are 2 float values, and the indices are single ints.</div></li><li
<li><div> vertex positions, </div> class="level1"><div
</li> class="li"> In order for JMonkey to correctly show the mesh in the scene, it needs to know the bounds of our new mesh. This can easily be achieved by calling the updateBound() method on it.</div></li></ol><pre>m.setBuffer&#40;Type.Position, 3, BufferUtils.createFloatBuffer&#40;vertices&#41;&#41;;
<li><div> texture coordinates, </div>
</li>
<li><div> indices.</div>
</li>
</ul>
</li>
<li><div> We assign the data to the appropriate type of buffer inside the mesh object. The three buffer types are taken from an enum in <code>com.jme3.scene.VertexBuffer.Type</code>.</div>
</li>
<li><div> The third parameter describes the number of components of the values. Vertex postions are 3 float values, texture coordinates are 2 float values, and the indices are single ints. </div>
</li>
<li><div> In order for JMonkey to correctly show the mesh in the scene, it needs to know the bounds of our new mesh. This can easily be achieved by calling the updateBound() method on it.</div>
</li>
</ol>
<pre>m.setBuffer&#40;Type.Position, 3, BufferUtils.createFloatBuffer&#40;vertices&#41;&#41;;
m.setBuffer&#40;Type.TexCoord, 2, BufferUtils.createFloatBuffer&#40;texCoord&#41;&#41;; m.setBuffer&#40;Type.TexCoord, 2, BufferUtils.createFloatBuffer&#40;texCoord&#41;&#41;;
m.setBuffer&#40;Type.Index, 1, BufferUtils.createIntBuffer&#40;indexes&#41;&#41;; m.setBuffer&#40;Type.Index, 1, BufferUtils.createIntBuffer&#40;indexes&#41;&#41;;
m.updateBound&#40;&#41;;</pre> m.updateBound&#40;&#41;;</pre><p> Our Mesh is ready! Now we want to see it.</p></div><h2><a
<p> name="using_the_mesh_in_a_scene">Using the Mesh in a Scene</a></h2><div
Our Mesh is ready! Now we want to see it. class="level2"><p> We create a <code>com.jme3.scene.Geometry</code>, apply a simple color material to it, and attach it to the rootNode to make it appear in the scene.</p><pre>Geometry geom = new Geometry&#40;&quot;OurMesh&quot;, m&#41;;
</p>
</div>
<h2><a>Using the Mesh in a Scene</a></h2>
<div>
<p>
We create a <code>com.jme3.scene.Geometry</code>, apply a simple color material to it, and attach it to the rootNode to make it appear in the scene.
</p>
<pre>Geometry geom = new Geometry&#40;&quot;OurMesh&quot;, m&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/SolidColor.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/SolidColor.j3md&quot;&#41;;
mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;
geom.setMaterial&#40;mat&#41;; geom.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;geom&#41;;</pre> rootNode.attachChild&#40;geom&#41;;</pre><p> Ta-daa!</p></div><h2><a
<p> name="optional_mesh_features">Optional Mesh Features</a></h2><div
Ta-daa! class="level2"><p> There are more vertex buffers in a Mesh than the three shown above. For an overview, see also <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/meshes_and_models.html">Meshes and Models</a>.</p></div><h3><a
name="examplevertex_colors">Example: Vertex Colors</a></h3><div
</div> class="level3"><p> Vertex coloring is a simple way of coloring meshes. Instead of just assigning one solid color, each vertex (corner) has a color assigned. The faces between the vertices are then colored with a gradient.</p><p> We will use the same mesh <code>m</code> as defined above, but with a special VertexColor material.</p><pre>Geometry coloredMesh = new Geometry &#40;&quot;ColoredMesh&quot;, m&#41;;
Material matVC = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/VertexColor.j3md&quot;&#41;;</pre><p> We create a float array color buffer.</p><ul><li
<h2><a>Optional Mesh Features</a></h2> class="level1"><div
<div> class="li"> We assign 4 color values, RGBA, to each vertex.</div><ul><li
class="level2"><div
<p> class="li"> To loop over the 4 color values, we use a color index<pre>int colorIndex = 0;</pre></div></li></ul></li><li
class="level1"><div
There are more vertex buffers in a Mesh than the three shown above. For an overview, see also <a href="/com/jme3/gde/core/docs/jme3/advanced/meshes_and_models.html">Meshes and Models</a>. class="li"> The color buffer contains four color values for each vertex.</div><ul><li
</p> class="level2"><div
class="li"> The Quad in this example has 4 vertices.<pre>float&#91;&#93; colorArray = new float&#91;4*4&#93;;</pre></div></li><li
</div> class="level2"><div
class="li"> Tip: If your mesh has a different number of vertices, you would write:<pre>float&#91;&#93; colorArray = new float&#91;yourVertexCount * 4&#93;</pre></div></li></ul></li></ul><p> We loop over the colorArray buffer to quickly set some RGBA value for each vertex. As usual, RGBA color values range from 0.0f to 1.0f. Note that the values we use here are arbitrarily chosen! It&#039;s just a quick loop to give every vertex a different RGBA value (a purplish gray, purple, a greenish gray, green, see screenshot), without writing too much code. For your own mesh, you&#039;d assign values for the color buffer depending on which color you want your mesh to have.</p><pre>for&#40;int i = 0; i &lt; 4; i++&#41;&#123;
<h3><a>Example: Vertex Colors</a></h3>
<div>
<p>
Vertex coloring is a simple way of coloring meshes. Instead of just assigning one solid color, each vertex (corner) has a color assigned. The faces between the vertices are then colored with a gradient.
</p>
<p>
We will use the same mesh <code>m</code> as defined above, but with a special VertexColor material.
</p>
<pre>Geometry coloredMesh = new Geometry &#40;&quot;ColoredMesh&quot;, m&#41;;
Material matVC = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/VertexColor.j3md&quot;&#41;;</pre>
<p>
We create a float array color buffer.
</p>
<ul>
<li><div> We assign 4 color values, RGBA, to each vertex.</div>
<ul>
<li><div> To loop over the 4 color values, we use a color index <pre>int colorIndex = 0;</pre></div>
</li>
</ul>
</li>
<li><div> The color buffer contains four color values for each vertex.</div>
<ul>
<li><div> The Quad in this example has 4 vertices. <pre>float&#91;&#93; colorArray = new float&#91;4*4&#93;;</pre></div>
</li>
<li><div> Tip: If your mesh has a different number of vertices, you would write: <pre>float&#91;&#93; colorArray = new float&#91;yourVertexCount * 4&#93;</pre></div>
</li>
</ul>
</li>
</ul>
<p>
We loop over the colorArray buffer to quickly set some RGBA value for each vertex. As usual, RGBA color values range from 0.0f to 1.0f. Note that the values we use here are arbitrarily chosen! It&#039;s just a quick loop to give every vertex a different RGBA value (a purplish gray, purple, a greenish gray, green, see screenshot), without writing too much code. For your own mesh, you&#039;d assign values for the color buffer depending on which color you want your mesh to have.
</p>
<pre>for&#40;int i = 0; i &lt; 4; i++&#41;&#123;
// Red value (is increased by .2 on each next vertex here) // Red value (is increased by .2 on each next vertex here)
colorArray&#91;colorIndex++&#93;= 0.1f+&#40;.2f*i&#41;; colorArray&#91;colorIndex++&#93;= 0.1f+&#40;.2f*i&#41;;
// Green value (is reduced by .2 on each next vertex) // Green value (is reduced by .2 on each next vertex)
@ -213,27 +80,10 @@ We loop over the colorArray buffer to quickly set some RGBA value for each verte
colorArray&#91;colorIndex++&#93;= 0.5f; colorArray&#91;colorIndex++&#93;= 0.5f;
// Alpha value (no transparency set here) // Alpha value (no transparency set here)
colorArray&#91;colorIndex++&#93;= 1.0f; colorArray&#91;colorIndex++&#93;= 1.0f;
&#125;</pre> &#125;</pre><p> Next, set the color buffer. An RGBA color value contains four float components, thus the parameter <code>4</code>.</p><pre>m.setBuffer&#40;Type.Color, 4, colorArray&#41;;
<p> coloredMesh.setMaterial&#40;matVC&#41;;</pre><p> Now you see a gradient color extending from each vertex.</p></div><h3><a
name="examplepoint_mode">Example: Point Mode</a></h3><div
Next, set the color buffer. An RGBA color value contains four float components, thus the parameter <code>4</code>. class="level3"><p> Alternatively, you can show the vertices as colored points instead of coloring the faces.</p><pre>Geometry coloredMesh = new Geometry &#40;&quot;ColoredMesh&quot;, cMesh&#41;;
</p>
<pre>m.setBuffer&#40;Type.Color, 4, colorArray&#41;;
coloredMesh.setMaterial&#40;matVC&#41;;</pre>
<p>
Now you see a gradient color extending from each vertex.
</p>
</div>
<h3><a>Example: Point Mode</a></h3>
<div>
<p>
Alternatively, you can show the vertices as colored points instead of coloring the faces.
</p>
<pre>Geometry coloredMesh = new Geometry &#40;&quot;ColoredMesh&quot;, cMesh&#41;;
... ...
m.setMode&#40;Mesh.Mode.Points&#41;; m.setMode&#40;Mesh.Mode.Points&#41;;
m.setPointSize&#40;10f&#41;; m.setPointSize&#40;10f&#41;;
@ -243,36 +93,11 @@ Geometry points = new Geometry&#40;&quot;Points&quot;, m&#41;;
points.setMaterial&#40;mat&#41;; points.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;points&#41;; rootNode.attachChild&#40;points&#41;;
&nbsp; &nbsp;
rootNode.attachChild&#40;coloredMesh&#41;;</pre> rootNode.attachChild&#40;coloredMesh&#41;;</pre><p> This will result in a 10 px dot being rendered for each of the four vertices. The dot has the vertex color you specified above. The Quad&#039;s faces are not rendered at all. This can be used for a special debugging or editing mode.</p></div><h2><a
<p> name="tipfront_and_back_faces">Tip: Front and Back Faces</a></h2><div
This will result in a 10 px dot being rendered for each of the four vertices. The dot has the vertex color you specified above. The Quad&#039;s faces are not rendered at all. This can be used for a special debugging or editing mode. class="level2"><p> By default, jME3 optimizes a scene by culling all backfaces. It determines which side the front or backface of a mesh is by the order of the vertices. The frontface is the one where the vertices are specified counter-clockwise.</p><p> This means your mesh, as created above, is invisible when seen from &quot;behind&quot;. This may not be a problem and is often even intended. If you use the custom meshes to form a polyhedron, or flat wallpaper-like object, rendering the backfaces (the inside of the polyhedron) would indeed be a waste of resources.</p><p> In case that your use case requires the backfaces to be visible, you have two options:</p><ul><li
</p> class="level1"><div
class="li"> If you have a very simple scene, you can just deactivate backface culling for this one mesh&#039;s material. <br/> <code>mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off));</code></div></li><li
</div> class="level1"><div
class="li"> The recommended solution is to specify each triangle twice, the second time with the opposite order of vertices. The second, reversed triangle makes up the backface. <br/> <code>int[] indexes = { 2,0,1, 1,3,2, 2,3,1, 1,0,2 }; </code></div></li></ul></div>
<h2><a>Tip: Front and Back Faces</a></h2>
<div>
<p>
By default, jME3 optimizes a scene by culling all backfaces. It determines which side the front or backface of a mesh is by the order of the vertices. The frontface is the one where the vertices are specified counter-clockwise.
</p>
<p>
This means your mesh, as created above, is invisible when seen from “behind”. This may not be a problem and is often even intended. If you use the custom meshes to form a polyhedron, or flat wallpaper-like object, rendering the backfaces (the inside of the polyhedron) would indeed be a waste of resources.
</p>
<p>
In case that your use case requires the backfaces to be visible, you have two options:
</p>
<ul>
<li><div> If you have a very simple scene, you can just deactivate backface culling for this one mesh&#039;s material. <br/>
<code>mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off));</code></div>
</li>
<li><div> The recommended solution is to specify each triangle twice, the second time with the opposite order of vertices. The second, reversed triangle makes up the backface. <br/>
<code>int[] indexes = { 2,0,1, 1,3,2, 2,3,1, 1,0,2 }; </code></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_meshes?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_meshes?do=export_xhtmlbody">view online version</a></em></p>

@ -1,43 +1,12 @@
<h1><a
<h1><a>Debugging</a></h1> name="debugging">Debugging</a></h1><div
<div> class="level1"><p> When you deal with complex game engine features like animations or physics it is handy to get feedback from the engine how it interpreted the current state. Is the physical object&#039;s collision shape really where you think it is? Is the skeleton of the animated character moveing like you think it should? This document shows you how to activate visual debug aides.</p><p> What if you just want to quickly write code that loads models and brings them in their start position? You may not want to hunt for a sample model, convert it, add lights, and load materials. Instead you use &quot;hasslefree&quot; simple shapes a wireframe material: No model, no light source, no materials are needed to see them in the scene.</p><p> If you ever have problems with objects appearing in the wrong spot, with the wrong scale, or wrong orientation, simply attach debug shapes to your scene to have a point of reference in 3D space – just like a giant ruler. If your code positions the debug shapes correctly, but models remain invisible when you apply the same code to them, you know that the problem must be the model or the light or its material – and not the positioning code.</p><p> Here are some different debug shapes:</p><p> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:debug-shapes.png?id=jme3%3Aadvanced%3Adebugging"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/debug-shapes.png?w=600&amp;h=220" class="mediacenter" alt="" width="600" height="220" /></a></p></div><h2><a
name="debug_shapes">Debug Shapes</a></h2><div
When you deal with complex game engine features like animations or physics it is handy to get feedback from the engine how it interpreted the current state. Is the physical object&#039;s collision shape really where you think it is? Is the skeleton of the animated character moveing like you think it should? This document shows you how to activate visual debug aides. class="level2"></div><h3><a
</p> name="coordinate_axes">Coordinate Axes</a></h3><div
class="level3"><p> The coordinate axes (com.jme3.scene.debug.Arrow) help you see the cardinal directions (X,Y,Z) from their center point. Scale the arrows to use them as a &quot;ruler&quot; for a certain length.</p><pre>private void attachCoordinateAxes&#40;Vector3f pos&#41;&#123;
<p>
What if you just want to quickly write code that loads models and brings them in their start position? You may not want to hunt for a sample model, convert it, add lights, and load materials. Instead you use “hasslefree” simple shapes a wireframe material: No model, no light source, no materials are needed to see them in the scene.
</p>
<p>
If you ever have problems with objects appearing in the wrong spot, with the wrong scale, or wrong orientation, simply attach debug shapes to your scene to have a point of reference in 3D space – just like a giant ruler. If your code positions the debug shapes correctly, but models remain invisible when you apply the same code to them, you know that the problem must be the model or the light or its material – and not the positioning code.
</p>
<p>
Here are some different debug shapes:
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/debug-shapes.png">
</p>
</div>
<h2><a>Debug Shapes</a></h2>
<div>
</div>
<h3><a>Coordinate Axes</a></h3>
<div>
<p>
The coordinate axes (com.jme3.scene.debug.Arrow) help you see the cardinal directions (X,Y,Z) from their center point. Scale the arrows to use them as a “ruler” for a certain length.
</p>
<pre>private void attachCoordinateAxes&#40;Vector3f pos&#41;&#123;
Arrow arrow = new Arrow&#40;Vector3f.UNIT_X&#41;; Arrow arrow = new Arrow&#40;Vector3f.UNIT_X&#41;;
arrow.setLineWidth&#40;4&#41;; // make arrow thicker arrow.setLineWidth&#40;4&#41;; // make arrow thicker
putShape&#40;arrow, ColorRGBA.Red&#41;.setLocalTranslation&#40;pos&#41;; putShape&#40;arrow, ColorRGBA.Red&#41;.setLocalTranslation&#40;pos&#41;;
@ -59,17 +28,9 @@ private Geometry putShape&#40;Mesh shape, ColorRGBA color&#41;&#123;
g.setMaterial&#40;mat&#41;; g.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;g&#41;; rootNode.attachChild&#40;g&#41;;
return g; return g;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="wireframe_grid">Wireframe Grid</a></h3><div
class="level3"><p> Use a wireframe grid (com.jme3.scene.debug.Grid) as a ruler or simple floor.</p><pre>private void attachGrid&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
<h3><a>Wireframe Grid</a></h3>
<div>
<p>
Use a wireframe grid (com.jme3.scene.debug.Grid) as a ruler or simple floor.
</p>
<pre>private void attachGrid&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
Geometry g = new Geometry&#40;&quot;wireframe grid&quot;, new Grid&#40;size, size, 0.2f&#41; &#41;; Geometry g = new Geometry&#40;&quot;wireframe grid&quot;, new Grid&#40;size, size, 0.2f&#41; &#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;; mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;;
@ -78,17 +39,9 @@ Use a wireframe grid (com.jme3.scene.debug.Grid) as a ruler or simple floor.
g.center&#40;&#41;.move&#40;pos&#41;; g.center&#40;&#41;.move&#40;pos&#41;;
rootNode.attachChild&#40;g&#41;; rootNode.attachChild&#40;g&#41;;
return g; return g;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="wireframe_cube">Wireframe Cube</a></h3><div
class="level3"><p> Use a wireframe cube (com.jme3.scene.debug.WireBox) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.</p><pre>public void attachWireBox&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
<h3><a>Wireframe Cube</a></h3>
<div>
<p>
Use a wireframe cube (com.jme3.scene.debug.WireBox) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.
</p>
<pre>public void attachWireBox&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
Geometry g = new Geometry&#40;&quot;wireframe cube&quot;, new WireBox&#40;size, size, size&#41;&#41;; Geometry g = new Geometry&#40;&quot;wireframe cube&quot;, new WireBox&#40;size, size, size&#41;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;; mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;;
@ -97,17 +50,9 @@ Use a wireframe cube (com.jme3.scene.debug.WireBox) as a stand-in object to see
g.setLocalTranslation&#40;pos&#41;; g.setLocalTranslation&#40;pos&#41;;
rootNode.attachChild&#40;g&#41;; rootNode.attachChild&#40;g&#41;;
return g; return g;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="wireframe_sphere">Wireframe Sphere</a></h3><div
class="level3"><p> Use a wireframe sphere (com.jme3.scene.debug.WireSphere) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.</p><pre>private void attachWireSphere&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
<h3><a>Wireframe Sphere</a></h3>
<div>
<p>
Use a wireframe sphere (com.jme3.scene.debug.WireSphere) as a stand-in object to see whether your code scales, positions, or orients, loaded models right.
</p>
<pre>private void attachWireSphere&#40;Vector3f pos, float size, ColorRGBA color&#41;&#123;
Geometry g = new Geometry&#40;&quot;wireframe sphere&quot;, new WireSphere&#40;size&#41;&#41;; Geometry g = new Geometry&#40;&quot;wireframe sphere&quot;, new WireSphere&#40;size&#41;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;; mat.getAdditionalRenderState&#40;&#41;.setWireframe&#40;true&#41;;
@ -116,52 +61,24 @@ Use a wireframe sphere (com.jme3.scene.debug.WireSphere) as a stand-in object to
g.setLocalTranslation&#40;pos&#41;; g.setLocalTranslation&#40;pos&#41;;
rootNode.attachChild&#40;g&#41;; rootNode.attachChild&#40;g&#41;;
return g; return g;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="wireframe_for_physics">Wireframe for Physics</a></h2><div
class="level2"><p> You can display a wireframe of the (usually invisible) collision shape around all physical objects. Use this for debugging when analyzing unexpected behaviour. Does not work with DETACHED physics, please switch to PARALLEL or SEQUENTIAL for debugging.</p><pre>physicsSpace.enableDebug&#40;assetManager&#41;;</pre></div><h2><a
<h2><a>Wireframe for Physics</a></h2> name="wireframe_for_animations">Wireframe for Animations</a></h2><div
<div> class="level2"><p> Making the skeleton visible inside animated models can be handy for debugging animations. The <code>control</code> object is an AnimControl, <code>player</code> is the loaded model.</p><pre> SkeletonDebugger skeletonDebug =
<p>
You can display a wireframe of the (usually invisible) collision shape around all physical objects. Use this for debugging when analyzing unexpected behaviour. Does not work with DETACHED physics, please switch to PARALLEL or SEQUENTIAL for debugging.
</p>
<pre>physicsSpace.enableDebug&#40;assetManager&#41;;</pre>
</div>
<h2><a>Wireframe for Animations</a></h2>
<div>
<p>
Making the skeleton visible inside animated models can be handy for debugging animations. The <code>control</code> object is an AnimControl, <code>player</code> is the loaded model.
</p>
<pre> SkeletonDebugger skeletonDebug =
new SkeletonDebugger&#40;&quot;skeleton&quot;, control.getSkeleton&#40;&#41;&#41;; new SkeletonDebugger&#40;&quot;skeleton&quot;, control.getSkeleton&#40;&#41;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Green&#41;; mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Green&#41;;
mat.getAdditionalRenderState&#40;&#41;.setDepthTest&#40;false&#41;; mat.getAdditionalRenderState&#40;&#41;.setDepthTest&#40;false&#41;;
skeletonDebug.setMaterial&#40;mat&#41;; skeletonDebug.setMaterial&#40;mat&#41;;
player.attachChild&#40;skeletonDebug&#41;;</pre> player.attachChild&#40;skeletonDebug&#41;;</pre></div><h2><a
</div> name="exampletoggle_wireframe_on_model">Example: Toggle Wireframe on Model</a></h2><div
class="level2"><p> We assume that you have loaded a model with a material <code>mat</code>.</p><p> Then you can add a switch to toggle the model&#039;s wireframe on and off, like this:</p><ol><li
<h2><a>Example: Toggle Wireframe on Model</a></h2> class="level1"><div
<div> class="li"> Create a key input trigger that switches between the two materials: E.g. we toggle when the T key is pressed:<pre> inputManager.addMapping&#40;&quot;toggle wireframe&quot;, new KeyTrigger&#40;KeyInput.KEY_T&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;toggle wireframe&quot;&#41;;</pre></div></li><li
<p> class="level1"><div
class="li"> Now add the toggle action to the action listener<pre> private ActionListener&#40;&#41; &#123;
We assume that you have loaded a model with a material <code>mat</code>.
</p>
<p>
Then you can add a switch to toggle the model&#039;s wireframe on and off, like this:
</p>
<ol>
<li><div> Create a key input trigger that switches between the two materials: E.g. we toggle when the T key is pressed: <pre> inputManager.addMapping&#40;&quot;toggle wireframe&quot;, new KeyTrigger&#40;KeyInput.KEY_T&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;toggle wireframe&quot;&#41;;</pre></div>
</li>
<li><div> Now add the toggle action to the action listener <pre> private ActionListener&#40;&#41; &#123;
@Override @Override
public void onAction&#40;String name, boolean pressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean pressed, float tpf&#41; &#123;
// toggle wireframe // toggle wireframe
@ -171,9 +88,5 @@ Then you can add a switch to toggle the model&#039;s wireframe on and off, like
&#125; &#125;
// else ... other input tests. // else ... other input tests.
&#125; &#125;
&#125;;</pre></div> &#125;;</pre></div></li></ol></div>
</li>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:debugging?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:debugging?do=export_xhtmlbody">view online version</a></em></p>

@ -1,266 +1,92 @@
<h1><a
<h1><a>jME3 Effects -- Overview</a></h1> name="jme3_effects_--_overview">jME3 Effects -- Overview</a></h1><div
<div> class="level1"><p> <br/></p><p> jME3 supports various post-rendering and particle effects. This list contains screenshots and sample code that demonstrates how to add the effect to a scene.</p><p> <br/></p></div><h2><a
name="d_filter_effects">2D Filter Effects</a></h2><div
<p> class="level2"></div><h3><a
name="screen_space_ambient_occlusion">Screen Space Ambient Occlusion</a></h3><div
<br/> class="level3"><p> <a
href="/wiki/lib/exe/fetch.php?hash=500208&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F08%2Fssao-article.png"><img
</p> src="/wiki/lib/exe/fetch.php?hash=500208&amp;w=150&amp;h=100&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F08%2Fssao-article.png" class="mediaright" align="right" alt="" width="150" height="100" /></a></p><p> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestSSAO.java">jme3/src/test/jme3test/post/TestSSAO.java</a></p><p> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestSSAO2.java">jme3/src/test/jme3test/post/TestSSAO2.java</a></p><p> <a
jME3 supports various post-rendering and particle effects. This list contains screenshots and sample code that demonstrates how to add the effect to a scene. href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestTransparentSSAO.java">jme3/src/test/jme3test/post/TestTransparentSSAO.java</a></p><p> <a
</p> href="http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/#more-321">Screen Space Ambient Occlusion for jMonkeyEngine</a> (article)</p><p> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:light-scattering-filter.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-scattering-filter.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p></div><h3><a
<br/> name="light_scattering">Light Scattering</a></h3><div
class="level3"><p> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestLightScattering.java">jme3/src/test/jme3test/post/TestLightScattering.java</a></p></div><h3><a
name="bloom">Bloom</a></h3><div
</div> class="level3"><p> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestBloom.java">jme3/src/test/jme3test/post/TestBloom.java</a></p><p> <a
<h2><a>2D Filter Effects</a></h2> href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a></p><p> <a
<div> href="/wiki/lib/exe/detail.php/jme3:advanced:toon-dino.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/toon-dino.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p></div><h3><a
</div> name="toon_effect">Toon Effect</a></h3><div
class="level3"><p> <a
<h3><a>Screen Space Ambient Occlusion</a></h3> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestCartoonEdge.java">jme3/src/test/jme3test/post/TestCartoonEdge.java</a></p><p> <a
<div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestTransparentCartoonEdge.java">jme3/src/test/jme3test/post/TestTransparentCartoonEdge.java</a></p></div><h3><a
name="depth_of_field_blur">Depth of Field Blur</a></h3><div
<p> class="level3"><p> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:dof-blur.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
<img src="/wiki/lib/exe/fetch.php"> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/dof-blur.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p><p> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestDepthOfField.java">jme3/src/test/jme3test/post/TestDepthOfField.java</a></p></div><h3><a
name="fog">Fog</a></h3><div
<p> class="level3"><p> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestSSAO.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestSSAO.java</u></html>"><param name="textColor" value="blue"></object> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestFog.java">jme3/src/test/jme3test/post/TestFog.java</a> (temporary workaround, will be deprecated)</p><p> <a
</p> href="/wiki/lib/exe/detail.php/jme3:advanced:light-sources.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-sources.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p></div><h2><a
<p> name="lighting_and_shadows">Lighting and Shadows</a></h2><div
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestSSAO2.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestSSAO2.java</u></html>"><param name="textColor" value="blue"></object> class="level2"><p> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestSimpleLighting.java">jme3/src/test/jme3test/light/TestSimpleLighting.java</a></p><p> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestLightRadius.java">jme3/src/test/jme3test/light/TestLightRadius.java</a></p><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:shadow.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestTransparentSSAO.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestTransparentSSAO.java</u></html>"><param name="textColor" value="blue"></object> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/shadow.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p><p> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestManyLights.java">jme3/src/test/jme3test/light/TestManyLights.java</a></p><p> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestShadow.java">jme3/src/test/jme3test/light/TestShadow.java</a></p><p> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestPssmShadow.java">jme3/src/test/jme3test/light/TestPssmShadow.java</a> = Parallel-Split Shadow Mapping (PSSM)</p></div><h2><a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/2010/08/16/screen-space-ambient-occlusion-for-jmonkeyengine-3-0/#more-321"><param name="text" value="<html><u>Screen Space Ambient Occlusion for jMonkeyEngine</u></html>"><param name="textColor" value="blue"></object> (article) name="water">Water</a></h2><div
</p> class="level2"><p> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:water.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p><p> <a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-scattering-filter.png"> href="/com/jme3/gde/core/docs/jme3/advanced/water.html">&quot;SeaMonkey&quot; water</a></p><ul><li
</p> class="level1"><div
class="li"> <a
</div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSceneWater.java">jme3/src/test/jme3test/water/TestSceneWater.java</a></div></li></ul><ul><li
class="level1"><div
<h3><a>Light Scattering</a></h3> class="li"> <a
<div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSimpleWater.java">jme3/src/test/jme3test/water/TestSimpleWater.java</a></div></li></ul><p> <a
href="http://jmonkeyengine.org/2011/01/15/new-advanced-water-effect-for-jmonkeyengine-3/#comment-609">Rendering Water as Post-Process Effect</a></p><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:water-post.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water-post.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p><ul><li
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestLightScattering.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestLightScattering.java</u></html>"><param name="textColor" value="blue"></object> class="level1"><div
</p> class="li"> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWater.java">jme3/src/test/jme3test/water/TestPostWater.java</a></div></li></ul><ul><li
</div> class="level1"><div
class="li"> <a
<h3><a>Bloom</a></h3> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWaterLake.java">jme3/src/test/jme3test/water/TestPostWaterLake.java</a></div></li></ul><p> <br/></p><p> <br/></p></div><h2><a
<div> name="special_effects">Special Effects</a></h2><div
class="level2"><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:explosion-5.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/explosion-5.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestBloom.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestBloom.java</u></html>"><param name="textColor" value="blue"></object> href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a></p></div><h3><a
</p> name="particlesexplosions_fire">Particles: Explosions, Fire</a></h3><div
class="level3"><p> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestExplosionEffect.java">jme3/src/test/jme3test/effect/TestExplosionEffect.java</a> – debris, flame, flash, shockwave, smoke, sparks</p><p> <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestParticleEmitter.java">jme3/src/test/jme3test/effect/TestParticleEmitter.java</a></p><p> <a
</p> href="/wiki/lib/exe/detail.php/jme3:advanced:particle.png?id=jme3%3Aadvanced%3Aeffects_overview"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/particle.png?w=150&amp;h=100" class="mediaright" align="right" alt="" width="150" height="100" /></a></p></div><h3><a
<p> name="particlessmoke">Particles: Smoke</a></h3><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/toon-dino.png"> class="level3"><p> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestMovingParticle.java">jme3/src/test/jme3test/effect/TestMovingParticle.java</a></p><p> Particles can have any texture, e.g. fog, leaves, meteors, snowflakes, mosquitos</p><hr
/><p> See also:</p><ul><li
</div> class="level1"><div
class="li"> <a
<h3><a>Toon Effect</a></h3> href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a></div></li><li
<div> class="level1"><div
class="li"> <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a></div></li><li
class="level1"><div
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestCartoonEdge.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestCartoonEdge.java</u></html>"><param name="textColor" value="blue"></object> class="li"> <a
</p> href="http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/">http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/</a></div></li></ul></div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestTransparentCartoonEdge.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestTransparentCartoonEdge.java</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<h3><a>Depth of Field Blur</a></h3>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/dof-blur.png">
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestDepthOfField.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestDepthOfField.java</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<h3><a>Fog</a></h3>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/post/TestFog.java"><param name="text" value="<html><u>jme3/src/test/jme3test/post/TestFog.java</u></html>"><param name="textColor" value="blue"></object> (temporary workaround, will be deprecated)
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-sources.png">
</p>
</div>
<h2><a>Lighting and Shadows</a></h2>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestSimpleLighting.java"><param name="text" value="<html><u>jme3/src/test/jme3test/light/TestSimpleLighting.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestLightRadius.java"><param name="text" value="<html><u>jme3/src/test/jme3test/light/TestLightRadius.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/shadow.png">
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestManyLights.java"><param name="text" value="<html><u>jme3/src/test/jme3test/light/TestManyLights.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestShadow.java"><param name="text" value="<html><u>jme3/src/test/jme3test/light/TestShadow.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestPssmShadow.java"><param name="text" value="<html><u>jme3/src/test/jme3test/light/TestPssmShadow.java</u></html>"><param name="textColor" value="blue"></object> = Parallel-Split Shadow Mapping (PSSM)
</p>
</div>
<h2><a>Water</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water.png">
</p>
<p>
<a href="/com/jme3/gde/core/docs/jme3/advanced/water.html">&quot;SeaMonkey&quot; water</a>
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSceneWater.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestSceneWater.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSimpleWater.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestSimpleWater.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/2011/01/15/new-advanced-water-effect-for-jmonkeyengine-3/#comment-609"><param name="text" value="<html><u>Rendering Water as Post-Process Effect</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water-post.png">
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWater.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestPostWater.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWaterLake.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestPostWaterLake.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<p>
<br/>
</p>
<p>
<br/>
</p>
</div>
<h2><a>Special Effects</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/explosion-5.png">
<a href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a>
</p>
</div>
<h3><a>Particles: Explosions, Fire</a></h3>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestExplosionEffect.java"><param name="text" value="<html><u>jme3/src/test/jme3test/effect/TestExplosionEffect.java</u></html>"><param name="textColor" value="blue"></object> – debris, flame, flash, shockwave, smoke, sparks
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestParticleEmitter.java"><param name="text" value="<html><u>jme3/src/test/jme3test/effect/TestParticleEmitter.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/particle.png">
</p>
</div>
<h3><a>Particles: Smoke</a></h3>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/effect/TestMovingParticle.java"><param name="text" value="<html><u>jme3/src/test/jme3test/effect/TestMovingParticle.java</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
Particles can have any texture, e.g. fog, leaves, meteors, snowflakes, mosquitos
</p>
<hr />
<p>
See also:
</p>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a></div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/"><param name="text" value="<html><u>http://www.smashingmagazine.com/2008/08/07/50-photoshop-tutorials-for-sky-and-space-effects/</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:effects_overview?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:effects_overview?do=export_xhtmlbody">view online version</a></em></p>

@ -1,139 +1,55 @@
<h1><a
<h1><a>Physical Hinges and Joints</a></h1> name="physical_hinges_and_joints">Physical Hinges and Joints</a></h1><div
<div> class="level1"><p> The jMonkeyEngine3 has built-in support for <a
href="http://jbullet.advel.cz">jBullet physics</a> via the <code>com.jme3.bullet</code> package.</p><p> Game Physics are not only employed to calculate collisions, but they can also simulate hinges and joints. Think of pulley chains, shaky rope bridges, swinging pendulums, or (trap)door and chest hinges. Physics are a great addition to e.g. an action or puzzle game.</p><p> In this example, we will create a pendulum. The joint is the (invisible) connection between the pendulum body and the hook. You will see that you can use what you learn from the simple pendulum and apply it to other joint/hinge objects (rope bridges, etc).</p></div><h2><a
<p> name="sample_code">Sample Code</a></h2><div
class="level2"><ul><li
The jMonkeyEngine3 has built-in support for <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jbullet.advel.cz"><param name="text" value="<html><u>jBullet physics</u></html>"><param name="textColor" value="blue"></object> via the <code>com.jme3.bullet</code> package. class="level1"><div
</p> class="li"> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsHingeJoint.java">TestPhysicsHingeJoint.java</a></div></li></ul></div><h2><a
<p> name="overview_of_this_physics_application">Overview of this Physics Application</a></h2><div
Game Physics are not only employed to calculate collisions, but they can also simulate hinges and joints. Think of pulley chains, shaky rope bridges, swinging pendulums, or (trap)door and chest hinges. Physics are a great addition to e.g. an action or puzzle game. class="level2"><ol><li
</p> class="level1"><div
class="li"> Create a SimpleApplication with a <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a></div><ul><li
In this example, we will create a pendulum. The joint is the (invisible) connection between the pendulum body and the hook. You will see that you can use what you learn from the simple pendulum and apply it to other joint/hinge objects (rope bridges, etc). class="level2"><div
</p> class="li"> This gives us a PhysicsSpace for PhysicsControls</div></li></ul></li><li
class="level1"><div
</div> class="li"> For the pendulum, we use a Spatial with a PhysicsControl, and we apply physical forces to them.</div><ul><li
class="level2"><div
<h2><a>Sample Code</a></h2> class="li"> The parts of the &quot;pendulum&quot; are Physics Control&#039;ed Spatials with Collision Shapes.</div></li><li
<div> class="level2"><div
<ul> class="li"> We create a fixed <code>hookNode</code> and a dynamic <code>pendulumNode</code>.</div></li></ul></li><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsHingeJoint.java"><param name="text" value="<html><u>TestPhysicsHingeJoint.java</u></html>"><param name="textColor" value="blue"></object></div> class="level1"><div
</li> class="li"> We can &quot;crank the handle&quot; and rotate the joint like a hinge, or we can let loose and expose the joints freely to gravity.</div><ul><li
</ul> class="level2"><div
class="li"> For physical forces we will use the method <code>joint.enableMotor();</code></div></li></ul></li></ol></div><h2><a
</div> name="creating_a_fixed_node">Creating a Fixed Node</a></h2><div
class="level2"><p> The hookNode is the fixed point from which the pendulum hangs. It has no mass.</p><pre>Node hookNode=PhysicsTestHelper.createPhysicsTestNode&#40;assetManager, new BoxCollisionShape&#40;new Vector3f&#40; .1f, .1f, .1f&#41;&#41;,0&#41;;
<h2><a>Overview of this Physics Application</a></h2>
<div>
<ol>
<li><div> Create a SimpleApplication with a <a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a> </div>
<ul>
<li><div> This gives us a PhysicsSpace for PhysicsControls</div>
</li>
</ul>
</li>
<li><div> For the pendulum, we use a Spatial with a PhysicsControl, and we apply physical forces to them.</div>
<ul>
<li><div> The parts of the “pendulum” are Physics Control&#039;ed Spatials with Collision Shapes. </div>
</li>
<li><div> We create a fixed <code>hookNode</code> and a dynamic <code>pendulumNode</code>. </div>
</li>
</ul>
</li>
<li><div> We can “crank the handle” and rotate the joint like a hinge, or we can let loose and expose the joints freely to gravity. </div>
<ul>
<li><div> For physical forces we will use the method <code>joint.enableMotor();</code></div>
</li>
</ul>
</li>
</ol>
</div>
<h2><a>Creating a Fixed Node</a></h2>
<div>
<p>
The hookNode is the fixed point from which the pendulum hangs. It has no mass.
</p>
<pre>Node hookNode=PhysicsTestHelper.createPhysicsTestNode&#40;assetManager, new BoxCollisionShape&#40;new Vector3f&#40; .1f, .1f, .1f&#41;&#41;,0&#41;;
hookNode.getControl&#40;RigidBodyControl.class&#41;.setPhysicsLocation&#40;new Vector3f&#40;0f,0,0f&#41;&#41;; hookNode.getControl&#40;RigidBodyControl.class&#41;.setPhysicsLocation&#40;new Vector3f&#40;0f,0,0f&#41;&#41;;
&nbsp; &nbsp;
rootNode.attachChild&#40;hookNode&#41;; rootNode.attachChild&#40;hookNode&#41;;
getPhysicsSpace&#40;&#41;.add&#40;hookNode&#41;;</pre> getPhysicsSpace&#40;&#41;.add&#40;hookNode&#41;;</pre><p> For a rope bridge, there would be two fixed nodes where the bridge is attached to the mountainside.</p></div><h2><a
<p> name="creating_a_dynamic_node">Creating a Dynamic Node</a></h2><div
For a rope bridge, there would be two fixed nodes where the bridge is attached to the mountainside. class="level2"><p> The pendulumNode is the dynamic part of the construction. It has a mass.</p><pre>Node pendulumNode=PhysicsTestHelper.createPhysicsTestNode&#40;assetManager, new BoxCollisionShape&#40;new Vector3f&#40; .3f, .3f, .3f&#41;&#41;,1&#41;;
</p>
</div>
<h2><a>Creating a Dynamic Node</a></h2>
<div>
<p>
The pendulumNode is the dynamic part of the construction. It has a mass.
</p>
<pre>Node pendulumNode=PhysicsTestHelper.createPhysicsTestNode&#40;assetManager, new BoxCollisionShape&#40;new Vector3f&#40; .3f, .3f, .3f&#41;&#41;,1&#41;;
pendulumNode.getControl&#40;RigidBodyControl.class&#41;.setPhysicsLocation&#40;new Vector3f&#40;0f,-1,0f&#41;&#41;; pendulumNode.getControl&#40;RigidBodyControl.class&#41;.setPhysicsLocation&#40;new Vector3f&#40;0f,-1,0f&#41;&#41;;
rootNode.attachChild&#40;pendulumNode&#41;; rootNode.attachChild&#40;pendulumNode&#41;;
getPhysicsSpace&#40;&#41;.add&#40;pendulumNode&#41;;</pre> getPhysicsSpace&#40;&#41;.add&#40;pendulumNode&#41;;</pre><p> For a rope bridge, each set of planks would be one dynamic node.</p></div><h2><a
<p> name="understanding_dof_joints_and_hinges">Understanding DOF, Joints, and Hinges</a></h2><div
For a rope bridge, each set of planks would be one dynamic node. class="level2"><p> A PhysicsHingeJoint is an invisible connection between two nodes – here between the pendulum body and the hook. Why are hinges and joints represented by the same class? Hinges and joints have something in common: They constrain the <em>mechanical degree of freedom</em> (DOF) of another object.</p><p> Consider a free falling, &quot;unchained&quot; object in physical 3D space: It has 6 DOFs:</p><ul><li
</p> class="level1"><div
class="li"> It translates along 3 axes</div></li><li
</div> class="level1"><div
class="li"> It rotates around 3 axes</div></li></ul><p> Now consider some examples of objects with joints:</p><ul><li
<h2><a>Understanding DOF, Joints, and Hinges</a></h2> class="level1"><div
<div> class="li"> An individual chain link is free to spin and move around, but joined into a chain, the link&#039;s movement is restricted to stay with the surrounding links.</div></li><li
class="level1"><div
<p> class="li"> A person&#039;s arm can rotate around some axes, but not around others. The shoulder joint allows one and restricts the other.</div></li><li
class="level1"><div
A PhysicsHingeJoint is an invisible connection between two nodes – here between the pendulum body and the hook. Why are hinges and joints represented by the same class? Hinges and joints have something in common: They constrain the <em>mechanical degree of freedom</em> (DOF) of another object. class="li"> A door hinge is one of the most restricted types of joint: It can only rotate around one axis.</div></li></ul><p> You&#039;ll understand that, when creating any type of joint, it is important to correctly specify the DOFs that the joint restricts, and the DOFs that the joint allows. For the typical DOF of a <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/ragdoll.html">ragDoll</a> character&#039;s limbs, jME even offers a special joint, <code>PhysicsConeJoint</code>.</p></div><h2><a
name="creating_the_joint">Creating the Joint</a></h2><div
<p> class="level2"><p> You create the PhysicsHingeJoint after you have created the nodes that are to be chained together. In the code snippet you see that the PhysicsHingeJoint constructor requires the two node objects. You also have to specify axes and pivots – they are the degrees of freedom that you just heard about.</p><pre>private HingeJoint joint;
Consider a free falling, “unchained” object in physical 3D space: It has 6 DOFs:
</p>
<ul>
<li><div> It translates along 3 axes</div>
</li>
<li><div> It rotates around 3 axes</div>
</li>
</ul>
<p>
Now consider some examples of objects with joints:
</p>
<ul>
<li><div> An individual chain link is free to spin and move around, but joined into a chain, the link&#039;s movement is restricted to stay with the surrounding links.</div>
</li>
<li><div> A person&#039;s arm can rotate around some axes, but not around others. The shoulder joint allows one and restricts the other.</div>
</li>
<li><div> A door hinge is one of the most restricted types of joint: It can only rotate around one axis. </div>
</li>
</ul>
<p>
You&#039;ll understand that, when creating any type of joint, it is important to correctly specify the DOFs that the joint restricts, and the DOFs that the joint allows. For the typical DOF of a <a href="/com/jme3/gde/core/docs/jme3/advanced/ragdoll.html">ragDoll</a> character&#039;s limbs, jME even offers a special joint, <code>PhysicsConeJoint</code>.
</p>
</div>
<h2><a>Creating the Joint</a></h2>
<div>
<p>
You create the PhysicsHingeJoint after you have created the nodes that are to be chained together. In the code snippet you see that the PhysicsHingeJoint constructor requires the two node objects. You also have to specify axes and pivots – they are the degrees of freedom that you just heard about.
</p>
<pre>private HingeJoint joint;
... ...
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
... ...
@ -145,72 +61,26 @@ You create the PhysicsHingeJoint after you have created the nodes that are to be
new Vector3f&#40;0f, 0f, 0f&#41;, // pivot point of A new Vector3f&#40;0f, 0f, 0f&#41;, // pivot point of A
new Vector3f&#40;0f,-1f, 0f&#41;, // pivot point of B new Vector3f&#40;0f,-1f, 0f&#41;, // pivot point of B
Vector3f.UNIT_Z, // DoF Axis of A (Z axis) Vector3f.UNIT_Z, // DoF Axis of A (Z axis)
Vector3f.UNIT_Z &#41;; // DoF Axis of B (Z axis)</pre> Vector3f.UNIT_Z &#41;; // DoF Axis of B (Z axis)</pre><p> Specify the following parameters for each joint:</p><ul><li
<p> class="level1"><div
Specify the following parameters for each joint: class="li"> PhysicsControl A and B – the two nodes that are to be joined</div></li><li
</p> class="level1"><div
<ul> class="li"> Vector3f pivot A and pivot B – coordinates of the two attachment points</div><ul><li
<li><div> PhysicsControl A and B – the two nodes that are to be joined</div> class="level2"><div
</li> class="li"> The points typically lie on the surface of the PhysicsControl&#039;s Spatials, rarely in the middle.</div></li></ul></li><li
<li><div> Vector3f pivot A and pivot B – coordinates of the two attachment points</div> class="level1"><div
<ul> class="li"> Vector3f axisA and axisB – around which axes each node is allowed to spin.</div><ul><li
<li><div> The points typically lie on the surface of the PhysicsControl&#039;s Spatials, rarely in the middle.</div> class="level2"><div
</li> class="li"> In our example, we constrain the pendulum to swing only along the Z axis.</div></li></ul></li></ul><p> Remember to add all joint objects to the physicsSpace, just like you would do with any physical objects.</p><pre>bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;joint&#41;;</pre><p> <strong>Tip:</strong> If you want the joint to be visible, attach a geometry to the dynamic node, and translate it to its start position.</p></div><h2><a
</ul> name="apply_physical_forces">Apply Physical Forces</a></h2><div
</li> class="level2"><p> You can apply forces to dynamic nodes (the ones that have a mass), and see how other joined (&quot;chained&quot;) objects are dragged along.</p><p> Alternatively, you can also apply forces to the joint itself. In a game, you may want to spin an automatic revolving door, or slam a door closed in a spooky way, or dramatically open the lid of a treasure chest.</p><p> The method to call on the joint is <code>enableMotor()</code>.</p><pre>joint.enableMotor&#40;true, 1, .1f&#41;;
<li><div> Vector3f axisA and axisB – around which axes each node is allowed to spin.</div> joint.enableMotor&#40;true, -1, .1f&#41;;</pre><ol><li
<ul> class="level1"><div
<li><div> In our example, we constrain the pendulum to swing only along the Z axis.</div> class="li"> Switch the motor on by supplying <code>true</code></div></li><li
</li> class="level1"><div
</ul> class="li"> Specify the velocity with which the joint should rotate around the specified axis.</div><ul><li
</li> class="level2"><div
</ul> class="li"> Use positive and negative numbers to change direction.</div></li></ul></li><li
class="level1"><div
<p> class="li"> Specify the impulse for this motor. Heavier masses need a bigger impulse to be moved.</div></li></ol><p> When you disable the motor, the chained nodes are exposed to gravity again:</p><pre>joint.enableMotor&#40;false, 0, 0&#41;;</pre></div>
Remember to add all joint objects to the physicsSpace, just like you would do with any physical objects.
</p>
<pre>bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;joint&#41;;</pre>
<p>
<strong>Tip:</strong> If you want the joint to be visible, attach a geometry to the dynamic node, and translate it to its start position.
</p>
</div>
<h2><a>Apply Physical Forces</a></h2>
<div>
<p>
You can apply forces to dynamic nodes (the ones that have a mass), and see how other joined (“chained”) objects are dragged along.
</p>
<p>
Alternatively, you can also apply forces to the joint itself. In a game, you may want to spin an automatic revolving door, or slam a door closed in a spooky way, or dramatically open the lid of a treasure chest.
</p>
<p>
The method to call on the joint is <code>enableMotor()</code>.
</p>
<pre>joint.enableMotor&#40;true, 1, .1f&#41;;
joint.enableMotor&#40;true, -1, .1f&#41;;</pre><ol>
<li><div> Switch the motor on by supplying <code>true</code></div>
</li>
<li><div> Specify the velocity with which the joint should rotate around the specified axis. </div>
<ul>
<li><div> Use positive and negative numbers to change direction.</div>
</li>
</ul>
</li>
<li><div> Specify the impulse for this motor. Heavier masses need a bigger impulse to be moved.</div>
</li>
</ol>
<p>
When you disable the motor, the chained nodes are exposed to gravity again:
</p>
<pre>joint.enableMotor&#40;false, 0, 0&#41;;</pre>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:hinges_and_joints?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:hinges_and_joints?do=export_xhtmlbody">view online version</a></em></p>

@ -1,185 +1,87 @@
<h1><a
<h1><a>Head-Up Display (HUD)</a></h1> name="head-up_display_hud">Head-Up Display (HUD)</a></h1><div
<div> class="level1"><p> A HUD (Head-Up Display) is part of a game&#039;s visual user interface. It&#039;s an overlay that displays additional information as (typically) 2-dimensional text or icons on the screen, on top of the 3D scene.</p><p> HUDs are used to supply players with essential information about the game state.</p><ul><li
class="level1"><div
<p> class="li"> Status: Score, minimap, points, stealth mode, …</div></li><li
class="level1"><div
A HUD (Head-Up Display) is part of a game&#039;s visual user interface. It&#039;s an overlay that displays additional information as (typically) 2-dimensional text or icons on the screen, on top of the 3D scene. class="li"> Resources: Ammunition, lives/health, time, …</div></li><li
</p> class="level1"><div
class="li"> Vehicle instruments: Cockpit, speedometer, …</div></li><li
<p> class="level1"><div
HUDs are used to supply players with essential information about the game state. class="li"> Navigational aides: Crosshairs, cursor, hand, …</div></li></ul><p> <a
</p> href="/wiki/lib/exe/fetch.php?hash=c9f2a3&amp;media=http%3A%2F%2Fwww.jmonkeyengine.com%2Fwp-content%2Fuploads%2F2010%2F10%2Fgrapplinghook.jpg"><img
<ul> src="/wiki/lib/exe/fetch.php?hash=c9f2a3&amp;w=256&amp;h=192&amp;media=http%3A%2F%2Fwww.jmonkeyengine.com%2Fwp-content%2Fuploads%2F2010%2F10%2Fgrapplinghook.jpg" class="mediaright" align="right" title="www.jmonkeyengine.com_wp-content_uploads_2010_10_grapplinghook.jpg" alt="www.jmonkeyengine.com_wp-content_uploads_2010_10_grapplinghook.jpg" width="256" height="192" /></a></p><p> Not all games have, or need a HUD. To avoid breaking the immersion and cluttering the screen, only use a HUD if it is the only way to convey certain information.</p><p> You have two options how to create HUDs.</p><ul><li
<li><div> Status: Score, minimap, points, stealth mode, …</div> class="level1"><div
</li> class="li"> To create full-featured user interfaces, you use Nifty <acronym
<li><div> Resources: Ammunition, lives/health, time, …</div> title="Graphical User Interface">GUI</acronym>. (Recommended)</div></li><li
</li> class="level1"><div
<li><div> Vehicle instruments: Cockpit, speedometer, …</div> class="li"> If you just quickly want to display a line of text or an icon, you use the guiNode.</div></li></ul></div><h2><a
</li> name="hud_with_nifty_gui">HUD with Nifty GUI</a></h2><div
<li><div> Navigational aides: Crosshairs, cursor, hand, …</div> class="level2"><p> The recommended approach to create HUDs is using Nifty <acronym
</li> title="Graphical User Interface">GUI</acronym>.</p><ol><li
</ul> class="level1"><div
class="li"> Lay out the <acronym
<p> title="Graphical User Interface">GUI</acronym> in one or several Nifty <acronym
title="Extensible Markup Language">XML</acronym> files.</div></li><li
<img src="/wiki/lib/exe/fetch.php"> class="level1"><div
</p> class="li"> Write the controller classes in Java.</div></li><li
class="level1"><div
<p> class="li"> Load the <acronym
Not all games have, or need a HUD. To avoid breaking the immersion and cluttering the screen, only use a HUD if it is the only way to convey certain information. title="Extensible Markup Language">XML</acronym> file with the controller object in your game&#039;s simpleInit() method.</div></li></ol><p> The advantage of Nifty <acronym
</p> title="Graphical User Interface">GUI</acronym> is that it is well integrated into jME and the jMonkeyPlatform, and that it offers all the features that you expect from a professional modern user interface. The only small disadvantage is that you (currently still) have to lay out the interface in <acronym
title="Extensible Markup Language">XML</acronym>. You can see this as an advantage too, as it enables you to edit the user interface without editing the code afterwards.</p><p> For HUDs, you Basically follow the same instructions as for creating a normal <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a>, you just don&#039;t pause the game while the HUD is up.</p></div><h2><a
You have two options how to create HUDs. name="the_gui_node">The GUI Node</a></h2><div
</p> class="level2"><p> Using the <acronym
<ul> title="Graphical User Interface">GUI</acronym> Node is the default approach in jme3 to create very simple, static HUDs. If you just quickly want to display a line of text, or a simple icon on the screen, use this no-frills method. If you want a more advanced HUD with effects and interaction, use <a
<li><div> To create full-featured user interfaces, you use Nifty <acronym title="Graphical User Interface">GUI</acronym>. (Recommended)</div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a>.</p><p> Next to the rootNode for the 3-dimensional scene graph, jME3 also offers a 2-dimension (orthogonal) node, the <code>guiNode</code>. This is how you use it for HUDs:</p><ul><li
</li> class="level1"><div
<li><div> If you just quickly want to display a line of text or an icon, you use the guiNode.</div> class="li"> Create a <acronym
</li> title="Graphical User Interface">GUI</acronym> element (text or image).</div></li><li
</ul> class="level1"><div
class="li"> Attach the <acronym
</div> title="Graphical User Interface">GUI</acronym> element to the guiNode.</div></li><li
class="level1"><div
<h2><a>HUD with Nifty GUI</a></h2> class="li"> Place the <acronym
<div> title="Graphical User Interface">GUI</acronym> element in the orthogonal render queue using <code>setQueueBucket(Bucket.Gui)</code>.</div></li></ul><p> The element appears as 2-D, static element on the screen.</p><p> By default, the guiNode has some scene graph statistics attached in SimpleApplication. To clear the guiNode and attach your own <acronym
title="Graphical User Interface">GUI</acronym> elements, you detach all children.</p><pre>guiNode.detachAllChildren&#40;&#41;;</pre></div><h3><a
<p> name="displaying_pictures_in_the_hud">Displaying Pictures in the HUD</a></h3><div
class="level3"><p> A simple image can be displayed using <code>com.jme3.ui.Picture</code>.</p><pre>Picture pic = new Picture&#40;&quot;HUD Picture&quot;&#41;;
The recommended approach to create HUDs is using Nifty <acronym title="Graphical User Interface">GUI</acronym>.
</p>
<ol>
<li><div> Lay out the <acronym title="Graphical User Interface">GUI</acronym> in one or several Nifty <acronym title="Extensible Markup Language">XML</acronym> files. </div>
</li>
<li><div> Write the controller classes in Java.</div>
</li>
<li><div> Load the <acronym title="Extensible Markup Language">XML</acronym> file with the controller object in your game&#039;s simpleInit() method.</div>
</li>
</ol>
<p>
The advantage of Nifty <acronym title="Graphical User Interface">GUI</acronym> is that it is well integrated into jME and the jMonkeyPlatform, and that it offers all the features that you expect from a professional modern user interface. The only small disadvantage is that you (currently still) have to lay out the interface in <acronym title="Extensible Markup Language">XML</acronym>. You can see this as an advantage too, as it enables you to edit the user interface without editing the code afterwards.
</p>
<p>
For HUDs, you Basically follow the same instructions as for creating a normal <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a>, you just don&#039;t pause the game while the HUD is up.
</p>
</div>
<h2><a>The GUI Node</a></h2>
<div>
<p>
Using the <acronym title="Graphical User Interface">GUI</acronym> Node is the default approach in jme3 to create very simple, static HUDs. If you just quickly want to display a line of text, or a simple icon on the screen, use this no-frills method. If you want a more advanced HUD with effects and interaction, use <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a>.
</p>
<p>
Next to the rootNode for the 3-dimensional scene graph, jME3 also offers a 2-dimension (orthogonal) node, the <code>guiNode</code>. This is how you use it for HUDs:
</p>
<ul>
<li><div> Create a <acronym title="Graphical User Interface">GUI</acronym> element (text or image).</div>
</li>
<li><div> Attach the <acronym title="Graphical User Interface">GUI</acronym> element to the guiNode. </div>
</li>
<li><div> Place the <acronym title="Graphical User Interface">GUI</acronym> element in the orthogonal render queue using <code>setQueueBucket(Bucket.Gui)</code>. </div>
</li>
</ul>
<p>
The element appears as 2-D, static element on the screen.
</p>
<p>
By default, the guiNode has some scene graph statistics attached in SimpleApplication. To clear the guiNode and attach your own <acronym title="Graphical User Interface">GUI</acronym> elements, you detach all children.
</p>
<pre>guiNode.detachAllChildren&#40;&#41;;</pre>
</div>
<h3><a>Displaying Pictures in the HUD</a></h3>
<div>
<p>
A simple image can be displayed using <code>com.jme3.ui.Picture</code>.
</p>
<pre>Picture pic = new Picture&#40;&quot;HUD Picture&quot;&#41;;
pic.setImage&#40;assetManager, &quot;Textures/ColoredTex/Monkey.png&quot;, true&#41;; pic.setImage&#40;assetManager, &quot;Textures/ColoredTex/Monkey.png&quot;, true&#41;;
pic.setWidth&#40;settings.getWidth&#40;&#41;/2&#41;; pic.setWidth&#40;settings.getWidth&#40;&#41;/2&#41;;
pic.setHeight&#40;settings.getHeight&#40;&#41;/2&#41;; pic.setHeight&#40;settings.getHeight&#40;&#41;/2&#41;;
pic.setPosition&#40;settings.getWidth&#40;&#41;/4, settings.getHeight&#40;&#41;/4&#41;; pic.setPosition&#40;settings.getWidth&#40;&#41;/4, settings.getHeight&#40;&#41;/4&#41;;
guiNode.attachChild&#40;pic&#41;;</pre> guiNode.attachChild&#40;pic&#41;;</pre><p> When you set the last boolean in setImage() to true, the alpha channel of your image will be rendered transparent/translucent.</p></div><h3><a
<p> name="displaying_text_in_the_hud">Displaying Text in the HUD</a></h3><div
When you set the last boolean in setImage() to true, the alpha channel of your image will be rendered transparent/translucent. class="level3"><p> You use <code>com.jme3.font.BitmapText</code> to display text on the screen.</p><pre>BitmapText hudText = new BitmapText&#40;guiFont, false&#41;;
</p>
</div>
<h3><a>Displaying Text in the HUD</a></h3>
<div>
<p>
You use <code>com.jme3.font.BitmapText</code> to display text on the screen.
</p>
<pre>BitmapText hudText = new BitmapText&#40;guiFont, false&#41;;
hudText.setSize&#40;guiFont.getCharSet&#40;&#41;.getRenderedSize&#40;&#41;&#41;; // font size hudText.setSize&#40;guiFont.getCharSet&#40;&#41;.getRenderedSize&#40;&#41;&#41;; // font size
hudText.setColor&#40;ColorRGBA.Blue&#41;; // font color hudText.setColor&#40;ColorRGBA.Blue&#41;; // font color
hudText.setText&#40;&quot;You can write any string here&quot;&#41;; // the text hudText.setText&#40;&quot;You can write any string here&quot;&#41;; // the text
hudText.setLocalTranslation&#40;300, hudText.getLineHeight&#40;&#41;, 0&#41;; // position hudText.setLocalTranslation&#40;300, hudText.getLineHeight&#40;&#41;, 0&#41;; // position
guiNode.attachChild&#40;hudText&#41;;</pre> guiNode.attachChild&#40;hudText&#41;;</pre><p> The BitmapFont object <code>guiFont</code> is a default font provided by SimpleApplication. Copy you own fonts as .fnt+.png files into the <code>assets/Interface/Fonts</code> directory and load them like this:</p><pre>BitmapFont myFont = assetManager.loadFont(&quot;Interface/Fonts/Console.fnt&quot;);
<p> hudText = new BitmapText(myFont, false);</pre></div><h3><a
The BitmapFont object <code>guiFont</code> is a default font provided by SimpleApplication. Copy you own fonts as .fnt+.png files into the <code>assets/Interface/Fonts</code> directory and load them like this: name="displaying_geometries_in_the_hud">Displaying Geometries in the HUD</a></h3><div
</p> class="level3"><p> It is technically possible to attach Quads and 3D Geometries to the HUD. They show up as flat, static <acronym
<pre>BitmapFont myFont = assetManager.loadFont(&quot;Interface/Fonts/Console.fnt&quot;); title="Graphical User Interface">GUI</acronym> elements. Note that if you use a lit Material, you must add a light to the guiNode. Also remember that size units are pixels in the HUD (a 2-wu cube is displayed 2 pixels wide).</p></div><h3><a
hudText = new BitmapText(myFont, false);</pre> name="positioning_hud_elements">Positioning HUD Elements</a></h3><div
class="level3"><ul><li
</div> class="level1"><div
class="li"> When positioning text and images in 2D, the bottom left corner of the screen is <code>(0f,0f)</code>, and the top right corner is at <code>(settings.getWidth(),settings.getHeight())</code>.</div></li><li
<h3><a>Displaying Geometries in the HUD</a></h3> class="level1"><div
<div> class="li"> If you have several 2D elements in the <acronym
title="Graphical User Interface">GUI</acronym> bucket that overlap, define their depth order by specifing a Z value. You can use <code>pic.move(x, y, -2)</code> or <code>hudText.setLocalTranslation(x,y,-2)</code>.</div></li><li
<p> class="level1"><div
class="li"> Size and length values in the orthogonal render queue are treated like pixels. A 20*20-wu big quad is rendered 20 pixels wide.</div></li></ul></div><h3><a
It is technically possible to attach Quads and 3D Geometries to the HUD. They show up as flat, static <acronym title="Graphical User Interface">GUI</acronym> elements. Note that if you use a lit Material, you must add a light to the guiNode. Also remember that size units are pixels in the HUD (a 2-wu cube is displayed 2 pixels wide). name="keeping_the_hud_up-to-date">Keeping the HUD Up-To-Date</a></h3><div
</p> class="level3"><p> Use the update loop to keep the content up-to-date.</p><pre>public void simpleUpdate&#40;float tpf&#41; &#123;
</div>
<h3><a>Positioning HUD Elements</a></h3>
<div>
<ul>
<li><div> When positioning text and images in 2D, the bottom left corner of the screen is <code>(0f,0f)</code>, and the top right corner is at <code>(settings.getWidth(),settings.getHeight())</code>.</div>
</li>
<li><div> If you have several 2D elements in the <acronym title="Graphical User Interface">GUI</acronym> bucket that overlap, define their depth order by specifing a Z value. You can use <code>pic.move(x, y, -2)</code> or <code>hudText.setLocalTranslation(x,y,-2)</code>.</div>
</li>
<li><div> Size and length values in the orthogonal render queue are treated like pixels. A 20*20-wu big quad is rendered 20 pixels wide.</div>
</li>
</ul>
</div>
<h3><a>Keeping the HUD Up-To-Date</a></h3>
<div>
<p>
Use the update loop to keep the content up-to-date.
</p>
<pre>public void simpleUpdate&#40;float tpf&#41; &#123;
... ...
hudText.setText&#40;&quot;Score: &quot; + score&#41;; hudText.setText&#40;&quot;Score: &quot; + score&#41;;
... ...
picture.setImage&#40;assetManager, &quot;Interface/statechange.png&quot;, true&#41;; picture.setImage&#40;assetManager, &quot;Interface/statechange.png&quot;, true&#41;;
... ...
&#125;</pre><div><span> &#125;</pre><div
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, class="tags"><span> <a
<a href="/wiki/doku.php/tag:display?do=showtag&amp;tag=tag%3Adisplay">display</a>, href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, <a
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> href="/wiki/doku.php/tag:display?do=showtag&amp;tag=tag%3Adisplay">display</a>, <a
</span></div> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:hud?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:hud?do=export_xhtmlbody">view online version</a></em></p>

@ -1,192 +1,102 @@
<h1><a
<h1><a>Input Handling</a></h1> name="input_handling">Input Handling</a></h1><div
<div> class="level1"><p> Users interact with your jME3 application with different input devices – the mouse, the keyboard, or a joystick. To respond to inputs we use the <code>inputManager</code> object in <code>SimpleApplication</code>.</p><p> This is how you add interaction to your game:</p><ol><li
class="level1"><div
<p> class="li"> For each action, choose the trigger(s) (a key or mouse click etc)</div></li><li
class="level1"><div
Users interact with your jME3 application with different input devices – the mouse, the keyboard, or a joystick. To respond to inputs we use the <code>inputManager</code> object in <code>SimpleApplication</code>. class="li"> For each action, add a trigger mapping to the inputManager</div></li><li
</p> class="level1"><div
class="li"> Create at least one listener in SimpleApplication</div></li><li
<p> class="level1"><div
This is how you add interaction to your game: class="li"> For each action, register its mappings to a listener</div></li><li
class="level1"><div
</p> class="li"> Implement each action in the listener</div></li></ol></div><h2><a
<ol> name="choose_trigger">1. Choose Trigger</a></h2><div
<li><div> For each action, choose the trigger(s) (a key or mouse click etc)</div> class="level2"><p> Choose one or several key/mouse events for the interaction. We use <code>KeyTrigger</code>, <code>MouseAxisTrigger</code>, <code>MouseButtonTrigger</code>, <code>JoyAxisTrigger</code> and <code>JoyButtonTrigger</code> constants from the <code>com.jme3.input.controls</code> package.</p><p> The booleans are used to negate the axes: For inputs that have two axes (MouseAxis, JoyAxis), you have to listen to the negative (true) and positive (false) axis separately.</p><div
</li> class="table sectionedit1"><table
<li><div> For each action, add a trigger mapping to the inputManager</div> class="inline"><tr
</li> class="row0"><th
<li><div> Create at least one listener in SimpleApplication</div> class="col0"> Trigger</th><th
</li> class="col1"> Code</th></tr><tr
<li><div> For each action, register its mappings to a listener</div> class="row1"><td
</li> class="col0"> Mouse button: Left Click</td><td
<li><div> Implement each action in the listener</div> class="col1"> MouseButtonTrigger(MouseInput.BUTTON_LEFT)</td></tr><tr
</li> class="row2"><td
</ol> class="col0"> Mouse button: Right Click</td><td
class="col1"> MouseButtonTrigger(MouseInput.BUTTON_RIGHT)</td></tr><tr
</div> class="row3"><td
class="col0"> Mouse button: Middle Click</td><td
<h2><a>1. Choose Trigger</a></h2> class="col1"> MouseButtonTrigger(MouseInput.BUTTON_MIDDLE)</td></tr><tr
<div> class="row4"><td
class="col0"> Mouse movement:</td><td
<p> class="col1"> MouseAxisTrigger(MouseInput.AXIS_X, true), <br/> MouseAxisTrigger(MouseInput.AXIS_Y, true), <br/> MouseAxisTrigger(MouseInput.AXIS_X, false), <br/> MouseAxisTrigger(MouseInput.AXIS_Y, false)</td></tr><tr
class="row5"><td
Choose one or several key/mouse events for the interaction. We use <code>KeyTrigger</code>, <code>MouseAxisTrigger</code>, <code>MouseButtonTrigger</code>, <code>JoyAxisTrigger</code> and <code>JoyButtonTrigger</code> constants from the <code>com.jme3.input.controls</code> package. class="col0"> Mouse wheel:</td><td
</p> class="col1"> MouseAxisTrigger(MouseInput.AXIS_WHEEL,false) <br/> MouseAxisTrigger(MouseInput.AXIS_WHEEL,true)</td></tr><tr
class="row6"><td
<p> class="col0"> Keyboard: Characters and Numbers etc</td><td
The booleans are used to negate the axes: For inputs that have two axes (MouseAxis, JoyAxis), you have to listen to the negative (true) and positive (false) axis separately. class="col1"> KeyTrigger(KeyInput.KEY_X) etc</td></tr><tr
class="row7"><td
</p> class="col0 leftalign"> Keyboard: Spacebar</td><td
<table> class="col1"> KeyTrigger(KeyInput.KEY_SPACE)</td></tr><tr
<tr> class="row8"><td
<th> Trigger </th><th> Code </th> class="col0"> Keyboard: Shift</td><td
</tr> class="col1"> KeyTrigger(KeyInput.KEY_RSHIFT), <br/> KeyTrigger(KeyInput.KEY_LSHIFT)</td></tr><tr
<tr> class="row9"><td
<td> Mouse button: Left Click </td><td> MouseButtonTrigger(MouseInput.BUTTON_LEFT) </td> class="col0"> Keyboard: F1 etc</td><td
</tr> class="col1"> KeyTrigger(KeyInput.KEY_F1) etc</td></tr><tr
<tr> class="row10"><td
<td> Mouse button: Right Click </td><td> MouseButtonTrigger(MouseInput.BUTTON_RIGHT) </td> class="col0"> Keyboard: Return, Enter</td><td
</tr> class="col1 leftalign"> KeyTrigger(KeyInput.KEY_RETURN), <br/> KeyTrigger(KeyInput.KEY_NUMPADENTER)</td></tr><tr
<tr> class="row11"><td
<td> Mouse button: Middle Click </td><td> MouseButtonTrigger(MouseInput.BUTTON_MIDDLE) </td> class="col0"> Keyboard: PageUp, PageDown</td><td
</tr> class="col1"> KeyTrigger(KeyInput.KEY_PGUP), <br/> KeyTrigger(KeyInput.KEY_PGDN)</td></tr><tr
<tr> class="row12"><td
<td> Mouse movement: </td><td> MouseAxisTrigger(MouseInput.AXIS_X, true), <br/> class="col0"> Keyboard: Delete, Backspace</td><td
MouseAxisTrigger(MouseInput.AXIS_Y, true), <br/> class="col1"> KeyTrigger(KeyInput.KEY_BACK), <br/> KeyTrigger(KeyInput.KEY_DELETE)</td></tr><tr
MouseAxisTrigger(MouseInput.AXIS_X, false), <br/> class="row13"><td
MouseAxisTrigger(MouseInput.AXIS_Y, false) </td> class="col0"> Keyboard: Escape</td><td
</tr> class="col1"> KeyTrigger(KeyInput.KEY_ESCAPE)</td></tr><tr
<tr> class="row14"><td
<td> Mouse wheel: </td><td> MouseAxisTrigger(MouseInput.AXIS_WHEEL,false) <br/> class="col0"> Keyboard: Arrows</td><td
MouseAxisTrigger(MouseInput.AXIS_WHEEL,true) </td> class="col1"> KeyTrigger(KeyInput.KEY_DOWN), <br/> KeyTrigger(KeyInput.KEY_UP) <br/> KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT)</td></tr><tr
</tr> class="row15"><td
<tr> class="col0"> NumPad: Number 1 etc</td><td
<td> Keyboard: Characters and Numbers etc </td><td> KeyTrigger(KeyInput.KEY_X) etc </td> class="col1"> KeyTrigger(KeyInput.KEY_NUMPAD1) etc</td></tr><tr
</tr> class="row16"><td
<tr> class="col0"> Joystick: Button</td><td
<td> Keyboard: Spacebar </td><td> KeyTrigger(KeyInput.KEY_SPACE) </td> class="col1"> JoyButtonTrigger(0, JoyInput.AXIS_POV_X), <br/> JoyButtonTrigger(0, JoyInput.AXIS_POV_Y) ?</td></tr><tr
</tr> class="row17"><td
<tr> class="col0"> Joystick: Movement</td><td
<td> Keyboard: Shift </td><td> KeyTrigger(KeyInput.KEY_RSHIFT), <br/> class="col1"> JoyAxisTrigger(0, JoyInput.AXIS_POV_X, true), <br/> JoyAxisTrigger(0, JoyInput.AXIS_POV_X, false), <br/> JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, true), <br/> JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, false)</td></tr></table></div></div><h2><a
KeyTrigger(KeyInput.KEY_LSHIFT) </td> name="add_a_trigger_mapping">2. Add a Trigger Mapping</a></h2><div
</tr> class="level2"><p> When initializing the application, add a Mapping for each Trigger.</p><p> Give the mapping a meaningful name. The name should reflect the action, not the key, since the keys can change. Here some examples:</p><pre>inputManager.addMapping&#40;&quot;Pause Game&quot;, new KeyTrigger&#40;KeyInput.KEY_P&#41;&#41;;
<tr> inputManager.addMapping&#40;&quot;Rotate&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;</pre><p> There are cases where you may want more then one trigger for one action. For instance some users prefer the WASD keys to navigate, others prefer the arrow keys. You can define both by adding them after a comma.</p><pre>inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_A&#41;,
<td> Keyboard: F1 etc </td><td> KeyTrigger(KeyInput.KEY_F1) etc </td>
</tr>
<tr>
<td> Keyboard: Return, Enter </td><td> KeyTrigger(KeyInput.KEY_RETURN), <br/>
KeyTrigger(KeyInput.KEY_NUMPADENTER) </td>
</tr>
<tr>
<td> Keyboard: PageUp, PageDown </td><td> KeyTrigger(KeyInput.KEY_PGUP), <br/>
KeyTrigger(KeyInput.KEY_PGDN) </td>
</tr>
<tr>
<td> Keyboard: Delete, Backspace </td><td> KeyTrigger(KeyInput.KEY_BACK), <br/>
KeyTrigger(KeyInput.KEY_DELETE) </td>
</tr>
<tr>
<td> Keyboard: Escape </td><td> KeyTrigger(KeyInput.KEY_ESCAPE) </td>
</tr>
<tr>
<td> Keyboard: Arrows </td><td> KeyTrigger(KeyInput.KEY_DOWN), <br/>
KeyTrigger(KeyInput.KEY_UP) <br/>
KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT) </td>
</tr>
<tr>
<td> NumPad: Number 1 etc </td><td> KeyTrigger(KeyInput.KEY_NUMPAD1) etc </td>
</tr>
<tr>
<td> Joystick: Button </td><td> JoyButtonTrigger(0, JoyInput.AXIS_POV_X), <br/>
JoyButtonTrigger(0, JoyInput.AXIS_POV_Y) ? </td>
</tr>
<tr>
<td> Joystick: Movement </td><td> JoyAxisTrigger(0, JoyInput.AXIS_POV_X, true), <br/>
JoyAxisTrigger(0, JoyInput.AXIS_POV_X, false), <br/>
JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, true), <br/>
JoyAxisTrigger(0, JoyInput.AXIS_POV_Z, false) </td>
</tr>
</table>
</div>
<h2><a>2. Add a Trigger Mapping</a></h2>
<div>
<p>
When initializing the application, add a Mapping for each Trigger.
</p>
<p>
Give the mapping a meaningful name. The name should reflect the action, not the key, since the keys can change. Here some examples:
</p>
<pre>inputManager.addMapping&#40;&quot;Pause Game&quot;, new KeyTrigger&#40;KeyInput.KEY_P&#41;&#41;;
inputManager.addMapping&#40;&quot;Rotate&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;</pre>
<p>
There are cases where you may want more then one trigger for one action. For instance some users prefer the WASD keys to navigate, others prefer the arrow keys. You can define both by adding them after a comma.
</p>
<pre>inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_A&#41;,
new KeyTrigger&#40;KeyInput.KEY_LEFT&#41;&#41;; new KeyTrigger&#40;KeyInput.KEY_LEFT&#41;&#41;;
inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_D&#41;, inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_D&#41;,
new KeyTrigger&#40;KeyInput.KEY_RIGHT&#41;&#41;;</pre> new KeyTrigger&#40;KeyInput.KEY_RIGHT&#41;&#41;;</pre></div><h2><a
</div> name="create_listeners">3. Create Listeners</a></h2><div
class="level2"><p> The jME3 input manager supports two types of event listeners for inputs:</p><p> <strong>com.jme3.input.controls.AnalogListener</strong></p><ul><li
<h2><a>3. Create Listeners</a></h2> class="level1"><div
<div> class="li"> Use for continuous and gradual actions.</div><ul><li
class="level2"><div
<p> class="li"> Examples: Walk, run, rotate, accelerate vehicle, strafe, (semi-)automatic weapon shot</div></li></ul></li><li
class="level1"><div
The jME3 input manager supports two types of event listeners for inputs: class="li"> JME gives you access to:</div><ul><li
</p> class="level2"><div
class="li"> the name of the triggered action.</div></li><li
<p> class="level2"><div
<strong>com.jme3.input.controls.AnalogListener</strong> class="li"> a gradual value between 0-9 how long the key has been pressed.</div></li></ul></li></ul><p> <strong>com.jme3.input.controls.ActionListener</strong></p><ul><li
</p> class="level1"><div
<ul> class="li"> Use for absolute &quot;pressed or released?&quot;, &quot;on or off?&quot; actions.</div><ul><li
<li><div> Use for continuous and gradual actions.</div> class="level2"><div
<ul> class="li"> Examples: Pause/unpause, a rifle or revolver shot, jump, click to select.</div></li></ul></li><li
<li><div> Examples: Walk, run, rotate, accelerate vehicle, strafe, (semi-)automatic weapon shot</div> class="level1"><div
</li> class="li"> JME gives you access to:</div><ul><li
</ul> class="level2"><div
</li> class="li"> the name of the triggered action.</div></li><li
<li><div> JME gives you access to:</div> class="level2"><div
<ul> class="li"> a boolean whether the key is still pressed or has just been released.</div></li></ul></li></ul><p> You can use one or both in the same application. Add one or both of these code snippets to your main SimpleApplication-based class to activate the listener.</p><pre>private ActionListener&#40;&#41; &#123;
<li><div> the name of the triggered action.</div>
</li>
<li><div> a gradual value between 0-9 how long the key has been pressed.</div>
</li>
</ul>
</li>
</ul>
<p>
<strong>com.jme3.input.controls.ActionListener</strong>
</p>
<ul>
<li><div> Use for absolute “pressed or released?”, “on or off?” actions. </div>
<ul>
<li><div> Examples: Pause/unpause, a rifle or revolver shot, jump, click to select.</div>
</li>
</ul>
</li>
<li><div> JME gives you access to:</div>
<ul>
<li><div> the name of the triggered action.</div>
</li>
<li><div> a boolean whether the key is still pressed or has just been released.</div>
</li>
</ul>
</li>
</ul>
<p>
You can use one or both in the same application. Add one or both of these code snippets to your main SimpleApplication-based class to activate the listener.
</p>
<pre>private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
/** TODO */ /** TODO */
&#125; &#125;
@ -194,44 +104,12 @@ You can use one or both in the same application. Add one or both of these code s
public void onAnalog&#40;String name, float keyPressed, float tpf&#41; &#123; public void onAnalog&#40;String name, float keyPressed, float tpf&#41; &#123;
/** TODO */ /** TODO */
&#125; &#125;
&#125;;</pre> &#125;;</pre></div><h2><a
</div> name="register_mappings_to_listeners">4. Register Mappings to Listeners</a></h2><div
class="level2"><p> To activate the mappings, you must register them to the Listener. Write your registration code after the part where you have added the mappings to the inputManager before.</p><p> In this example, we register the &quot;Pause Game&quot; mapping to the <code>actionListener</code> object, because pausing a game is in &quot;either/or&quot; decision.</p><pre>inputManager.addListener&#40;actionListener, new String&#91;&#93;&#123;&quot;Left&quot;, &quot;Right&quot;&#125;&#41;;</pre><p> As you see, you can add several listeners in one String array. You can call the addListener() method more than once, each time with a subset of your list, if that helps you keep you code tidy.</p><p> <strong>Tip:</strong> Check the string&#039;s capitalization and spelling if you think you have registered an action, but it does not work.</p></div><h2><a
<h2><a>4. Register Mappings to Listeners</a></h2> name="implement_actions">5. Implement Actions</a></h2><div
<div> class="level2"><p> You specify the action to be triggered where it says TODO in the Listener code snippets.
Typically you write a series of if/else conditions, testing for all the mapping names, and specifying each action. Here is one example:</p><pre>private AnalogListener analogListener = new AnalogListener&#40;&#41; &#123;
<p>
To activate the mappings, you must register them to the Listener. Write your registration code after the part where you have added the mappings to the inputManager before.
</p>
<p>
In this example, we register the “Pause Game” mapping to the <code>actionListener</code> object, because pausing a game is in “either/or” decision.
</p>
<pre>inputManager.addListener&#40;actionListener, new String&#91;&#93;&#123;&quot;Pause Game&quot;&#125;&#41;;</pre>
<p>
In this example, we register navigational mappings to the <code>analogListener</code> object, because walking is a continuous action. Players tend to keep the key pressed to express continuity, for example when they want to “walk on” or “accelerate”.
</p>
<pre>inputManager.addListener&#40;analogListener, new String&#91;&#93;&#123;&quot;Left&quot;, &quot;Right&quot;&#125;&#41;;</pre>
<p>
As you see, you can add several listeners in one String array. You can call the addListener() method more than once, each time with a subset of your list, if that helps you keep you code tidy.
</p>
<p>
<strong>Tip:</strong> Check the string&#039;s capitalization and spelling if you think you have registered an action, but it does not work.
</p>
</div>
<h2><a>5. Implement Actions</a></h2>
<div>
<p>
You specify the action to be triggered where it says TODO in the Listener code snippets.
Typically you write a series of if/else conditions, testing for all the mapping names, and specifying each action. Here is one example:
</p>
<pre>private AnalogListener analogListener = new AnalogListener&#40;&#41; &#123;
public void onAnalog&#40;String name, float value, float tpf&#41; &#123; public void onAnalog&#40;String name, float value, float tpf&#41; &#123;
&nbsp; &nbsp;
if &#40;name.equals&#40;&quot;Rotate&quot;&#41;&#41; &#123; // test? if &#40;name.equals&#40;&quot;Rotate&quot;&#41;&#41; &#123; // test?
@ -239,11 +117,7 @@ Typically you write a series of if/else conditions, testing for all the mapping
&#125; // else if ... &#125; // else if ...
&nbsp; &nbsp;
&#125; &#125;
&#125;;</pre> &#125;;</pre><p> It&#039;s very common that you want an action to be only triggered once, in the moment when the key is released. Examples are when the player presses an action key to open a door or pick up an item, or to flip a game state, such as pause/unpause. For these cases, use an ActionListener and test for <code>&amp;&amp; !keyPressed</code>, like shown in the following example.</p><pre>private ActionListener&#40;&#41; &#123;
<p>
It&#039;s very common that you want an action to be only triggered once, in the moment when the key is released. Examples are when the player presses an action key to open a door or pick up an item, or to flip a game state, such as pause/unpause. For these cases, use an ActionListener and test for <code>&amp;&amp; !keyPressed</code>, like shown in the following example.
</p>
<pre>private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
&nbsp; &nbsp;
if &#40;name.equals&#40;&quot;Pause Game&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; // test? if &#40;name.equals&#40;&quot;Pause Game&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; // test?
@ -251,21 +125,11 @@ It&#039;s very common that you want an action to be only triggered once, in the
&#125; // else if ... &#125; // else if ...
&nbsp; &nbsp;
&#125; &#125;
&#125;;</pre> &#125;;</pre></div><h2><a
</div> name="remapping_keys">Remapping Keys</a></h2><div
class="level2"><p> This approach of separating triggers from actions has the advantage that you can remap triggers easily. Maybe your players have different keyboard layouts, are used to &quot;reversed&quot; mouse navigation, or prefer different navigational keys than the ones you defined. In any case, you only need to replace the trigger parts in the <code>inputManager.addMapping()</code> lines with variables, and load different sets of trigger objects when the game starts. The rest of the code stays as it is.</p><div
<h2><a>Remapping Keys</a></h2> class="tags"><span> <a
<div> href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
This approach of separating triggers from actions has the advantage that you can remap triggers easily. Maybe your players have different keyboard layouts, are used to “reversed” mouse navigation, or prefer different navigational keys than the ones you defined. In any case, you only need to replace the trigger parts in the <code>inputManager.addMapping()</code> lines with variables, and load different sets of trigger objects when the game starts. The rest of the code stays as it is.
</p>
<div><span>
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:input_handling?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:input_handling?do=export_xhtmlbody">view online version</a></em></p>

@ -1,23 +1,16 @@
<h1><a
<h1><a>Saving and Loading Materials with .j3m Files</a></h1> name="saving_and_loading_materials_with_j3m_files">Saving and Loading Materials with .j3m Files</a></h1><div
<div> class="level1"><p> In the <a
href="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> article you learned how to configure <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials</a> programmatically in Java code. If you have certain commonly used Materials that never change, you can clean up the amount of Java code that clutters your init method, by moving material settings into .j3m files. Then later in your code, you only need to call one setter instead of several to apply the material.</p></div><h2><a
name="writing_the_j3m_file">Writing the .j3m File</a></h2><div
In the <a href="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> article you learned how to configure <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials</a> programmatically in Java code. If you have certain commonly used Materials that never change, you can clean up the amount of Java code that clutters your init method, by moving material settings into .j3m files. Then later in your code, you only need to call one setter instead of several to apply the material. class="level2"><ol><li
</p> class="level1"><div
class="li"> For every Material, create a file and give it a name that describes it: e.g. <code>SimpleBump.j3m</code></div></li><li
</div> class="level1"><div
class="li"> Place the file in your project&#039;s <code>assets/Materials/</code> directory, e.g. <code>MyGame/src/assets/Materials/SimpleBump.j3m</code></div></li><li
<h2><a>Writing the .j3m File</a></h2> class="level1"><div
<div> class="li"> Edit the file and add content using the following Syntax, e.g.:<pre>Material shiny bumpy rock : Common/MatDefs/Light/Lighting.j3md {
<ol>
<li><div> For every Material, create a file and give it a name that describes it: e.g. <code>SimpleBump.j3m</code></div>
</li>
<li><div> Place the file in your project&#039;s <code>assets/Materials/</code> directory, e.g. <code>MyGame/src/assets/Materials/SimpleBump.j3m</code></div>
</li>
<li><div> Edit the file and add content using the following Syntax, e.g.:<pre>
Material shiny bumpy rock : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters { MaterialParameters {
Shininess: 8.0 Shininess: 8.0
NormalMap: Textures/bump_rock_normal.png NormalMap: Textures/bump_rock_normal.png
@ -26,235 +19,190 @@ Material shiny bumpy rock : Common/MatDefs/Light/Lighting.j3md {
Diffuse : 1.0 1.0 1.0 1.0 Diffuse : 1.0 1.0 1.0 1.0
Specular : 0.0 0.0 0.0 1.0 Specular : 0.0 0.0 0.0 1.0
} }
} }</pre></div></li></ol><p> How to this file is structured:</p><ol><li
</pre> class="level1"><div
</div> class="li"> Header</div><ol><li
</li> class="level2"><div
</ol> class="li"> <code>Material</code> is a fixed keyword, keep it.</div></li><li
class="level2"><div
<p> class="li"> <code>shiny bumpy rock</code> is a descriptive string that you can make up. Choose a name to help you remember for what you intend to use this material.</div></li><li
class="level2"><div
How to this file is structured: class="li"> After the colon, specify on which <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> definition you base this Material.</div></li></ol></li><li
<ol> class="level1"><div
<li><div> Header</div> class="li"> Now look up the choosen Material Definition&#039;s parameters and their parameter types from the <a
<ol> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> table. Add one line for each parameter.</div><ul><li
<li><div> <code>Material</code> is a fixed keyword, keep it.</div> class="level2"><div
</li> class="li"> For example: The series of four numbers in the example above represent RGBA color values.</div></li></ul></li><li
<li><div> <code>shiny bumpy rock</code> is a descriptive string that you can make up. Choose a name to help you remember for what you intend to use this material.</div> class="level1"><div
</li> class="li"> Check the detailed syntax reference below if you are unsure.</div></li></ol><p> <strong>Tip:</strong> In the jMonkeyPlatform, use File&gt;New File&gt;Material&gt;Empty Material File to create .j3m files.</p></div><h2><a
<li><div> After the colon, specify on which <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> definition you base this Material.</div> name="how_to_use_j3m_materials">How to Use .j3m Materials</a></h2><div
</li> class="level2"><p> This is how you use the prepared .j3m Material on a Spatial. Since you have saved the .j3m file to your project&#039;s Assets directory, the .j3m path is relative to <code>MyGame/src/assets/…</code>.</p><pre>myGeometry.setMaterial&#40;assetManager.loadAsset&#40;&quot;Materials/SimpleBump.j3m&quot;&#41;&#41;;</pre><p> <strong>Tip:</strong> In the jMonkeyPlatform, open Windows&gt;Palette and drag the <code>JME Material: Set J3M</code> snippet into your code.</p></div><h2><a
</ol> name="syntax_reference_for_j3m_files">Syntax Reference for .j3m Files</a></h2><div
</li> class="level2"></div><h3><a
<li><div> Now look up the choosen Material Definition&#039;s parameters and their parameter types from the <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> table. Add one line for each parameter.</div> name="paths">Paths</a></h3><div
<ul> class="level3"><p> Make sure to get the paths to the textures (.png, .jpg) and material definitions (.j3md) right.</p><ul><li
<li><div> For example: The series of four numbers in the example above represent RGBA color values.</div> class="level1"><div
</li> class="li"> The paths to the built-in .j3md files are relative to jME3&#039;s Core Data directory. Just copy the path stated in the <a
</ul> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> table. <br/> <code>Common/MatDefs/Misc/Unshaded.j3md</code> is resolved to <code>jme3/src/src/core-data/Common/MatDefs/Misc/Unshaded.j3md</code>.</div></li><li
</li> class="level1"><div
<li><div> Check the detailed syntax reference below if you are unsure.</div> class="li"> The paths to your textures are relative to your project&#039;s assets directory. <br/> <code>Textures/bump_rock_normal.png</code> is resolved to <code>MyGame/src/assets/Textures/bump_rock_normal.png</code></div></li></ul></div><h3><a
</li> name="data_types">Data Types</a></h3><div
</ol> class="level3"><p> All data types (except Color) are specified in com.jme3.shader.VarType.
&quot;Color&quot; is specified as Vector4 in J3MLoader.java.</p><div
<p> class="table sectionedit1"><table
class="inline"><tr
<strong>Tip:</strong> In the jMonkeyPlatform, use File&gt;New File&gt;Material&gt;Empty Material File to create .j3m files. class="row0"><th
</p> class="col0">Name</th><th
class="col1">jME Java class</th><th
</div> class="col2">.j3m file syntax</th></tr><tr
class="row1"><td
<h2><a>How to Use .j3m Materials</a></h2> class="col0"> Float</td><td
<div> class="col1"></td><td
class="col2"> a float (e.g. 0.72) , no comma or parentheses</td></tr><tr
<p> class="row2"><td
class="col0"> Vector2</td><td
This is how you use the prepared .j3m Material on a Spatial. Since you have saved the .j3m file to your project&#039;s Assets directory, the .j3m path is relative to <code>MyGame/src/assets/…</code>. class="col1"> <code>com.jme3.math.Vector2f</code></td><td
</p> class="col2"> Two floats, no comma or parentheses</td></tr><tr
<pre>myGeometry.setMaterial&#40;assetManager.loadAsset&#40;&quot;Materials/SimpleBump.j3m&quot;&#41;&#41;;</pre> class="row3"><td
<p> class="col0"> Vector3</td><td
<strong>Tip:</strong> In the jMonkeyPlatform, open Windows&gt;Palette and drag the <code>JME Material: Set J3M</code> snippet into your code. class="col1"> <code>com.jme3.math.Vector3f</code></td><td
</p> class="col2"> Three floats, no comma or parentheses</td></tr><tr
class="row4"><td
</div> class="col0"> Texture2D</td><td
class="col1"> <code>com.jme3.texture.Texture</code></td><td
<h2><a>Syntax Reference for .j3m Files</a></h2> class="col2"> Path to texture in <code>assets</code> directory, no quotation marks</td></tr><tr
<div> class="row5"><td
class="col0"> Boolean</td><td
</div> class="col1"> (basic Java type)</td><td
class="col2"> <code>true</code> or <code>false</code></td></tr><tr
<h3><a>Paths</a></h3> class="row6"><td
<div> class="col0"> Int</td><td
class="col1"> (basic Java type)</td><td
<p> class="col2"> Integer number, no comma or parentheses</td></tr><tr
class="row7"><td
Make sure to get the paths to the textures (.png, .jpg) and material definitions (.j3md) right. class="col0"> Color</td><td
class="col1"> <code>com.jme3.math.ColorRGBA</code></td><td
</p> class="col2"> Four floats, no comma or parentheses</td></tr><tr
<ul> class="row8"><td
<li><div> The paths to the built-in .j3md files are relative to jME3&#039;s Core Data directory. Just copy the path stated in the <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material</a> table. <br/> class="col0"> Vector4</td><td
<code>Common/MatDefs/Misc/Unshaded.j3md</code> is resolved to <code>jme3/src/src/core-data/Common/MatDefs/Misc/Unshaded.j3md</code>.</div> class="col1 leftalign"></td><td
</li> class="col2 leftalign"></td></tr><tr
<li><div> The paths to your textures are relative to your project&#039;s assets directory. <br/> class="row9"><td
<code>Textures/bump_rock_normal.png</code> is resolved to <code>MyGame/src/assets/Textures/bump_rock_normal.png</code></div> class="col0"> FloatArray</td><td
</li> class="col1"></td><td
</ul> class="col2 leftalign"></td></tr><tr
class="row10"><td
</div> class="col0"> Vector2Array</td><td
class="col1"></td><td
<h3><a>Data Types</a></h3> class="col2 leftalign"></td></tr><tr
<div> class="row11"><td
class="col0"> Vector3Array</td><td
<p> class="col1"></td><td
class="col2 leftalign"></td></tr><tr
All data types (except Color) are specified in com.jme3.shader.VarType. class="row12"><td
“Color” is specified as Vector4 in J3MLoader.java. class="col0"> Vector4Array</td><td
class="col1"></td><td
</p> class="col2 leftalign"></td></tr><tr
<table> class="row13"><td
<tr> class="col0"> Matrix3</td><td
<th>Name</th><th>jME Java class</th><th>.j3m file syntax</th> class="col1"></td><td
</tr> class="col2 leftalign"></td></tr><tr
<tr> class="row14"><td
<td> Float</td><td> </td><td> a float (e.g. 0.72) , no comma or parentheses </td> class="col0"> Matrix4</td><td
</tr> class="col1"></td><td
<tr> class="col2 leftalign"></td></tr><tr
<td> Vector2</td><td> <code>com.jme3.math.Vector2f</code></td><td> Two floats, no comma or parentheses </td> class="row15"><td
</tr> class="col0"> Matrix3Array</td><td
<tr> class="col1"></td><td
<td> Vector3 </td><td> <code>com.jme3.math.Vector3f</code> </td><td> Three floats, no comma or parentheses </td> class="col2 leftalign"></td></tr><tr
</tr> class="row16"><td
<tr> class="col0"> Matrix4Array</td><td
<td> Texture2D </td><td> <code>com.jme3.texture.Texture</code> </td><td> Path to texture in <code>assets</code> directory, no quotation marks </td> class="col1"></td><td
</tr> class="col2 leftalign"></td></tr><tr
<tr> class="row17"><td
<td> Boolean</td><td> (basic Java type) </td><td> <code>true</code> or <code>false</code> </td> class="col0"> TextureBuffer</td><td
</tr> class="col1"></td><td
<tr> class="col2 leftalign"></td></tr><tr
<td> Int</td><td> (basic Java type) </td><td> Integer number, no comma or parentheses </td> class="row18"><td
</tr> class="col0"> Texture3D</td><td
<tr> class="col1"></td><td
<td> Color </td><td> <code>com.jme3.math.ColorRGBA</code> </td><td> Four floats, no comma or parentheses </td> class="col2 leftalign"></td></tr><tr
</tr> class="row19"><td
<tr> class="col0"> TextureArray</td><td
<td> Vector4</td><td> </td><td> </td> class="col1"></td><td
</tr> class="col2 leftalign"></td></tr><tr
<tr> class="row20"><td
<td> FloatArray</td><td> </td><td> </td> class="col0"> TextureCubeMap</td><td
</tr> class="col1"></td><td
<tr> class="col2 leftalign"></td></tr></table></div></div><h3><a
<td> Vector2Array</td><td> </td><td> </td> name="flip_and_repeat_syntax">Flip and Repeat Syntax</a></h3><div
</tr> class="level3"><ul><li
<tr> class="level1"><div
<td> Vector3Array</td><td> </td><td> </td> class="li"> A texture can be flipped using the following syntax <code>NormalMap: Flip Textures/bump_rock_normal.png</code></div></li><li
</tr> class="level1"><div
<tr> class="li"> A texture can be set to repeat using the following syntax <code>NormalMap: Repeat Textures/bump_rock_normal.png</code></div></li><li
<td> Vector4Array</td><td> </td><td> </td> class="level1"><div
</tr> class="li"> If a texture is set to both being flipped and repeated, Flip must come before Repeat</div></li></ul></div><h3><a
<tr> name="syntax_for_additional_render_states">Syntax for Additional Render States</a></h3><div
<td> Matrix3</td><td> </td><td> </td> class="level3"><ul><li
</tr> class="level1"><div
<tr> class="li"> A Boolean can be &quot;On&quot; or &quot;Off&quot;</div></li><li
<td> Matrix4</td><td> </td><td> </td> class="level1"><div
</tr> class="li"> Float is &quot;123.0&quot; etc</div></li><li
<tr> class="level1"><div
<td> Matrix3Array</td><td> </td><td> </td> class="li"> Enum - values depend on the enum</div></li></ul><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td> Matrix4Array</td><td> </td><td> </td> class="row0"><th
</tr> class="col0">Name</th><th
<tr> class="col1">Type</th><th
<td> TextureBuffer</td><td> </td><td> </td> class="col2">Purpose</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">Wireframe</td><td
<td> Texture3D</td><td> </td><td> </td> class="col1">(Boolean)</td><td
</tr> class="col2"></td></tr><tr
<tr> class="row2"><td
<td> TextureArray</td><td> </td><td> </td> class="col0">FaceCull</td><td
</tr> class="col1">(Enum: FaceCullMode)</td><td
<tr> class="col2"></td></tr><tr
<td> TextureCubeMap</td><td> </td><td> </td> class="row3"><td
</tr> class="col0">DepthWrite</td><td
</table> class="col1">(Boolean)</td><td
class="col2"></td></tr><tr
</div> class="row4"><td
class="col0">DepthTest</td><td
<h3><a>Flip and Repeat Syntax</a></h3> class="col1">(Boolean)</td><td
<div> class="col2"></td></tr><tr
<ul> class="row5"><td
<li><div> A texture can be flipped using the following syntax <code>NormalMap: Flip Textures/bump_rock_normal.png</code></div> class="col0">Blend</td><td
</li> class="col1">(Enum: BlendMode)</td><td
<li><div> A texture can be set to repeat using the following syntax <code>NormalMap: Repeat Textures/bump_rock_normal.png</code></div> class="col2"></td></tr><tr
</li> class="row6"><td
<li><div> If a texture is set to both being flipped and repeated, Flip must come before Repeat</div> class="col0">AlphaTestFalloff</td><td
</li> class="col1">(Float)</td><td
</ul> class="col2"></td></tr><tr
class="row7"><td
</div> class="col0">PolyOffset</td><td
class="col1">(Float, Float)</td><td
<h3><a>Syntax for Additional Render States</a></h3> class="col2"></td></tr><tr
<div> class="row8"><td
<ul> class="col0">ColorWrite</td><td
<li><div> A Boolean can be “On” or “Off”</div> class="col1">(Boolean)</td><td
</li> class="col2"></td></tr><tr
<li><div> Float is “123.0” etc</div> class="row9"><td
</li> class="col0">PointSprite</td><td
<li><div> Enum - values depend on the enum</div> class="col1">(Boolean)</td><td
</li> class="col2"></td></tr></table></div></div><h2><a
</ul> name="examples">Examples</a></h2><div
<table> class="level2"></div><h3><a
<tr> name="example_1shiny">Example 1: Shiny</a></h3><div
<th>Name</th><th>Type</th><th>Purpose</th> class="level3"><pre>Spatial signpost = &#40;Spatial&#41; assetManager.loadAsset&#40;
</tr>
<tr>
<td>Wireframe </td><td>(Boolean)</td><td> </td>
</tr>
<tr>
<td>FaceCull </td><td>(Enum: FaceCullMode)</td><td> </td>
</tr>
<tr>
<td>DepthWrite </td><td>(Boolean)</td><td> </td>
</tr>
<tr>
<td>DepthTest </td><td>(Boolean)</td><td> </td>
</tr>
<tr>
<td>Blend </td><td>(Enum: BlendMode)</td><td> </td>
</tr>
<tr>
<td>AlphaTestFalloff </td><td>(Float)</td><td> </td>
</tr>
<tr>
<td>PolyOffset </td><td>(Float, Float)</td><td> </td>
</tr>
<tr>
<td>ColorWrite </td><td>(Boolean)</td>
</tr>
<tr>
<td>PointSprite </td><td>(Boolean)</td><td> </td>
</tr>
</table>
</div>
<h2><a>Examples</a></h2>
<div>
</div>
<h3><a>Example 1: Shiny</a></h3>
<div>
<pre>Spatial signpost = &#40;Spatial&#41; assetManager.loadAsset&#40;
new OgreMeshKey&#40;&quot;Models/Sign Post/Sign Post.mesh.xml&quot;, null&#41;&#41;; new OgreMeshKey&#40;&quot;Models/Sign Post/Sign Post.mesh.xml&quot;, null&#41;&#41;;
signpost.setMaterial&#40; &#40;Material&#41; assetManager.loadAsset&#40; signpost.setMaterial&#40; &#40;Material&#41; assetManager.loadAsset&#40;
new AssetKey&#40;&quot;Models/Sign Post/Sign Post.j3m&quot;&#41;&#41;&#41;; new AssetKey&#40;&quot;Models/Sign Post/Sign Post.j3m&quot;&#41;&#41;&#41;;
TangentBinormalGenerator.generate&#40;signpost&#41;; TangentBinormalGenerator.generate&#40;signpost&#41;;
rootNode.attachChild&#40;signpost&#41;;</pre> rootNode.attachChild&#40;signpost&#41;;</pre><p> The file <code>assets/Models/Sign Post/Sign Post.j3m</code> contains:</p><pre>Material Signpost : Common/MatDefs/Light/Lighting.j3md {
<p>
The file <code>assets/Models/Sign Post/Sign Post.j3m</code> contains:
</p>
<pre>
Material Signpost : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters { MaterialParameters {
Shininess: 4.0 Shininess: 4.0
DiffuseMap: Models/Sign Post/Sign Post.jpg DiffuseMap: Models/Sign Post/Sign Post.jpg
@ -265,53 +213,24 @@ Material Signpost : Common/MatDefs/Light/Lighting.j3md {
Diffuse : 1.0 1.0 1.0 1.0 Diffuse : 1.0 1.0 1.0 1.0
Specular : 1.0 1.0 1.0 1.0 Specular : 1.0 1.0 1.0 1.0
} }
} }</pre><p> The <acronym
</pre> title="Joint Photographics Experts Group">JPG</acronym> files are in the same directory, <code>assets/Models/Sign Post/…</code>.</p></div><h3><a
name="example_2repeating_texture">Example 2: Repeating Texture</a></h3><div
<p> class="level3"><pre>Material mat = assetManager.loadMaterial&#40;
The <acronym title="Joint Photographics Experts Group">JPG</acronym> files are in the same directory, <code>assets/Models/Sign Post/…</code>.
</p>
</div>
<h3><a>Example 2: Repeating Texture</a></h3>
<div>
<pre>Material mat = assetManager.loadMaterial&#40;
&quot;Textures/Terrain/Pond/Pond.j3m&quot;&#41;; &quot;Textures/Terrain/Pond/Pond.j3m&quot;&#41;;
mat.setColor&#40;&quot;Ambient&quot;, ColorRGBA.DarkGray&#41;; mat.setColor&#40;&quot;Ambient&quot;, ColorRGBA.DarkGray&#41;;
mat.setColor&#40;&quot;Diffuse&quot;, ColorRGBA.White&#41;; mat.setColor&#40;&quot;Diffuse&quot;, ColorRGBA.White&#41;;
mat.setBoolean&#40;&quot;UseMaterialColors&quot;, true&#41;;</pre> mat.setBoolean&#40;&quot;UseMaterialColors&quot;, true&#41;;</pre><p> The file <code>assets/Textures/Terrain/Pond/Pond.j3m</code> contains:</p><pre>Material Pong Rock : Common/MatDefs/Light/Lighting.j3md {
<p>
The file <code>assets/Textures/Terrain/Pond/Pond.j3m</code> contains:
</p>
<pre>
Material Pong Rock : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters { MaterialParameters {
Shininess: 8.0 Shininess: 8.0
DiffuseMap: Repeat Textures/Terrain/Pond/Pond.png DiffuseMap: Repeat Textures/Terrain/Pond/Pond.png
NormalMap: Repeat Textures/Terrain/Pond/Pond_normal.png NormalMap: Repeat Textures/Terrain/Pond/Pond_normal.png
} }
} }</pre><p> The <acronym
</pre> title="Portable Network Graphics">PNG</acronym> files are in the same directory, <code>assets/Textures/Terrain/Pond/</code></p></div><h3><a
name="example_3transparent">Example 3: Transparent</a></h3><div
<p> class="level3"><p> The file <code>assets/Models/Tree/Leaves.j3m</code> contains:</p><pre>Material Leaves : Common/MatDefs/Light/Lighting.j3md {
The <acronym title="Portable Network Graphics">PNG</acronym> files are in the same directory, <code>assets/Textures/Terrain/Pond/</code>
</p>
</div>
<h3><a>Example 3: Transparent</a></h3>
<div>
<p>
The file <code>assets/Models/Tree/Leaves.j3m</code> contains:
</p>
<pre>
Material Leaves : Common/MatDefs/Light/Lighting.j3md {
Transparent On Transparent On
MaterialParameters { MaterialParameters {
DiffuseMap : Models/Tree/Leaves.png DiffuseMap : Models/Tree/Leaves.png
UseAlpha : true UseAlpha : true
@ -327,12 +246,6 @@ Material Leaves : Common/MatDefs/Light/Lighting.j3md {
AlphaTestFalloff 0.50 AlphaTestFalloff 0.50
FaceCull Off FaceCull Off
} }
} }</pre><p> The <acronym
</pre> title="Portable Network Graphics">PNG</acronym> file is in the same directory, <code>assets/Models/Tree/…</code></p></div>
<p>
The <acronym title="Portable Network Graphics">PNG</acronym> file is in the same directory, <code>assets/Models/Tree/…</code>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:j3m_material_files?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:j3m_material_files?do=export_xhtmlbody">view online version</a></em></p>

@ -1,105 +1,27 @@
<h1><a
<h1><a>JME3 and Shaders</a></h1> name="jme3_and_shaders">JME3 and Shaders</a></h1><div
<div> class="level1"><p> <br/></p></div><h1><a
name="shaders_basics">Shaders Basics</a></h1><div
<p> class="level1"><p> Shaders are sets of instructions that are executed on the GPU. They are used to take advantage of hardware acceleration available on the GPU for rendering purposes.<br/> This paper only covers Vertex and Fragment shaders because they are the only ones supported by JME3 for the moment. But be aware that there are some other types of shaders (geometry, tessellation,…).<br/> There are multiple frequently used languages that you may encounter to code shaders but as JME3 is based on OpenGL, shaders in JME use GLSL and any example in this paper will be written in GLSL.<br/> <br/></p></div><h3><a
<br/> name="how_does_it_work">How Does it work?</a></h3><div
class="level3"><p> To keep it Simple: The Vertex shader is executed once for each vertex in the view, then the Fragment shader (also called the Pixel shader) is executed once for each pixel on the screen.<br/> The main purpose of the Vertex shader is to compute the screen coordinate of a vertex (where this vertex will be displayed on screen) while the main purpose of the Fragment shader is to compute the color of a pixel.<br/> This is a very simplified graphic to describe the call stack: <br/> <a
href="/wiki/lib/exe/fetch.php?hash=d919e8&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F09%2FJME3andShaders.png"><img
</p> src="/wiki/lib/exe/fetch.php?hash=d919e8&amp;w=250&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F09%2FJME3andShaders.png" class="media" alt="" width="250" /></a><br/> The main program sends mesh data to the vertex shader (vertex position in object space, normals, tangents, etc..). The vertex shader computes the screen position of the vertex and sends it to the Fragment shader. The fragment shader computes the color, and the result is displayed on screen or in a texture. <br/></p></div><h3><a
name="variables_scope">Variables scope</a></h3><div
</div> class="level3"><p> There are different types of scope for variables in a shader :</p><ul><li
class="level1"><div
<h1><a>Shaders Basics</a></h1> class="li"> uniform : User defined variables that are passed by the main program to the vertex and fragment shader, these variables are global for a given execution of a shader.</div></li><li
<div> class="level1"><div
class="li"> attribute : Per-vertex variables passed by the engine to the shader, like position, normal, etc (Mesh data in the graphic)</div></li><li
<p> class="level1"><div
Shaders are sets of instructions that are executed on the GPU. They are used to take advantage of hardware acceleration available on the GPU for rendering purposes.<br/> class="li"> varrying : Variables passed from the vertex shader to the fragment shader.</div></li></ul><p> There is a large panel of variable types to be used, for more information about it I recommend reading the GLSL specification <a
href="http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf">here</a>.<br/> <br/></p></div><h3><a
This paper only covers Vertex and Fragment shaders because they are the only ones supported by JME3 for the moment. But be aware that there are some other types of shaders (geometry, tessellation,…).<br/> name="spaces_and_matrices">Spaces and Matrices</a></h3><div
class="level3"><p> To understand the coming example you must know about the different spaces in 3D computer graphics, and the matrices used to translate coordinate from one space to another.<br/> <a
There are multiple frequently used languages that you may encounter to code shaders but as JME3 is based on OpenGL, shaders in JME use GLSL and any example in this paper will be written in GLSL.<br/> href="/wiki/lib/exe/fetch.php?hash=65c1f0&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F09%2FJME3andShaders-1.png"><img
src="/wiki/lib/exe/fetch.php?hash=65c1f0&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F09%2FJME3andShaders-1.png" class="media" alt="" /></a><br/> The engine passes the object space coordinates to the vertex shader. We need to compute its position in projection space. To do that we transform the object space position by the WorldViewProjectionMatrix which is a combination of the World, View, Projection matrices (who would have guessed?).<br/> <br/></p></div><h3><a
<br/> name="simple_example_rendering_a_solid_color_on_an_object">Simple example : rendering a solid color on an object</a></h3><div
class="level3"><p> Here is the simplest application to shaders, rendering a solid color.<br/> Vertex Shader : <br/></p><pre>//the global uniform World view projection matrix
</p>
</div>
<h3><a>How Does it work?</a></h3>
<div>
<p>
To keep it Simple: The Vertex shader is executed once for each vertex in the view, then the Fragment shader (also called the Pixel shader) is executed once for each pixel on the screen.<br/>
The main purpose of the Vertex shader is to compute the screen coordinate of a vertex (where this vertex will be displayed on screen) while the main purpose of the Fragment shader is to compute the color of a pixel.<br/>
This is a very simplified graphic to describe the call stack: <br/>
<img src="/wiki/lib/exe/fetch.php"><br/>
The main program sends mesh data to the vertex shader (vertex position in object space, normals, tangents, etc..). The vertex shader computes the screen position of the vertex and sends it to the Fragment shader. The fragment shader computes the color, and the result is displayed on screen or in a texture.
<br/>
</p>
</div>
<h3><a>Variables scope</a></h3>
<div>
<p>
There are different types of scope for variables in a shader :
</p>
<ul>
<li><div> uniform : User defined variables that are passed by the main program to the vertex and fragment shader, these variables are global for a given execution of a shader.</div>
</li>
<li><div> attribute : Per-vertex variables passed by the engine to the shader, like position, normal, etc (Mesh data in the graphic)</div>
</li>
<li><div> varrying : Variables passed from the vertex shader to the fragment shader.</div>
</li>
</ul>
<p>
There is a large panel of variable types to be used, for more information about it I recommend reading the GLSL specification <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf"><param name="text" value="<html><u>here</u></html>"><param name="textColor" value="blue"></object>.<br/>
<br/>
</p>
</div>
<h3><a>Spaces and Matrices</a></h3>
<div>
<p>
To understand the coming example you must know about the different spaces in 3D computer graphics, and the matrices used to translate coordinate from one space to another.<br/>
<img src="/wiki/lib/exe/fetch.php"><br/>
The engine passes the object space coordinates to the vertex shader. We need to compute its position in projection space. To do that we transform the object space position by the WorldViewProjectionMatrix which is a combination of the World, View, Projection matrices (who would have guessed?).<br/>
<br/>
</p>
</div>
<h3><a>Simple example : rendering a solid color on an object</a></h3>
<div>
<p>
Here is the simplest application to shaders, rendering a solid color.<br/>
Vertex Shader : <br/>
</p>
<pre>//the global uniform World view projection matrix
//(more on global uniforms below) //(more on global uniforms below)
uniform mat4 g_WorldViewProjectionMatrix; uniform mat4 g_WorldViewProjectionMatrix;
//The attribute inPosition is the Object space position of the vertex //The attribute inPosition is the Object space position of the vertex
@ -114,43 +36,14 @@ void main&#40;&#41;&#123;
//by the position vector. //by the position vector.
//The multiplication must be done in this order. //The multiplication must be done in this order.
gl_Position = g_WorldViewProjectionMatrix * vec4&#40;inPosition, 1.0&#41;; gl_Position = g_WorldViewProjectionMatrix * vec4&#40;inPosition, 1.0&#41;;
&#125;</pre> &#125;</pre><p> Fragment Shader : <br/></p><pre>void main&#40;&#41;&#123;
<p>
Fragment Shader : <br/>
</p>
<pre>void main&#40;&#41;&#123;
//returning the color of the pixel (here solid blue) //returning the color of the pixel (here solid blue)
//- gl_FragColor is the standard GLSL variable that holds the pixel //- gl_FragColor is the standard GLSL variable that holds the pixel
//color. It must be filled in the Fragment Shader. //color. It must be filled in the Fragment Shader.
gl_FragColor = vec4&#40;0.0, 0.0, 1.0, 1.0&#41;; gl_FragColor = vec4&#40;0.0, 0.0, 1.0, 1.0&#41;;
&#125;</pre> &#125;</pre><p> For example applying this shader to a sphere would render a solid blue sphere on screen.<br/> <br/></p></div><h1><a
<p> name="how_to_use_shaders_in_jme3">How to use shaders in JME3</a></h1><div
class="level1"><p> You probably heard that JME3 is “shader oriented”, but what does that mean?<br/> Usually to use shaders you must create what is called a program. This program specify the vertex shader and the fragment shader to use.<br/> JME3 encloses this in the material system. Every material in JME3 uses shaders.<br/> For example let’s have a look at the SolidColor.j3md file : <br/></p><pre>MaterialDef Solid Color &#123;
For example applying this shader to a sphere would render a solid blue sphere on screen.<br/>
<br/>
</p>
</div>
<h1><a>How to use shaders in JME3</a></h1>
<div>
<p>
You probably heard that JME3 is “shader oriented”, but what does that mean?<br/>
Usually to use shaders you must create what is called a program. This program specify the vertex shader and the fragment shader to use.<br/>
JME3 encloses this in the material system. Every material in JME3 uses shaders.<br/>
For example let’s have a look at the SolidColor.j3md file : <br/>
</p>
<pre>MaterialDef Solid Color &#123;
//This is the complete list of user defined uniforms to be used in the //This is the complete list of user defined uniforms to be used in the
//shaders //shaders
MaterialParameters &#123; MaterialParameters &#123;
@ -171,164 +64,67 @@ For example let’s have a look at the SolidColor.j3md file : <br/>
&#125; &#125;
Technique FixedFunc &#123; Technique FixedFunc &#123;
&#125; &#125;
&#125;</pre> &#125;</pre><p> For more information on JME3 material system, i suggest you read this <a
<p> href="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/jmonkeyengine3-material-system-full-explanation">topic</a>.<br/> <br/></p></div><h3><a
name="jme3_global_uniforms">JME3 Global uniforms</a></h3><div
For more information on JME3 material system, i suggest you read this <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/jmonkeyengine3-material-system-full-explanation"><param name="text" value="<html><u>topic</u></html>"><param name="textColor" value="blue"></object>.<br/> class="level3"><p> JME3 can expose pre-computed global uniforms to your shaders. You must specify the one that are required for your shader in the WorldParameters section of the material definition file (.j3md).<br/> Note that in the shader the uniform names will be prefixed by a “g_”.<br/> In the example above, WorldViewProjectionMatrix is declared as uniform mat4 g_WorldViewProjectionMatrix in the shader.<br/> The complete list of global uniforms that can be used in JME3 can be found <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/shader/UniformBinding.java">here</a>.<br/> <br/></p></div><h3><a
<br/> name="jme3_attributes">JME3 attributes</a></h3><div
class="level3"><p> Those are different attributes that are always passed to your shader.<br/> you can find a complete list of those attribute in the Type enum of the VertexBuffer <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/VertexBuffer.java">here</a>.<br/> Note that in the shader the attributes names will be prefixed by a “in”.<br/> <br/></p></div><h3><a
name="user_s_uniforms">User&#039;s uniforms</a></h3><div
</div> class="level3"><p> At some point when making your own shader you&#039;ll need to pass your own uniforms<br/> Any uniform has to be declared in the material definition file in the &quot;MaterialParameters&quot; section.<br/></p><pre> MaterialParameters &#123;
<h3><a>JME3 Global uniforms</a></h3>
<div>
<p>
JME3 can expose pre-computed global uniforms to your shaders. You must specify the one that are required for your shader in the WorldParameters section of the material definition file (.j3md).<br/>
Note that in the shader the uniform names will be prefixed by a “g_”.<br/>
In the example above, WorldViewProjectionMatrix is declared as uniform mat4 g_WorldViewProjectionMatrix in the shader.<br/>
The complete list of global uniforms that can be used in JME3 can be found <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/shader/UniformBinding.java"><param name="text" value="<html><u>here</u></html>"><param name="textColor" value="blue"></object>.<br/>
<br/>
</p>
</div>
<h3><a>JME3 attributes</a></h3>
<div>
<p>
Those are different attributes that are always passed to your shader.<br/>
you can find a complete list of those attribute in the Type enum of the VertexBuffer <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/VertexBuffer.java"><param name="text" value="<html><u>here</u></html>"><param name="textColor" value="blue"></object>.<br/>
Note that in the shader the attributes names will be prefixed by a “in”.<br/>
<br/>
</p>
</div>
<h3><a>User&#039;s uniforms</a></h3>
<div>
<p>
At some point when making your own shader you&#039;ll need to pass your own uniforms<br/>
Any uniform has to be declared in the material definition file in the “MaterialParameters” section.<br/>
</p>
<pre> MaterialParameters &#123;
Vector4 Color Vector4 Color
&#125;</pre> &#125;</pre><p> This material parameter will be sent from the engine to the shader as follow</p><pre> material.setColor&#40;&quot;Color&quot;, ColorRGBA&#40;1.0f, 0.0f, 0.0f, 1.0f&#41;;//red color</pre><p> Note that there is a setXXXX method for any type of uniform you want to pass.<br/> To use this uniform in the shader, you need to declare it in the .frag or in the .vert files (depending on where you need it) as follow :</p><pre> uniform vec4 m_Color;</pre><p> <strong>Note the &quot;m_&quot; prefix that specifies that the uniform is a material parameter.</strong><br/> This uniform will be populated at runtime with the value you sent.</p></div><h3><a
<p> name="step_by_step">Step by step</a></h3><div
class="level3"><ul><li
This material parameter will be sent from the engine to the shader as follow class="level1"><div
class="li"> Create a vertex shader (.vert) file</div></li><li
</p> class="level1"><div
<pre> material.setColor&#40;&quot;Color&quot;, ColorRGBA&#40;1.0f, 0.0f, 0.0f, 1.0f&#41;;//red color</pre> class="li"> Create a fragment shader (.frag) file</div></li><li
<p> class="level1"><div
class="li"> Create a material definition (j3md) file specifying the user defined uniforms, path to the shaders and the global uniforms to use</div></li><li
Note that there is a setXXXX method for any type of uniform you want to pass.<br/> class="level1"><div
class="li"> In your initSimpleApplication, create a material using this definition, apply it to a geometry</div></li><li
To use this uniform in the shader, you need to declare it in the .frag or in the .vert files (depending on where you need it) as follow : class="level1"><div
class="li"> That’s it!!</div></li></ul><pre> // A cube
</p>
<pre> uniform vec4 m_Color;</pre>
<p>
<strong>Note the “m_” prefix that specifies that the uniform is a material parameter.</strong><br/>
This uniform will be populated at runtime with the value you sent.
</p>
</div>
<h3><a>Step by step</a></h3>
<div>
<ul>
<li><div> Create a vertex shader (.vert) file</div>
</li>
<li><div> Create a fragment shader (.frag) file</div>
</li>
<li><div> Create a material definition (j3md) file specifying the user defined uniforms, path to the shaders and the global uniforms to use</div>
</li>
<li><div> In your initSimpleApplication, create a material using this definition, apply it to a geometry </div>
</li>
<li><div> That’s it!!</div>
</li>
</ul>
<pre> // A cube
Box&#40;Vector3f.ZERO, 1f,1f,1f&#41;; Box&#40;Vector3f.ZERO, 1f,1f,1f&#41;;
Geometry cube = new Geometry&#40;&quot;box&quot;, box&#41;; Geometry cube = new Geometry&#40;&quot;box&quot;, box&#41;;
Material mat = new Material&#40;assetManager,&quot;Path/To/My/materialDef.j3md&quot;&#41;; Material mat = new Material&#40;assetManager,&quot;Path/To/My/materialDef.j3md&quot;&#41;;
cube.setMaterial&#40;mat&#41;; cube.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;cube&#41;;</pre> rootNode.attachChild&#40;cube&#41;;</pre><p> <br/></p></div><h3><a
<p> name="jme3_and_opengl_3_4_compatibility">JME3 and OpenGL 3 &amp; 4 compatibility</a></h3><div
class="level3"><p> GLSL 1.0 to 1.2 comes with build in attributes and uniforms (ie, gl_Vertex, gl_ModelViewMatrix, etc…).<br/> Those attributes are deprecated since GLSL 1.3 (opengl 3), hence JME3 global uniforms and attributes. Here is a list of deprecated attributes and their equivalent in JME3<br/></p><div
<br/> class="table sectionedit1"><table
class="inline"><tr
class="row0"><th
</p> class="col0">GLSL 1.2 attributes</th><th
class="col1">JME3 equivalent</th></tr><tr
</div> class="row1"><td
class="col0 leftalign">gl_Vertex</td><td
<h3><a>JME3 and OpenGL 3 &amp; 4 compatibility</a></h3> class="col1">inPosition</td></tr><tr
<div> class="row2"><td
class="col0 leftalign">gl_Normal</td><td
<p> class="col1">inNormal</td></tr><tr
GLSL 1.0 to 1.2 comes with build in attributes and uniforms (ie, gl_Vertex, gl_ModelViewMatrix, etc…).<br/> class="row3"><td
Those attributes are deprecated since GLSL 1.3 (opengl 3), hence JME3 global uniforms and attributes. Here is a list of deprecated attributes and their equivalent in JME3<br/> class="col0 leftalign">gl_Color</td><td
class="col1">inColor</td></tr><tr
</p> class="row4"><td
<table> class="col0 leftalign">gl_MultiTexCoord0</td><td
<tr> class="col1">inTexCoord</td></tr><tr
<th>GLSL 1.2 attributes</th><th>JME3 equivalent</th> class="row5"><td
</tr> class="col0 leftalign">gl_ModelViewMatrix</td><td
<tr> class="col1">g_WorldViewMatrix</td></tr><tr
<td>gl_Vertex </td><td>inPosition</td> class="row6"><td
</tr> class="col0 leftalign">gl_ProjectionMatrix</td><td
<tr> class="col1">g_ProjectionMatrix</td></tr><tr
<td>gl_Normal </td><td>inNormal</td> class="row7"><td
</tr> class="col0 leftalign">gl_ModelViewProjectionMatrix</td><td
<tr> class="col1">g_WorldViewProjectionMatrix</td></tr><tr
<td>gl_Color </td><td>inColor</td> class="row8"><td
</tr> class="col0 leftalign">gl_NormalMatrix</td><td
<tr> class="col1">g_NormalMatrix</td></tr></table></div></div><h3><a
<td>gl_MultiTexCoord0 </td><td>inTexCoord</td> name="useful_links">Useful links</a></h3><div
</tr> class="level3"><p> <a
<tr> href="http://www.eng.utah.edu/~cs5610/lectures/GLSL-ATI-Intro.pdf">http://www.eng.utah.edu/~cs5610/lectures/GLSL-ATI-Intro.pdf</a></p></div>
<td>gl_ModelViewMatrix </td><td>g_WorldViewMatrix</td>
</tr>
<tr>
<td>gl_ProjectionMatrix </td><td>g_ProjectionMatrix</td>
</tr>
<tr>
<td>gl_ModelViewProjectionMatrix </td><td>g_WorldViewProjectionMatrix</td>
</tr>
<tr>
<td>gl_NormalMatrix </td><td>g_NormalMatrix</td>
</tr>
</table>
</div>
<h3><a>Useful links</a></h3>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.eng.utah.edu/~cs5610/lectures/GLSL-ATI-Intro.pdf"><param name="text" value="<html><u>http://www.eng.utah.edu/~cs5610/lectures/GLSL-ATI-Intro.pdf</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:jme3_shaders?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:jme3_shaders?do=export_xhtmlbody">view online version</a></em></p>

@ -1,71 +1,32 @@
<h1><a
<h1><a>Light and Shadow</a></h1> name="light_and_shadow">Light and Shadow</a></h1><div
<div> class="level1"><p> Lighting means that an object is brighter on the side facing the light direction, and darker on the backside. A light source with a direction or location is required for lit Materials to be visible. Lighting does not automatically mean that objects cast a shadow on the floor or other objects: Activating shadow processing is an extra step described below. <a
href="/wiki/lib/exe/detail.php/jme3:advanced:light-sources.png?id=jme3%3Aadvanced%3Alight_and_shadow"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-sources.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:pssm.png?id=jme3%3Aadvanced%3Alight_and_shadow"><img
Lighting means that an object is lighter on the side facing the light direction, and darker on the backside. A light source with a direction or location is required for lit Materials to be visible. Lighting does not automatically mean that objects cast a shadow on the floor or other objects: Activating shadow processing is an extra step described below. src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/pssm.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a></p></div><h2><a
</p> name="light_sources">Light Sources</a></h2><div
class="level2"><p> You can add several light sources to a scene using <code>rootNode.addLight()</code>. All Lighting.j3md- based Materials require a light source to be visible.
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/light-sources.png"> <img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/pssm.png">
</p>
</div>
<h2><a>Light Sources</a></h2>
<div>
<p>
You can add several light sources to a scene using <code>rootNode.addLight()</code>. All Lighting.j3md- based Materials require a light source to be visible.
</p>
<p>
The available light sources in <code>com.jme3.light</code> are SpotLight, PointLight, AmbientLight, and DirectionalLight. You can set the color of the light – normally, it is white. You can choose to set other colors to influence the scene&#039;s atmosphere. The available light sources in <code>com.jme3.light</code> are SpotLight, PointLight, AmbientLight, and DirectionalLight. You can set the color of the light – normally, it is white. You can choose to set other colors to influence the scene&#039;s atmosphere.
</p> A PointLight has a location and shines from there in all directions as far as its radius reaches, like a lamp. The light intensity decreases with increased distance from the light source.</p><pre>PointLight lamp_light = new PointLight&#40;&#41;;
<p>
A PointLight has a location and shines from there in all directions as far as its radius reaches, like a lamp. The light intensity decreases with increased distance from the light source.
</p>
<pre>PointLight lamp_light = new PointLight&#40;&#41;;
lamp_light.setColor&#40;ColorRGBA.Yellow&#41;; lamp_light.setColor&#40;ColorRGBA.Yellow&#41;;
lamp_light.setRadius&#40;4f&#41;; lamp_light.setRadius&#40;4f&#41;;
lamp_light.setPosition&#40;new Vector3f&#40;lamp_geo.getLocalTranslation&#40;&#41;&#41;&#41;; lamp_light.setPosition&#40;new Vector3f&#40;lamp_geo.getLocalTranslation&#40;&#41;&#41;&#41;;
rootNode.addLight&#40;lamp_light&#41;;</pre> rootNode.addLight&#40;lamp_light&#41;;</pre><p> A DirectionalLight has no position, only a direction. It is considered &quot;infinitely&quot; far away and sends out parallel beams of light. It can cast shadows. You typically use it to simulate sun light:</p><pre>DirectionalLight sun = new DirectionalLight&#40;&#41;;
<p>
A DirectionalLight has no position, only a direction. It is considered “infinitely” far away and sends out parallel beams of light. It can cast shadows. You typically use it to simulate sun light:
</p>
<pre>DirectionalLight sun = new DirectionalLight&#40;&#41;;
sun.setColor&#40;ColorRGBA.White&#41;; sun.setColor&#40;ColorRGBA.White&#41;;
sun.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;; sun.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;;
rootNode.addLight&#40;sun&#41;;</pre> rootNode.addLight&#40;sun&#41;;</pre><p> An AmbientLight influences the brightness of the whole scene globally. It has no direction and no location, and does not cast any shadow.</p><pre>AmbientLight al = new AmbientLight&#40;&#41;;
<p>
An AmbientLight influences the brightness of the whole scene globally. It has no direction and no location, and does not cast any shadow.
</p>
<pre>AmbientLight al = new AmbientLight&#40;&#41;;
al.setColor&#40;ColorRGBA.White.mult&#40;1.3f&#41;&#41;; al.setColor&#40;ColorRGBA.White.mult&#40;1.3f&#41;&#41;;
rootNode.addLight&#40;al&#41;;</pre> rootNode.addLight&#40;al&#41;;</pre><p> A SpotLight is like a flashlight that sends a distinct beam of light. (Still work in progress, as of alpha-3.)</p></div><h2><a
<p> name="simple_lighting">Simple Lighting</a></h2><div
A SpotLight is like a flashlight that sends a distinct beam of light. (Still work in progress, as of alpha-3.) class="level2"><ul><li
</p> class="level1"><div
class="li"> <a
</div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestSimpleLighting.java">TestSimpleLighting.java</a></div></li><li
class="level1"><div
<h2><a>Simple Lighting</a></h2> class="li"> <a
<div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestLightRadius.java">TestLightRadius.java</a></div></li></ul><p> Here we use a material based on Lighting.j3md (<a
<ul> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">More info about Materials</a>). Lighting.j3md-based materials dynamically support Shininess, and Ambient, Diffuse, and Specular Colors.</p><pre>Geometry teapot = &#40;Geometry&#41; assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestSimpleLighting.java"><param name="text" value="<html><u>TestSimpleLighting.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestLightRadius.java"><param name="text" value="<html><u>TestLightRadius.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<p>
Here we use a material based on Lighting.j3md (<a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">More info about Materials</a>). Lighting.j3md-based materials dynamically support Shininess, and Ambient, Diffuse, and Specular Colors.
</p>
<pre>Geometry teapot = &#40;Geometry&#41; assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;
TangentBinormalGenerator.generate&#40;teapot.getMesh&#40;&#41;, true&#41;; TangentBinormalGenerator.generate&#40;teapot.getMesh&#40;&#41;, true&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;;
mat.setBoolean&#40;&quot;m_UseMaterialColors&quot;, true&#41;; mat.setBoolean&#40;&quot;m_UseMaterialColors&quot;, true&#41;;
@ -73,11 +34,7 @@ mat.setColor&#40;&quot;m_Ambient&quot;, ColorRGBA.Black&#41;;
mat.setColor&#40;&quot;m_Diffuse&quot;, ColorRGBA.Blue&#41;; mat.setColor&#40;&quot;m_Diffuse&quot;, ColorRGBA.Blue&#41;;
mat.setColor&#40;&quot;m_Specular&quot;, ColorRGBA.White&#41;; mat.setColor&#40;&quot;m_Specular&quot;, ColorRGBA.White&#41;;
mat.setFloat&#40;&quot;m_Shininess&quot;, 12&#41;; mat.setFloat&#40;&quot;m_Shininess&quot;, 12&#41;;
rootNode.attachChild&#40;teapot&#41;;</pre> rootNode.attachChild&#40;teapot&#41;;</pre><p> In this example, we use material colors instead of textures. But you can equally well use Lighting.j3md to create a Material that uses texture maps, such as the Diffuse and Normal map used here, but also Specular and Paralax Maps:</p><pre> Sphere rock = new Sphere&#40;32,32, 2f&#41;;
<p>
In this example, we use material colors instead of textures. But you can equally well use Lighting.j3md to create a Material that uses texture maps, such as the Diffuse and Normal map used here, but also Specular and Paralax Maps:
</p>
<pre> Sphere rock = new Sphere&#40;32,32, 2f&#41;;
Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;; Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;;
rock.setTextureMode&#40;Sphere.TextureMode.Projected&#41;; // better quality on spheres rock.setTextureMode&#40;Sphere.TextureMode.Projected&#41;; // better quality on spheres
TangentBinormalGenerator.generate&#40;rock&#41;; // for lighting effect TangentBinormalGenerator.generate&#40;rock&#41;; // for lighting effect
@ -89,33 +46,14 @@ In this example, we use material colors instead of textures. But you can equally
assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond_normal.png&quot;&#41;&#41;; assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond_normal.png&quot;&#41;&#41;;
mat_lit.setFloat&#40;&quot;m_Shininess&quot;, 5f&#41;; // [0,128] mat_lit.setFloat&#40;&quot;m_Shininess&quot;, 5f&#41;; // [0,128]
shiny_rock.setMaterial&#40;mat_lit&#41;; shiny_rock.setMaterial&#40;mat_lit&#41;;
rootNode.attachChild&#40;shiny_rock&#41;;</pre> rootNode.attachChild&#40;shiny_rock&#41;;</pre><p> This lighting updates live when the object or light source moves. If you shine a colored PointLight at this object, you will see a light reflection in the color of the PointLight.
<p> This lighting method doesn&#039;t make the node cast a shadow onto other nodes.</p></div><h2><a
This lighting updates live when the object or light source moves. If you shine a colored PointLight at this object, you will see a light reflection in the color of the PointLight. name="basicshadowrenderer">BasicShadowRenderer</a></h2><div
</p> class="level2"><ul><li
class="level1"><div
<p> class="li"> <a
This lighting method doesn&#039;t make the node cast a shadow onto other nodes. href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestShadow.java">TestShadow.java</a></div></li></ul><p> Use the Shadow Renderer to make textured scene nodes cast and receive shadows.
</p> Switch off the default shadow mode, and add a jME SceneProcessor named com.jme3.shadow.BasicShadowRenderer to the viewPort.</p><pre>BasicShadowRenderer bsr;
</div>
<h2><a>BasicShadowRenderer</a></h2>
<div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestShadow.java"><param name="text" value="<html><u>TestShadow.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
<p>
Use the Shadow Renderer to make textured scene nodes cast and receive shadows.
</p>
<p>
Switch off the default shadow mode, and add a jME SceneProcessor named com.jme3.shadow.BasicShadowRenderer to the viewPort.
</p>
<pre>BasicShadowRenderer bsr;
... ...
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
... ...
@ -123,84 +61,49 @@ public void simpleInitApp&#40;&#41; &#123;
bsr = new BasicShadowRenderer&#40;assetManager, 256&#41;; bsr = new BasicShadowRenderer&#40;assetManager, 256&#41;;
bsr.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;; bsr.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;;
viewPort.addProcessor&#40;bsr&#41;; viewPort.addProcessor&#40;bsr&#41;;
...</pre> ...</pre><p> For every scene node that needs shadows, individually specify the shadow behaviour: Whether it cast shadows, receive shadows, both, or neither.</p><pre>wall.setShadowMode&#40;ShadowMode.CastAndReceive&#41;;
<p>
For every scene node that needs shadows, individually specify the shadow behaviour: Whether it cast shadows, receive shadows, both, or neither.
</p>
<pre>wall.setShadowMode&#40;ShadowMode.CastAndReceive&#41;;
... ...
floor.setShadowMode&#40;ShadowMode.Receive&#41;; floor.setShadowMode&#40;ShadowMode.Receive&#41;;
... ...
airplane.setShadowMode&#40;ShadowMode.Cast&#41;; airplane.setShadowMode&#40;ShadowMode.Cast&#41;;
... ...
ghost.setShadowMode&#40;ShadowMode.Off&#41;; ghost.setShadowMode&#40;ShadowMode.Off&#41;;
...</pre> ...</pre></div><h2><a
</div> name="parallel-split_shadow_map">Parallel-Split Shadow Map</a></h2><div
class="level2"><ul><li
<h2><a>Parallel-Split Shadow Map</a></h2> class="level1"><div
<div> class="li"> <a
<ul> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestPssmShadow.java">TestPssmShadow.java</a></div></li></ul><p> The PSSM shadow renderer can cast real-time shadows on curved surfaces.
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestPssmShadow.java"><param name="text" value="<html><u>TestPssmShadow.java</u></html>"><param name="textColor" value="blue"></object></div> To activate it, add a jME SceneProcessor named <code>com.jme3.shadow.PssmShadowRenderer</code> to the viewPort.</p><pre>private PssmShadowRenderer pssmRenderer;
</li>
</ul>
<p>
The PSSM shadow renderer can cast real-time shadows on curved surfaces.
To activate it, add a jME SceneProcessor named <code>com.jme3.shadow.PssmShadowRenderer</code> to the viewPort.
</p>
<pre>private PssmShadowRenderer pssmRenderer;
... ...
&nbsp;
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
.... ....
pssmRenderer = new PssmShadowRenderer&#40; pssmRenderer = new PssmShadowRenderer&#40;
assetManager,1024,4,PssmShadowRenderer.EDGE_FILTERING_PCF&#41;; assetManager,1024,4,PssmShadowRenderer.EDGE_FILTERING_PCF&#41;;
pssmRenderer.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;; pssmRenderer.setDirection&#40;new Vector3f&#40;-1, -1, -1&#41;.normalizeLocal&#40;&#41;&#41;;
viewPort.addProcessor&#40;pssmRenderer&#41;;</pre> viewPort.addProcessor&#40;pssmRenderer&#41;;</pre><p> The constructor expects the following values:</p><ul><li
<p> class="level1"><div
The constructor expects the following values: class="li"> Your assetManager object</div></li><li
</p> class="level1"><div
<ul> class="li"> The size of the rendered shadowmaps (512, 1024, 2048, etc…)</div></li><li
<li><div> Your assetManager object</div> class="level1"><div
</li> class="li"> The number of shadow maps rendered (the more shadow maps, the more quality, the less FPS).</div></li><li
<li><div> The size of the rendered shadowmaps (512, 1024, 2048, etc…)</div> class="level1"><div
</li> class="li"> The type of filtering for shadow edge smoothing:</div><ul><li
<li><div> The number of shadow maps rendered (the more shadow maps, the more quality, the less FPS). </div> class="level2"><div
</li> class="li"> PSSMShadowRenderer.EDGE_FILTERING_DITHER</div></li><li
<li><div> The type of filtering for shadow edge smoothing: </div> class="level2"><div
<ul> class="li"> PSSMShadowRenderer.EDGE_FILTERING_PCF (default).</div></li></ul></li></ul><p> You can set the following properties on the <code>pssmRenderer</code> object:</p><ul><li
<li><div> PSSMShadowRenderer.EDGE_FILTERING_DITHER</div> class="level1"><div
</li> class="li"> setDirection(Vector3f) – the direction of the light</div></li><li
<li><div> PSSMShadowRenderer.EDGE_FILTERING_PCF (default).</div> class="level1"><div
</li> class="li"> setLambda(0.65f) – Factor to use to reduce the split size</div></li><li
</ul> class="level1"><div
</li> class="li"> setShadowIntensity(0.7f) – shadow darkness (1 black, 0 invisible)</div></li><li
</ul> class="level1"><div
class="li"> setShadowZextend() – distance how far away from camera shadows will still be computed</div></li></ul><p> As usual, specify the shadow behaviour for every scene node.</p><pre>...
<p>
You can set the following properties on the <code>pssmRenderer</code> object:
</p>
<ul>
<li><div> setDirection(Vector3f) – the direction of the light</div>
</li>
<li><div> setLambda(0.65f) – Factor to use to reduce the split size </div>
</li>
<li><div> setShadowIntensity(0.7f) – shadow darkness (1 black, 0 invisible)</div>
</li>
<li><div> setShadowZextend() – distance how far away from camera shadows will still be computed</div>
</li>
</ul>
<p>
As usual, specify the shadow behaviour for every scene node.
</p>
<pre>...
teapot.setShadowMode&#40;ShadowMode.CastAndReceive&#41;; teapot.setShadowMode&#40;ShadowMode.CastAndReceive&#41;;
... ...
soil.setShadowMode&#40;ShadowMode.Receive&#41;; soil.setShadowMode&#40;ShadowMode.Receive&#41;;
...</pre> ...</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:light_and_shadow?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:light_and_shadow?do=export_xhtmlbody">view online version</a></em></p>

@ -1,173 +1,65 @@
<h1><a
<h1><a>Localizing jME 3 Games</a></h1> name="localizing_jme_3_games">Localizing jME 3 Games</a></h1><div
<div> class="level1"></div><h2><a
name="scope">Scope</a></h2><div
</div> class="level2"><p> Localizing an application can mean several things:</p><ul><li
class="level1"><div
<h2><a>Scope</a></h2> class="li"> At minimum you translate all messages and dialogs in the user interface to your target languages.</div></li><li
<div> class="level1"><div
class="li"> You should also translate the &quot;read me&quot;, help, and other documentation.</div></li><li
<p> class="level1"><div
class="li"> Also translating web content related to the application makes sure international users find out about your localized game.</div></li><li
Localizing an application can mean several things: class="level1"><div
class="li"> If you go the whole way of internationalization, you also &quot;translate&quot; metaphors in icons or symbols used. <br/> E.g. For localizations to right-to-left languages, you must also adjust the whole flow of the UI (order of menus and buttons).</div></li></ul><p> There are tools that assist you with localizing Java Swing GUIs. jME3 applications do not typically have a Swing <acronym
</p> title="Graphical User Interface">GUI</acronym>, so those tools are not of much help. Just stick to the normal Java rules about using Bundle Properties:</p></div><h2><a
<ul> name="preparing_the_localization">Preparing the Localization</a></h2><div
<li><div> At minimum you translate all messages and dialogs in the user interface to your target languages.</div> class="level2"><p> <strong>Tip:</strong> The jMonkeyPlatform supports opening and editing Bundle.properties files. Also note the Tools &gt; Localization menu.</p><p> To prepare the application for localization, you have to first identify all hard-coded messages.</p><ol><li
</li> class="level1"><div
<li><div> You should also translate the “read me”, help, and other documentation.</div> class="li"> Find every line in your jME3 game where you hard-coded message strings, e.g. <br/><pre>System.out.print&#40;&quot;Hello World!&quot;&#41;;
</li> UiText.setText&#40;&quot;Score: &quot;+score&#41;;</pre></div></li><li
<li><div> Also translating web content related to the application makes sure international users find out about your localized game.</div> class="level1"><div
</li> class="li"> Create one file named <code>Bundle.properties</code> in each directory where there are Java file that contain messages.</div></li><li
<li><div> If you go the whole way of internationalization, you also “translate” metaphors in icons or symbols used. <br/> class="level1"><div
E.g. For localizations to right-to-left languages, you must also adjust the whole flow of the UI (order of menus and buttons).</div> class="li"> For every hard-coded message, you add one line to the <code>Bundle.properties</code> file: First specify a unique key that identifies this string; then an equal sign; and the literal string itself. <br/><pre>greeting=Hello World!
</li> score.display=Score: </pre></div></li><li
</ul> class="level1"><div
class="li"> In the source code, replace every occurence of a hard-coded message with the appropriate Resource Bundle call to its unique key:<pre>ResourceBundle.getBundle&#40;&quot;Bundle&quot;&#41;.getString&#40;&quot;greeting&quot;&#41;&#41;;
<p> UiText.setText&#40;ResourceBundle.getBundle&#40;&quot;Bundle&quot;&#41;.getString&#40;&quot;score.display&quot;&#41;+score&#41;;</pre></div></li></ol><p> The language used in the Bundle.properties files will be the default language for your game.</p></div><h2><a
name="translating_the_messages">Translating the Messages</a></h2><div
There are tools that assist you with localizing Java Swing GUIs. jME3 applications do not typically have a Swing <acronym title="Graphical User Interface">GUI</acronym>, so those tools are not of much help. Just stick to the normal Java rules about using Bundle Properties: class="level2"><p> Each additional language comes in a set of files that is marked with a (usually) two-letter suffix. Common locales are de for German, en for English, fr for French, ja for Japanese, pt for Portuguese, etc.</p><p> To translate the messages to another language, for example, German:</p><ol><li
</p> class="level1"><div
class="li"> Make a copy of the <code>Bundle.properties</code> files.</div></li><li
</div> class="level1"><div
class="li"> Name the copy <code>Bundle_de.properties</code> for German. Note the added suffix _de.</div></li><li
<h2><a>Preparing the Localization</a></h2> class="level1"><div
<div> class="li"> Translate all strings (text on the right side of the equal sign) in the <code>Bundle_de.properties</code> to German.<pre>greeting=Hallo Welt!
score.display=Spielstand: </pre><p> <strong>Important:</strong> Do not modify any of the keys (text to the left of the equal sign)!</p></div></li><li
<p> class="level1"><div
class="li"> To test the German localization, start the application from the command line with <code>-Duser.language=de</code>. Note the parameter <code>de</code>.</div></li></ol><p> <strong>Tip:</strong> In the jMonkeyPlatform, you set this VM Option in the Project properties under Run. Here you can also save individual run configuraions for each language you want to test.</p><p> To get the full list of language suffixes use</p><pre>Locale.getISOLanguages&#40;&#41;&#41;&#41;;</pre></div><h2><a
<strong>Tip:</strong> The jMonkeyPlatform supports opening and editing Bundle.properties files. Also note the Tools &gt; Localization menu. name="which_strings_not_to_translate">Which Strings Not to Translate</a></h2><div
</p> class="level2"><p> <strong>Important:</strong> In the Bundle.properties file, do not include any strings that are asset paths, node or geometry names, input mappings, or material layers.</p><ul><li
class="level1"><div
<p> class="li"> Keep material layers:<pre>mat.setTexture&#40;&quot;ColorMap&quot;, tex&#41;;</pre></div></li><li
To prepare the application for localization, you have to first identify all hard-coded messages. class="level1"><div
class="li"> Keep paths:<pre>teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;</pre></div></li><li
</p> class="level1"><div
<ol> class="li"> Keep geometry and node names:<pre>Geometry thing=new Geometry&#40;&quot;A thing&quot;, mesh&#41;;
<li><div> Find every line in your jME3 game where you hard-coded message strings, e.g. <br/> Node vehicle = new Node&#40;&quot;Vehicle&quot;&#41;;</pre></div></li><li
<pre>System.out.print&#40;&quot;Hello World!&quot;&#41;; class="level1"><div
UiText.setText&#40;&quot;Score: &quot;+score&#41;;</pre></div> class="li"> Keep mappings:<pre>inputManager.addMapping&#40;&quot;Shoot&quot;, trigger&#41;;
</li> inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;;</pre></div></li></ul><p> Only localize messages and UI text!</p></div><h2><a
<li><div> Create one file named <code>Bundle.properties</code> in each directory where there are Java file that contain messages.</div> name="common_localization_problems">Common Localization Problems</a></h2><div
</li> class="level2"><p> Typical problems include:</p><ul><li
<li><div> For every hard-coded message, you add one line to the <code>Bundle.properties</code> file: First specify a unique key that identifies this string; then an equal sign; and the literal string itself. <br/> class="level1"><div
<pre>greeting=Hello World! class="li"> Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization</div></li><li
score.display=Score: </pre> class="level1"><div
</div> class="li"> Strings with variable text or numbers don&#039;t work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or find a work-around.</div></li><li
</li> class="level1"><div
<li><div> In the source code, replace every occurence of a hard-coded message with the appropriate Resource Bundle call to its unique key: <pre>ResourceBundle.getBundle&#40;&quot;Bundle&quot;&#41;.getString&#40;&quot;greeting&quot;&#41;&#41;; class="li"> The localizer only sees the strings, without any context. E.g. does &quot;Search History&quot; mean &quot;display the history of searches&quot;, or &quot;search through the history&quot;? ⇒ Use clear key labels and work closely with the localizers if they require extra info.</div></li><li
UiText.setText&#40;ResourceBundle.getBundle&#40;&quot;Bundle&quot;&#41;.getString&#40;&quot;score.display&quot;&#41;+score&#41;;</pre></div> class="level1"><div
</li> class="li"> Broken international characters ⇒ Make sure the files are saved with the right character encoding for the language.</div></li></ul></div><h2><a
</ol> name="more_documentation">More Documentation</a></h2><div
class="level2"><p> <a
<p> href="http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/">http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/</a></p><p> <a
href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation</a></p></div>
The language used in the Bundle.properties files will be the default language for your game.
</p>
</div>
<h2><a>Translating the Messages</a></h2>
<div>
<p>
Each additional language comes in a set of files that is marked with a (usually) two-letter suffix. Common locales are de for German, en for English, fr for French, ja for Japanese, pt for Portuguese, etc.
</p>
<p>
To translate the messages to another language, for example, German:
</p>
<ol>
<li><div> Make a copy of the <code>Bundle.properties</code> files.</div>
</li>
<li><div> Name the copy <code>Bundle_de.properties</code> for German. Note the added suffix _de.</div>
</li>
<li><div> Translate all strings (text on the right side of the equal sign) in the <code>Bundle_de.properties</code> to German. <pre>greeting=Hallo Welt!
score.display=Spielstand: </pre>
<p>
<strong>Important:</strong> Do not modify any of the keys (text to the left of the equal sign)!
</p>
</div>
</li>
<li><div> To test the German localization, start the application from the command line with <code>-Duser.language=de</code>. Note the parameter <code>de</code>.</div>
</li>
</ol>
<p>
<strong>Tip:</strong> In the jMonkeyPlatform, you set this VM Option in the Project properties under Run. Here you can also save individual run configuraions for each language you want to test.
</p>
<p>
To get the full list of language suffixes use
</p>
<pre>Locale.getISOLanguages&#40;&#41;&#41;&#41;;</pre>
</div>
<h2><a>Which Strings Not to Translate</a></h2>
<div>
<p>
<strong>Important:</strong> In the Bundle.properties file, do not include any strings that are asset paths, node or geometry names, input mappings, or material layers.
</p>
<ul>
<li><div> Keep material layers: <pre>mat.setTexture&#40;&quot;m_ColorMap&quot;, tex&#41;;</pre></div>
</li>
<li><div> Keep paths: <pre>teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;</pre></div>
</li>
<li><div> Keep geometry and node names: <pre>Geometry thing=new Geometry&#40;&quot;A thing&quot;, mesh&#41;;
Node vehicle = new Node&#40;&quot;Vehicle&quot;&#41;;</pre></div>
</li>
<li><div> Keep mappings: <pre>inputManager.addMapping&#40;&quot;Shoot&quot;, trigger&#41;;
inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;;</pre></div>
</li>
</ul>
<p>
Only localize messages and UI text!
</p>
</div>
<h2><a>Common Localization Problems</a></h2>
<div>
<p>
Typical problems include:
</p>
<ul>
<li><div> Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization</div>
</li>
<li><div> Strings with variable text or numbers don&#039;t work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or find a work-around.</div>
</li>
<li><div> The localizer only sees the strings, without any context. E.g. does “Search History” mean “display the history of searches”, or “search through the history”? ⇒ Use clear key labels and work closely with the localizers if they require extra info.</div>
</li>
<li><div> Broken international characters ⇒ Make sure the files are saved with the right character encoding for the language.</div>
</li>
</ul>
</div>
<h2><a>More Documentation</a></h2>
<div>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/"><param name="text" value="<html><u>http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Localisation</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:localization?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:localization?do=export_xhtmlbody">view online version</a></em></p>

@ -1,127 +1,33 @@
<h1><a
<h1><a>Logging and Monitoring</a></h1> name="logging_and_monitoring">Logging and Monitoring</a></h1><div
<div> class="level1"></div><h2><a
name="development_phase_log_output">Development Phase Log Output</a></h2><div
</div> class="level2"><p> Many developers just use System.out.println() to print diagnostic strings to the terminal. The problem with that is that before the release, you&#039;d have to go through all your code and make certain you removed all these println() calls. You do not want your users to see them and worry about ominous strings babbling about old development diagnostics.</p><p> Instead of println(), you use the standard Java logger from <code>java.util.logging</code>. It has many advantages for professional game development:</p><ul><li
class="level1"><div
<h2><a>Development Phase Log Output</a></h2> class="li"> You &quot;tag&quot; each message with a log level: Severe error, informative warning, etc.</div></li><li
<div> class="level1"><div
class="li"> You can switch off printing of all messages up to certain log level with just one line of code.</div><ul><li
<p> class="level2"><div
class="li"> During development, you would set the log level to fine, because you want all warnings printed.</div></li><li
Many developers just use System.out.println() to print diagnostic strings to the terminal. The problem with that is that before the release, you&#039;d have to go through all your code and make certain you removed all these println() calls. You do not want your users to see them and worry about ominous strings babbling about old development diagnostics. class="level2"><div
</p> class="li"> For the release, you set the log level to only report severe errors, and no informative diagnostics.</div></li></ul></li><li
class="level1"><div
<p> class="li"> The logger string is localizable, since it contains variables. You may want to localize all errors.</div></li></ul><p> So to print comments like a pro, you use the following logger syntax. The variables a, b, c, can be any printable Java object, e.g. <code>Vector3f a = cam.getLocation()</code>. They are numbered {0},{1},{2},etc for use in the string, in the order you put them in the Object array.</p><pre>private static final Logger logger = Logger.getLogger&#40;HelloWorld.class.getName&#40;&#41;&#41;;</pre><p> Replace HelloWorld by the name of the class where you are using this line.</p><pre>logger.log&#40;Level.WARNING, &quot;ok seriously wtf somebody check why {0} is {1} again?!&quot;,
Instead of println(), you use the standard Java logger from <code>java.util.logging</code>. It has many advantages for professional game development: new Object&#91;&#93;&#123;a , b&#125;&#41;;</pre><p> or</p><pre>logger.log&#40;Level.SEVERE, &quot;Game error: {0} must not be {1} after {2}! Please check your flux generator.&quot;,
</p> new Object&#91;&#93;&#123;a , b , c&#125;&#41;;</pre><p> As you see in the example, you should phrase potentially &quot;customer facing&quot; errors in a neutral way and offer a reason and a solution. If you use WARNINGs as replacement for casual printlns, make sure you deactivate them for the release.</p><p> More details about <a
<ul> href="http://download.oracle.com/javase/6/docs/api/java/util/logging/Level.html">Java log levels</a> here.</p></div><h3><a
<li><div> You “tag” each message with a log level: Severe error, informative warning, etc.</div> name="switching_the_logger_on_and_off">Switching the Logger on and off</a></h3><div
</li> class="level3"><p> In the release version you will deactivate the logging output to the terminal.</p><p> To deactivate the default logger, you set the log level to only report severe messages:</p><pre>Logger.getLogger&#40;””&#41;.setLevel&#40;Level.SEVERE&#41;;</pre><p> To reactivate it:</p><pre>Logger.getLogger&#40;””&#41;.setLevel&#40;Level.FINE&#41;;</pre></div><h2><a
<li><div> You can switch off printing of all messages up to certain log level with just one line of code.</div> name="jmonkeyplatform_log_files">jMonkeyPlatform Log Files</a></h2><div
<ul> class="level2"><p> You find the jMonkeyPlatform log file in /dev/var/log/messages.log in the jMonkeyPlatform preferences folder. You can learn the location of the preferences folder in the “About” screen of the jMonkeyPlatform under the label <strong>Userdir</strong>.</p><ul><li
<li><div> During development, you would set the log level to fine, because you want all warnings printed.</div> class="level1"><div
</li> class="li"> Windows: C:\Documents and Settings\YOUR_NAME\.jmonkeyplatform\&quot;</div></li><li
<li><div> For the release, you set the log level to only report severe errors, and no informative diagnostics.</div> class="level1"><div
</li> class="li"> Linux: /home/YOUR_NAME/.jmonkeyplatform/&quot;</div></li><li
</ul> class="level1"><div
</li> class="li"> Mac <acronym
<li><div> The logger string is localizable, since it contains variables. You may want to localize all errors.</div> title="Operating System">OS</acronym>: <code>/Users/YOUR_NAME/Library/Application Support/jmonkeyplatform/</code></div></li></ul></div><h2><a
</li> name="read_graphic_card_capabilites">Read Graphic Card Capabilites</a></h2><div
</ul> class="level2"><p> You can read the graphic card&#039;s capabilities using the <code>com.jme3.renderer.Caps</code> class:</p><pre>Collection&lt;Caps&gt; caps = renderer.getCaps&#40;&#41;;
Logger.getLogger&#40;HelloWorld.class.getName&#40;&#41;&#41;.log&#40;Level.INFO, “Caps: &#123;0&#125;” + caps.toString&#40;&#41;&#41;; </pre><p> Replace HelloWorld by the name of the class where you are using this line.</p><p> The result looks like the following example:</p><pre>Caps: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, OpenGL20, ARBprogram, GLSL100, GLSL110, GLSL120, VertexTextureFetch, FloatTexture, TextureCompressionLATC]</pre><p> This would tell you that this user&#039;s graphic card only supports OpenGL 2.0 and cannot handle newer OpenGL features.</p></div>
<p>
So to print comments like a pro, you use the following logger syntax. The variables a, b, c, can be any printable Java object, e.g. <code>Vector3f a = cam.getLocation()</code>. They are numbered {0},{1},{2},etc for use in the string, in the order you put them in the Object array.
</p>
<pre>private static final Logger logger = Logger.getLogger&#40;HelloWorld.class.getName&#40;&#41;&#41;;</pre>
<p>
Replace HelloWorld by the name of the class where you are using this line.
</p>
<pre>logger.log&#40;Level.WARNING, &quot;ok seriously wtf somebody check why {0} is {1} again?!&quot;,
new Object&#91;&#93;&#123;a , b&#125;&#41;;</pre>
<p>
or
</p>
<pre>logger.log&#40;Level.SEVERE, &quot;Game error: {0} must not be {1} after {2}! Please check your flux generator.&quot;,
new Object&#91;&#93;&#123;a , b , c&#125;&#41;;</pre>
<p>
As you see in the example, you should phrase potentially “customer facing” errors in a neutral way and offer a reason and a solution. If you use WARNINGs as replacement for casual printlns, make sure you deactivate them for the release.
</p>
<p>
More details about <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://download.oracle.com/javase/6/docs/api/java/util/logging/Level.html"><param name="text" value="<html><u>Java log levels</u></html>"><param name="textColor" value="blue"></object> here.
</p>
</div>
<h3><a>Switching the Logger on and off</a></h3>
<div>
<p>
In the release version you will deactivate the logging output to the terminal.
</p>
<p>
To deactivate the default logger, you set the log level to only report severe messages:
</p>
<pre>Logger.getLogger&#40;””&#41;.setLevel&#40;Level.SEVERE&#41;;</pre>
<p>
To reactivate it:
</p>
<pre>Logger.getLogger&#40;””&#41;.setLevel&#40;Level.FINE&#41;;</pre>
</div>
<h2><a>jMonkeyPlatform Log Files</a></h2>
<div>
<p>
You find the jMonkeyPlatform log file in /dev/var/log/messages.log in the jMonkeyPlatform preferences folder. You can learn the location of the preferences folder in the “About” screen of the jMonkeyPlatform under the label <strong>Userdir</strong>.
</p>
<ul>
<li><div> Windows: C:\Documents and Settings\YOUR_NAME\.jmonkeyplatform\”</div>
</li>
<li><div> Linux: /home/YOUR_NAME/.jmonkeyplatform/”</div>
</li>
<li><div> Mac <acronym title="Operating System">OS</acronym>: <code>/Users/YOUR_NAME/Library/Application Support/jmonkeyplatform/</code></div>
</li>
</ul>
</div>
<h2><a>Read Graphic Card Capabilites</a></h2>
<div>
<p>
You can read the graphic card&#039;s capabilities using the <code>com.jme3.renderer.Caps</code> class:
</p>
<pre>Collection&lt;Caps&gt; caps = renderer.getCaps&#40;&#41;;
Logger.getLogger&#40;HelloWorld.class.getName&#40;&#41;&#41;.log&#40;Level.INFO, “Caps: &#123;0&#125;” + caps.toString&#40;&#41;&#41;; </pre>
<p>
Replace HelloWorld by the name of the class where you are using this line.
</p>
<p>
The result looks like the following example:
</p>
<pre>
Caps: [FrameBuffer, FrameBufferMRT, FrameBufferMultisample, OpenGL20, ARBprogram, GLSL100, GLSL110, GLSL120, VertexTextureFetch, FloatTexture, TextureCompressionLATC]
</pre>
<p>
This would tell you that this user&#039;s graphic card only supports OpenGL 2.0 and cannot handle newer OpenGL features.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:logging?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:logging?do=export_xhtmlbody">view online version</a></em></p>

@ -1,107 +1,56 @@
<h1><a
<h1><a>How to Use Material Definitions (.j3md)</a></h1> name="how_to_use_material_definitions_j3md">How to Use Material Definitions (.j3md)</a></h1><div
<div> class="level1"><p> Typically, you create a set of custom materials, and use them throughout the game. For example, you can initialize and configure your materials objects in the <code>initSimpleApp()</code> method, and then load 3D models (Geometries) and use setMaterial() on them.</p><p> <strong>Tip:</strong> If you use one custom material very often, additionally read about storing material configurations in user-friendly <a
href="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3m Material Files</a>.</p></div><h2><a
<p> name="preparing_a_material">Preparing a Material</a></h2><div
class="level2"><ol><li
Typically, you create a set of custom materials, and use them throughout the game. For example, you can initialize and configure your materials objects in the <code>initSimpleApp()</code> method, and then load 3D models (Geometries) and use setMaterial() on them. class="level1"><div
</p> class="li"> Choose a Material Definition from the <a
href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> list that has the features that you need.</div><ul><li
<p> class="level2"><div
<strong>Tip:</strong> If you use one custom material very often, additionally read about storing material configurations in user-friendly <a href="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3m Material Files</a>. class="li"> Tip: If you don&#039;t know, you can always start with <code>Unshaded.j3md</code>.</div></li></ul></li><li
</p> class="level1"><div
class="li"> Look at the applicable parameters of the Material Definition and determine which ones you need to achieve the desired effect. Most parameters are optional.</div><ol><li
</div> class="level2"><div
class="li"> Create and save the necessary Texture files to the assets directory.</div><ul><li
<h2><a>Preparing a Material</a></h2> class="level3"><div
<div> class="li"> E.g. ColorMap; DiffuseMap, NormalMap, AlphaMap, etc…</div></li></ul></li><li
<ol> class="level2"><div
<li><div> Choose a Material Definition from the <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> list that has the features that you need. </div> class="li"> Determine the required values to achieve the effect that you want.</div><ul><li
<ul> class="level3"><div
<li><div> Tip: If you don&#039;t know, you can always start with <code>Unshaded.j3md</code>.</div> class="li"> E.g. Colors, floats, booleans, etc…</div></li></ul></li></ol></li></ol></div><h2><a
</li> name="using_a_material">Using a Material</a></h2><div
</ul> class="level2"><ol><li
</li> class="level1"><div
<li><div> Look at the applicable parameters of the Material Definition and determine which ones you need to achieve the desired effect. Most parameters are optional.</div> class="li"> In you Java code, create a Material object based on the .j3md file: e.g.<pre>Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;</pre></div></li><li
<ol> class="level1"><div
<li><div> Create and save the necessary Texture files to the assets directory.</div> class="li"> Configure your Material by setting the appropriate values listed in the <a
<ul> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> table. Here are examples of the methods that set the different data types:</div><ul><li
<li><div> E.g. ColorMap; DiffuseMap, NormalMap, AlphaMap, etc…</div> class="level2"><div
</li> class="li"> <code>mat.setColor( &quot;Color&quot;, ColorRGBA.White );</code></div></li><li
</ul> class="level2"><div
</li> class="li"> <code>mat.setTexture( &quot;ColorMap&quot;, assetManager.loadTexture(&quot;Interface/Logo/Monkey.png&quot; ));</code></div></li><li
<li><div> Determine the required values to achieve the effect that you want.</div> class="level2"><div
<ul> class="li"> <code>mat.setFloat( &quot;Shininess&quot;, 5f);</code></div></li><li
<li><div> E.g. Colors, floats, booleans, etc… </div> class="level2"><div
</li> class="li"> <code>mat.setBoolean( &quot;SphereMap&quot;, true);</code></div></li><li
</ul> class="level2"><div
</li> class="li"> <code>mat.setVector3( &quot;NormalScale&quot;, new Vector3f(1f,1f,1f));</code></div></li></ul></li><li
</ol> class="level1"><div
</li> class="li"> Use your prepared material on a Geometry:<pre>myGeometry.setMaterial&#40;mat&#41;;</pre></div></li><li
</ol> class="level1"><div
class="li"> (Optional) Adjust the texture scale:<pre>geometry.scaleTextureCoordinates&#40;new Vector2f&#40;1f, .5f&#41;&#41;;</pre></div></li></ol></div><h2><a
</div> name="examples">Examples</a></h2><div
class="level2"><p> A simpled textured material.</p><pre>Material mat = new Material&#40;assetManager,
<h2><a>Using a Material</a></h2>
<div>
<ol>
<li><div> In you Java code, create a Material object based on the .j3md file: e.g. <pre>Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;</pre></div>
</li>
<li><div> Configure your Material by setting the appropriate values listed in the <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> table. Here are examples of the methods that set the different data types:</div>
<ul>
<li><div> <code>mat.setColor( “Color”, ColorRGBA.White );</code></div>
</li>
<li><div> <code>mat.setTexture( “ColorMap”, assetManager.loadTexture(“Interface/Logo/Monkey.png” ));</code></div>
</li>
<li><div> <code>mat.setFloat( “Shininess”, 5f);</code></div>
</li>
<li><div> <code>mat.setBoolean( “SphereMap”, true);</code></div>
</li>
<li><div> <code>mat.setVector3( “NormalScale”, new Vector3f(1f,1f,1f));</code></div>
</li>
</ul>
</li>
<li><div> Use your prepared material on a Geometry: <pre>myGeometry.setMaterial&#40;mat&#41;;</pre></div>
</li>
<li><div> (Optional) Adjust the texture scale: <pre>geometry.scaleTextureCoordinates&#40;new Vector2f&#40;1f, .5f&#41;&#41;;</pre></div>
</li>
</ol>
</div>
<h2><a>Examples</a></h2>
<div>
<p>
A simpled textured material.
</p>
<pre>Material mat = new Material&#40;assetManager,
&quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.setTexture&#40;&quot;ColorMap&quot;, assetManager.loadTexture&#40; mat.setTexture&#40;&quot;ColorMap&quot;, assetManager.loadTexture&#40;
&quot;Interface/Logo/Monkey.jpg&quot;&#41;&#41;;</pre> &quot;Interface/Logo/Monkey.jpg&quot;&#41;&#41;;</pre><p> A textured material with a color bleeding through transparent areas.</p><pre>Material mat = new Material&#40;assetManager,
<p>
A textured material with a color bleeding through transparent areas.
</p>
<pre>Material mat = new Material&#40;assetManager,
&quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.setTexture&#40;&quot;ColorMap&quot;, assetManager.loadTexture&#40; mat.setTexture&#40;&quot;ColorMap&quot;, assetManager.loadTexture&#40;
&quot;Textures/ColoredTex/Monkey.png&quot;&#41;&#41;; &quot;Textures/ColoredTex/Monkey.png&quot;&#41;&#41;;
mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;</pre> mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;</pre><p> You can test these examples within the following code snippet. It creates a box and applies the material:</p><pre> Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
<p>
You can test these examples within the following code snippet. It creates a box and applies the material:
</p>
<pre> Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;; Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;;
// ... insert Material definition... // ... insert Material definition...
geom.setMaterial&#40;mat&#41;; geom.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;geom&#41;;</pre> rootNode.attachChild&#40;geom&#41;;</pre><p> <strong>Tip:</strong> You can find these and other common code snippets in the jMonkeyPlatform Code Palette. Drag and drop them into your source code.</p></div>
<p>
<strong>Tip:</strong> You can find these and other common code snippets in the jMonkeyPlatform Code Palette. Drag and drop them into your source code.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:material_definitions?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:material_definitions?do=export_xhtmlbody">view online version</a></em></p>

@ -1,303 +1,146 @@
<h1><a
<h1><a>Materials Overview</a></h1> name="materials_overview">Materials Overview</a></h1><div
<div> class="level1"><p> This table shows you which material definitions jME supplies by default, and how to make the most of your designer&#039;s 3D models by using material parameters.
If you are looking for information about how to use these materials in code, look at <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> and <a
href="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3M Material Files</a>. <br/> <strong>Tip:</strong> The two most commonly used materials are Lighting.j3md and Unshaded.j3md (standard materials with and without Phong illumination, respectively).</p></div><h2><a
This table shows you which material definitions jME supplies by default, and how to make the most of your designer&#039;s 3D models by using material parameters. name="table_of_material_definitions">Table of Material Definitions</a></h2><div
</p> class="level2"><p> Some parameters are &quot;optional&quot; because they are somewhat advanced. If you don&#039;t know what an option means, chances are that you are not using this feature in your textures – and you don&#039;t need to specify it. (E.g. YCoCg and LATC are image compression formats; Minnaert and WardIso are shader types.)
Also note that many other parameters are optional, even if they are not explicitly marked optional. For example, it&#039;s okay to specify solely the <code>DiffuseMap</code> and <code>NormalMap</code> when using <code>Lighting.j3md</code>. You are only using a subset of what is possible, but if that&#039;s what you want, you can do that. The developer should be in contact with the designer regarding what jME features individual Materials/Textures require.</p></div><h3><a
<p> name="coloring_and_standard_textures">Coloring and Standard Textures</a></h3><div
If you are looking for information about how to use these materials in code, look at <a href="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> and <a href="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3M Material Files</a>. class="level3"><div
</p> class="table sectionedit1"><table
class="inline"><tr
</div> class="row0"><th
class="col0 leftalign"> Material Definition</th><th
<h2><a>Table of Material Definitions</a></h2> class="col1"> Usage</th><th
<div> class="col2 leftalign"> Parameter : Type</th></tr><tr
class="row1"><td
<p> class="col0"> Common/MatDefs/Misc/Unshaded.j3md</td><td
class="col1"> Standard unlit Material. Use this for simple coloring, simple texturing, simple glow, simple transparency. <br/> See also: <a
Some parameters are “optional” because they are somewhat advanced. If you don&#039;t know what an option means, chances are that you are not using this feature in your textures – and you don&#039;t need to specify it. (E.g. YCoCg and LATC are image compression formats; Minnaert and WardIso are shader types.) href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></td><td
</p> class="col2"> ColorMap : Texture <br/> LightMap : Texture <br/> Color : Color <br/> VertexColor : Boolean <br/> SeparateTexCoord : Boolean <br/> GlowMap : Texture <br/> GlowColor: Color</td></tr><tr
class="row2"><td
<p> class="col0 leftalign"> Common/MatDefs/Misc/Sky.j3md</td><td
Also note that many other parameters are optional, even if they are not explicitly marked optional. For example, it&#039;s okay to specify solely the <code>DiffuseMap</code> and <code>NormalMap</code> when using <code>Lighting.j3md</code>. You are only using a subset of what is possible, but if that&#039;s what you want, you can do that. The developer should be in contact with the designer regarding what jME features individual Materials/Textures require. class="col1"> A solid skyblue, or use with a custom SkyDome texture. <br/> See also: <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">Sky</a></td><td
class="col2"> Texture : TextureCubeMap <br/> SphereMap : Boolean <br/> NormalScale : Vector3</td></tr><tr
</div> class="row3"><td
class="col0"> Common/MatDefs/Terrain/Terrain.j3md</td><td
<h3><a>Coloring and Standard Textures</a></h3> class="col1"> Splat textures for e.g. terrains. <br/> See also: <a
<div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a></td><td
<table> class="col2"> Texture1 : Texture (red) <br/> Texture1Scale : Float <br/> Texture2 : Texture (green) <br/> Texture2Scale : Float <br/> Texture3 : Texture (blue) <br/> Texture3Scale : Float <br/> Alpha : Texture</td></tr><tr
<tr> class="row4"><td
<th> Material Definition </th><th> Usage </th><th> Parameter : Type </th> class="col0 leftalign"> Common/MatDefs/Misc/Particle.j3md</td><td
</tr> class="col1"> Used with texture masks for particle effects, or for point sprites. <br/> The Quadratic value scales the particle for perspective view (<a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/effect/ParticleEmitter.java">formula</a>). <br/> Does support an optional colored glow effect. <br/> See also: <a
<td> Common/MatDefs/Misc/Unshaded.j3md </td><td> Standard unlit Material. </td><td> ColorMap : Texture <br/> href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a></td><td
LightMap : Texture <br/> class="col2"> Texture : Texture <br/> GlowMap : Texture <br/> GlowColor : Color <br/> Quadratic : Float <br/> PointSprite : Boolean</td></tr></table></div><p> <br/></p></div><h3><a
Color : Color <br/> name="light_and_shadow">Light and Shadow</a></h3><div
VertexColor : Boolean <br/> class="level3"><div
SeperateTexCoord : Boolean <br/> class="table sectionedit2"><table
GlowMap : Texture <br/> class="inline"><tr
GlowColor: Color </td> class="row0"><th
</tr> class="col0 leftalign"> Material Definition</th><th
<tr> class="col1"> Usage</th><th
<td> Common/MatDefs/Misc/Sky.j3md </td><td> A solid skyblue, or use with a custom SkyDome texture. <br/> class="col2 leftalign"> Parameters</th></tr><tr
See also: <a href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">Sky</a> </td><td> Texture : TextureCubeMap <br/> class="row1"><td
SphereMap : Boolean <br/> class="col0 leftalign"> Common/MatDefs/Light/Lighting.j3md</td><td
NormalScale : Vector3 </td> class="col1"> Standard lit material with Phong Illumination. Use this material together with DiffuseMap, SpecularMap, BumpMap (NormalMaps, ParalaxMap) textures. Supports shininess, transparency, and plain material colors (Diffuse, Ambient, Specular colors). <br/> See also: <a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> <strong>Note:</strong> Lit materials require a <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/light_and_shadow.html">light source</a>! Glowing materials require a <a
<td> Common/MatDefs/Terrain/Terrain.j3md </td><td> Splat textures for e.g. terrains. <br/> href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">FilterPostProcessor</a>!</td><td
See also: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a> </td><td> Texture1 : Texture (red) <br/> class="col2"> DiffuseMap : Texture <br/> UseAlpha<sup><a
Texture1Scale : Float <br/> href="#fn__1">1)</a></sup> : Boolean <br/> NormalMap : Texture <br/> LATC<sup><a
Texture2 : Texture (green) <br/> href="#fn__2">2)</a></sup> : Boolean <br/> SpecularMap : Texture <br/> Shininess : Float <br/> ParallaxMap : Texture <br/> AlphaMap : Texture <br/> AlphaDiscardThreshold: Float <br/> ColorRamp : Texture <br/> <strong>Glow (optional)</strong> <br/> GlowMap : Texture <br/> GlowColor : Color <br/> <strong>Performance and quality (optional)</strong> <br/> VertexLighting : Boolean <br/> UseVertexColor : Boolean <br/> LowQuality : Boolean <br/> HighQuality : Boolean <br/> <strong>Material Colors (optional)</strong> <br/> UseMaterialColors : Boolean <br/> Diffuse : Color <br/> Ambient : Color <br/> Specular : Color <br/> <strong>Tangent shading (optional):</strong> <br/> VTangent : Boolean <br/> Minnaert<sup><a
Texture2Scale : Float <br/> href="#fn__3">3)</a></sup> : Boolean <br/> WardIso<sup><a
Texture3 : Texture (blue) <br/> href="#fn__4">4)</a></sup> : Boolean</td></tr><tr
Texture3Scale : Float <br/> class="row2"><td
Alpha : Texture </td> class="col0">Common/MatDefs/Terrain/TerrainLighting.j3md</td><td
</tr> class="col1">Same kind of splat texture as Terrain.j3md, but with shading. <br/> Requires a light source.</td><td
<tr> class="col2">Color Diffuse : Color <br/> Ambient : Color <br/> Shininess : Float <br/> Specular : Color <br/> SpecularMap : Texture <br/> WardIso : Boolean <br/> useTriPlanarMapping : Boolean <br/> <strong>Texture Splat Maps</strong> <br/> DiffuseMap : Texture <br/> DiffuseMap_0_scale : Float <br/> NormalMap : Texture <br/> DiffuseMap_1 : Texture <br/> DiffuseMap_1_scale : Float <br/> NormalMap_1 : Texture <br/> DiffuseMap_2 : Texture <br/> DiffuseMap_2_scale : Float <br/> NormalMap_2 : Texture <br/> DiffuseMap_3 : Texture <br/> DiffuseMap_3_scale : Float <br/> NormalMap_3 : Texture <br/> <strong>Alpha Maps</strong> <br/> AlphaMap : Texture <br/> AlphaMap_1 : Texture <br/> AlphaMap_2 : Texture <br/> <strong>Glowing</strong> <br/> GlowMap : Texture <br/> GlowColor : Color</td></tr><tr
<td> Common/MatDefs/Misc/Particle.j3md </td><td> Used with texture masks for particle effects, or for point sprites. <br/> class="row3"><td
The Quadratic value scales the particle for perspective view (<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/effect/ParticleEmitter.java"><param name="text" value="<html><u>formula</u></html>"><param name="textColor" value="blue"></object>). <br/> class="col0 leftalign"> Common/MatDefs/Light/Reflection.j3md</td><td
Does support an optional colored glow effect. <br/> class="col1"> Reflective glass material with environment map (CubeMap/SphereMap). <br/> Requires light source. <br/> See also: <a
See also: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a> </td><td> Texture : Texture <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestCubeMap.java">TestCubeMap.java</a></td><td
GlowMap : Texture <br/> class="col2"> Texture : Texture <br/> SphereMap: Boolean</td></tr></table></div></div><h3><a
GlowColor : Color <br/> name="testing_and_debugging">Testing and Debugging</a></h3><div
Quadratic : Float <br/> class="level3"><div
PointSprite : Boolean </td> class="table sectionedit3"><table
</tr> class="inline"><tr
</table> class="row0"><th
<table> class="col0 leftalign"> Material Definition</th><th
<tr> class="col1"> Usage</th><th
<th> Deprecated Material Definition </th><th> Usage </th><th> Parameter : Type </th> class="col2 leftalign"> Parameters</th></tr><tr
</tr> class="row1"><td
<tr> class="col0 leftalign"> Common/MatDefs/Misc/ShowNormals.j3md</td><td
<td> <em>Deprecated: use Unshaded.j3md instead</em> <br/> class="col1"> A color gradient calculated from the model&#039;s surface normals. You can use this built-in material to test models that have no material, or as fall-back default material.</td><td
Common/MatDefs/Misc/SimpleTextured.j3md </td><td> Standard unlit textured Material. </td><td> ColorMap : Texture <br/> class="col2"> –</td></tr></table></div><p> <br/> <strong>Note:</strong> Common/MatDefs/Misc/SimpleTextured.j3md, ColoredTextured.j3md, VertexColor.j3md, Wireframe.j3md have been deprecated. Use equivalent features of Unshaded.j3md instead.</p></div><h2><a
ShowAlpha : Boolean (optional) <br/> name="transparency">Transparency</a></h2><div
Normalize : Boolean (optional) <br/> class="level2"><p> Most Material Definitions support an alpha channel for transparency. In an RGBA color, the last float is the alpha channel: 0.0f is transparent, 1.0f is opaque. <br/> For example: <code>mat.setColor(&quot;Color&quot;, new ColorRGBA(1,0,0,0.5f));</code> is a half-opaque red. <br/> Additionally, you must specify a blendmode:</p><div
YCoCg<sup><a href="#fn__1">1)</a></sup> : Boolean (optional) <br/> class="table sectionedit4"><table
LATC<sup><a href="#fn__2">2)</a></sup> : Boolean (optional) </td> class="inline"><tr
</tr> class="row0"><th
<tr> class="col0">Option</th><th
<td> <em>Deprecated: use Unshaded.j3md instead</em> <br/> class="col1">Usage</th></tr><tr
Common/MatDefs/Misc/ColoredTextured.j3md</td><td> Transparent texture with one solid color bleeding through transparent areas. </td><td> ColorMap : Texture <br/> class="row1"><td
Color : Color </td> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.Off);</td><td
</tr> class="col1">Opaque</td></tr><tr
</table> class="row2"><td
class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);</td><td
</div> class="col1">Use this for normal transparency. Interpolates the background pixel with the current by using the current pixel&#039;s alpha. E.g. alpha-blended vegetation.</td></tr><tr
class="row3"><td
<h3><a>Light and Shadow</a></h3> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.Additive);</td><td
<div> class="col1">Additive alpha blending adds colors in a commutative way, i.e. the result does not depend on the order of transparent layers. Adds the background pixel color with the current pixel color. E.g. particle effects that have black color as background.</td></tr><tr
<table> class="row4"><td
<tr> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);</td><td
<th> Material Definition </th><th> Usage </th><th> Parameters </th> class="col1">Same as &quot;Additive&quot;, except first it multiplies the current pixel color by the pixel alpha. E.g. used for particle effects that have alpha as background.</td></tr><tr
</tr> class="row5"><td
<tr> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.Color);</td><td
<td> Common/MatDefs/Light/Lighting.j3md </td><td> Standard lit material with Phong Lighting. Use with SpecularMap, BumpMap, NormalMaps textures, Shininess, etc. <br/> class="col1">Blends by color. Generally useless.</td></tr><tr
Requires light source! </td><td> DiffuseMap : Texture <br/> class="row6"><td
UseAlpha<sup><a href="#fn__3">3)</a></sup> : Boolean <br/> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.Modulate);</td><td
NormalMap : Texture <br/> class="col1">Multiplies the background pixel by the current pixel.</td></tr><tr
LATC<sup><a href="#fn__4">4)</a></sup> : Boolean <br/> class="row7"><td
SpecularMap : Texture <br/> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.ModulateX2);</td><td
Shininess : Float <br/> class="col1">Same as &quot;Modulate&quot;, except the result is doubled.</td></tr><tr
ParallaxMap : Texture <br/> class="row8"><td
AlphaMap : Texture <br/> class="col0">mat.getAdditionalRenderState().setBlendMode(BlendMode.PremultAlpha);</td><td
AlphaDiscardThreshold: Float <br/> class="col1">Pre-multiplied alpha blending. E.g. if the color of the object has already been multiplied by its alpha, this is used instead of &quot;Alpha&quot; blend mode.</td></tr><tr
ColorRamp : Texture <br/> class="row9"><td
<strong>Glow (optional)</strong> <br/> class="col0">mat.getAdditionalRenderState().setDepthWrite(false);</td><td
GlowMap : Texture <br/> class="col1">Use this if you have several transparent objects obscuring one another. Disables writing of the pixel&#039;s depth value to the depth buffer.</td></tr><tr
GlowColor : Color <br/> class="row10"><td
<strong>Performance and quality (optional)</strong> <br/> class="col0">mat.getAdditionalRenderState().setAlphaFallOff(0.5f); <br/> mat.getAdditionalRenderState().setAlphaTest(true)</td><td
VertexLighting : Boolean <br/> class="col1">Enables alpha test, generally used for vegetation. Works the same way as &quot;AlphaDiscardThreshold&quot;.</td></tr></table></div><p> <br/> Also note the AlphaDiscardThreshold value for materials based on Lighting.j3md. The renderer does not render pixels whose transparancy is below the threshold.</p></div><h2><a
UseVertexColor : Boolean <br/> name="material_options">Material Options</a></h2><div
LowQuality : Boolean <br/> class="level2"><div
HighQuality : Boolean <br/> class="table sectionedit5"><table
<strong>Material Colors (optional)</strong> <br/> class="inline"><tr
UseMaterialColors : Boolean <br/> class="row0"><td
Diffuse : Color <br/> class="col0">mat.getAdditionalRenderState().setWireframe(true);</td><td
Ambient : Color <br/> class="col1">Switch to showing the (textured) Material in wireframe mode</td></tr><tr
Specular : Color <br/> class="row1"><td
<strong>Tangent shading (optional):</strong> <br/> class="col0">mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); <br/> mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Front); <br/> mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back); <br/> mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.FrontAndBack)</td><td
VTangent : Boolean <br/> class="col1">Activate back- or frontface culling, both (=invisible), or off. Backface culling is activated by default as an optimization.</td></tr><tr
Minnaert<sup><a href="#fn__5">5)</a></sup> : Boolean <br/> class="row2"><td
WardIso<sup><a href="#fn__6">6)</a></sup> : Boolean </td> class="col0">mat.getAdditionalRenderState().setColorWrite(false);</td><td
</tr> class="col1">Disable writing the color of pixels. Use this together with setDepthWrite(true) to write pixels only to the depth buffer for example.</td></tr><tr
<tr> class="row3"><td
<td>Common/MatDefs/Terrain/TerrainLighting.j3md</td><td>Same kind of splat texture as Terrain.j3md, but with shading. <br/> class="col0">mat.getAdditionalRenderState().setPointSprite(true);</td><td
Requires a light source.</td><td>Color Diffuse : Color <br/> class="col1">Enables point-sprite mode, so meshes with &quot;Mode.Points&quot; will be rendered as textured sprites. Note that gl_PointCoord must be set in the shader. Point sprites are used for hardware accelerated particle effects.</td></tr><tr
Ambient : Color <br/> class="row4"><td
Shininess : Float <br/> class="col0">mat.getAdditionalRenderState().setPolyOffset();</td><td
Specular : Color <br/> class="col1">Enable polygon offset. Use this when you have meshes that have triangles really close to each over (e.g. <a
SpecularMap : Texture <br/> href="http://en.wikipedia.org/wiki/Coplanarity">Coplanar</a>), it will shift the depth values to prevent <a
WardIso : Boolean <br/> href="http://en.wikipedia.org/wiki/Z-fighting">Z-fighting</a>.</td></tr></table></div></div><div
useTriPlanarMapping : Boolean <br/> class="footnotes"><div
<strong>Texture Splat Maps</strong> <br/> class="fn"><sup><a
DiffuseMap : Texture <br/> href="#fnt__1">1)</a></sup> UseAlpha specifies whether DiffuseMap uses the alpha channel</div><div
DiffuseMap_0_scale : Float <br/> class="fn"><sup><a
NormalMap : Texture <br/> href="#fnt__2">2)</a></sup> LATC Specifies whether NormalMap is BC5/ATI2n/LATC/3Dc-compressed</div><div
DiffuseMap_1 : Texture <br/> class="fn"><sup><a
DiffuseMap_1_scale : Float <br/> href="#fnt__3">3)</a></sup> Minnaert is a shader type.</div><div
NormalMap_1 : Texture <br/> class="fn"><sup><a
DiffuseMap_2 : Texture <br/> href="#fnt__4">4)</a></sup> WardIso is a shader type.</div></div>
DiffuseMap_2_scale : Float <br/>
NormalMap_2 : Texture <br/>
DiffuseMap_3 : Texture <br/>
DiffuseMap_3_scale : Float <br/>
NormalMap_3 : Texture <br/>
<strong>Alpha Maps</strong> <br/>
AlphaMap : Texture <br/>
AlphaMap_1 : Texture <br/>
AlphaMap_2 : Texture <br/>
<strong>Glowing</strong> <br/>
GlowMap : Texture <br/>
GlowColor : Color </td>
</tr>
<tr>
<td> Common/MatDefs/Light/Reflection.j3md </td><td> Reflective glass material with environment map (CubeMap/SphereMap). <br/>
Requires light source. <br/>
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestCubeMap.java"><param name="text" value="<html><u>TestCubeMap.java</u></html>"><param name="textColor" value="blue"></object> </td><td> Texture : Texture <br/>
SphereMap: Boolean </td>
</tr>
</table>
</div>
<h3><a>Testing and Debugging</a></h3>
<div>
<table>
<tr>
<th> Material Definition </th><th> Usage </th><th> Parameters </th>
</tr>
<tr>
<td> Common/MatDefs/Misc/VertexColor.j3md </td><td> Every vertex gets a solid color, colors of mesh faces are interpolated. </td><td></td>
</tr>
<tr>
<td> Common/MatDefs/Misc/ShowNormals.j3md </td><td> A color gradient calculated from surface normals. </td><td></td>
</tr>
<tr>
<td> Common/MatDefs/Misc/Wireframe.j3md </td><td> Transparent wireframe outline. </td><td> Color : Color </td>
</tr>
</table>
</div>
<h2><a>Transparency</a></h2>
<div>
<p>
Most Material Definitions support an alpha channel for transparency. In an RGBA color, the last float is the alpha value, whereas 0.0f = transparent, 1.0f = opaque.
</p>
<p>
For example: <code>mat.setColor(“Color”, new ColorRGBA(1,0,0,0.5f));</code> is a half-opaque red.
</p>
<p>
Additionally, specify a blendmode:
</p>
<table>
<tr>
<th>Option</th><th>Usage</th>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.Off);</td><td>Opaque</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);</td><td>Use this for normal transparency. Interpolates the background pixel with the current by using the current pixel&#039;s alpha. E.g. alpha-blended vegetation. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.Additive);</td><td>Additive alpha blending adds colors in a commutative way, i.e. the result does not depend on the order of transparent layers. Adds the background pixel color with the current pixel color. E.g. particle effects that have black color as background. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.AlphaAdditive);</td><td>Same as “Additive”, except first it multiplies the current pixel color by the pixel alpha. E.g. used for particle effects that have alpha as background. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.Color);</td><td>Blends by color. Generally useless.</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.Modulate);</td><td>Multiplies the background pixel by the current pixel.</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.ModulateX2);</td><td>Same as “Modulate”, except the result is doubled.</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setBlendMode(BlendMode.PremultAlpha);</td><td>Pre-multiplied alpha blending. E.g. if the color of the object has already been multiplied by its alpha, this is used instead of “Alpha” blend mode. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setDepthWrite(false);</td><td>Use this if you have several transparent objects obscuring one another. Disables writing of the pixel&#039;s depth value to the depth buffer. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setAlphaFallOff(0.5f); <br/>
mat.getAdditionalRenderState().setAlphaTest(true)</td><td>Enables alpha test, generally used for vegetation. Works the same way as “AlphaDiscardThreshold”.</td>
</tr>
</table>
<p>
Also note the AlphaDiscardThreshold value for materials based on Lighting.j3md. The renderer does not render pixels whose transparancy is below the threshold.
</p>
</div>
<h2><a>Material Options</a></h2>
<div>
<table>
<tr>
<td>mat.getAdditionalRenderState().setWireframe(true);</td><td>Switch to showing the (textured) Material in wireframe mode</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); <br/>
mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Front); <br/>
mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back); <br/>
mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.FrontAndBack)</td><td>Activate back- or frontface culling, both (=invisible), or off. Backface culling is activated by default as an optimization.</td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setColorWrite(false);</td><td>Disable writing the color of pixels. Use this together with setDepthWrite(true) to write pixels only to the depth buffer for example. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setPointSprite(true);</td><td>Enables point-sprite mode, so meshes with “Mode.Points” will be rendered as textured sprites. Note that gl_PointCoord must be set in the shader. Point sprites are used for hardware accelerated particle effects. </td>
</tr>
<tr>
<td>mat.getAdditionalRenderState().setPolyOffset();</td><td>Enable polygon offset. Use this when you have meshes that have triangles really close to each over (e.g. <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/Coplanarity"><param name="text" value="<html><u>Coplanar</u></html>"><param name="textColor" value="blue"></object>), it will shift the depth values to prevent <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/Z-fighting"><param name="text" value="<html><u>Z-fighting</u></html>"><param name="textColor" value="blue"></object>.</td>
</tr>
</table>
</div>
<h2><a>Internal Use Only</a></h2>
<div>
<p>
You may also come across to mentions of the following Material Definition files, but they are only used internally.
</p>
<pre>
Common/MatDefs/Blur/HGaussianBlur.j3md, VGaussianBlur.j3md, RadialBlur.j3md
Common/MatDefs/Light/LightScattering.j3md, Deferred.j3md
Common/MatDefs/Shadow/PreShadow.j3md, PostShadow.j3md, PostShadowPSSM.j3md
Common/MatDefs/SSAO/normal.j3md, ssao.j3md
Common/MatDefs/Gui/Gui.j3md
Common/MatDefs/Hdr/LogLum.j3md, ToneMap.j3md</pre>
</div>
<div>
<div><sup><a href="#fnt__1">1)</a></sup>
YCoCg is an image compression format.</div>
<div><sup><a href="#fnt__2">2)</a></sup>
LATC is an image compression format.</div>
<div><sup><a href="#fnt__3">3)</a></sup>
UseAlpha specifies whether DiffuseMap uses the alpha channel</div>
<div><sup><a href="#fnt__4">4)</a></sup>
LATC Specifies whether NormalMap is BC5/ATI2n/LATC/3Dc-compressed</div>
<div><sup><a href="#fnt__5">5)</a></sup>
Minnaert is a shader type.</div>
<div><sup><a href="#fnt__6">6)</a></sup>
WardIso is a shader type.</div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:materials_overview?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:materials_overview?do=export_xhtmlbody">view online version</a></em></p>

@ -1,163 +1,129 @@
<h1><a
<h1><a>Polygon Meshes</a></h1> name="polygon_meshes">Polygon Meshes</a></h1><div
<div> class="level1"><p> <a
href="/wiki/lib/exe/detail.php/jme3:dolphin-mesh.png?id=jme3%3Aadvanced%3Amesh"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/dolphin-mesh.png" class="mediaright" align="right" alt="" /></a></p><p> All visible game elements in a scene, whether it is a Model or a Shape, are made up of polygon meshes. JME3 has a com.jme3.scene.Mesh class that represents all meshes.</p><ul><li
class="level1"><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/dolphin-mesh.png"> class="li"> Meshes are made up of triangles. <br/> <code>getTriangleCount(…)</code> and <code>getTriangle(…)</code></div></li><li
</p> class="level1"><div
class="li"> Each mesh has a unique ID <br/> <code>getId()</code></div></li><li
<p> class="level1"><div
All visible game elements in a scene, whether it is a Model or a Shape, are made up of polygon meshes. JME3 has a com.jme3.scene.Mesh class that represents all meshes. class="li"> Meshes have transformations: Location (local translation), rotation, scale.</div></li><li
class="level1"><div
</p> class="li"> Meshes have a bounding volume. jME3 can detect intersections (that is, non-physical collisions) between meshes, or between meshes and 2D elements such as rays. <br/> <code>collideWith()</code>.</div></li><li
<ul> class="level1"><div
<li><div> Meshes are made up of triangles. <br/> class="li"> Meshes are locked with <code>setStatic()</code> and unlocked with <code>setDynamic()</code>.</div><ul><li
<code>getTriangleCount(…)</code> and <code>getTriangle(…)</code></div> class="level2"><div
</li> class="li"> Static Meshes cannot be modified, but are more optimized and faster (they can be precalculated).</div></li><li
<li><div> Each mesh has a unique ID <br/> class="level2"><div
<code>getId()</code></div> class="li"> Dynamic Meshes can be modified live, but are not optimized and slower.</div></li></ul></li><li
</li> class="level1"><div
<li><div> Meshes have transformations: Location (local translation), rotation, scale.</div> class="li"> (Optional) Meshes can have a LOD (level of detail optimization) that renders more or less details depending on distance from the camera.</div></li></ul><p> You can use default <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s as meshes; load <a
<li><div> Meshes have a bounding volume. jME3 can detect intersections (that is, non-physical collisions) between meshes, or between meshes and 2D elements such as rays. <br/> href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D models</a> (i.e. meshes created in external applications); or create free-form <a
<code>collideWith()</code>.</div> href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">custom meshes</a> programmatically.</p></div><h2><a
</li> name="vertex_buffer">Vertex Buffer</a></h2><div
<li><div> Meshes are locked with <code>setStatic()</code> and unlocked with <code>setDynamic()</code>. </div> class="level2"><p> The VertexBuffer contains a particular type of geometry data used by Meshes. Every VertexBuffer set on a Mesh is sent as an attribute to the vertex shader to be processed.</p><div
<ul> class="table sectionedit1"><table
<li><div> Static Meshes cannot be modified, but are more optimized and faster (they can be precalculated). </div> class="inline"><tr
</li> class="row0"><th
<li><div> Dynamic Meshes can be modified live, but are not optimized and slower. </div> class="col0">Vertex Buffer Type</th><th
</li> class="col1">Description</th></tr><tr
</ul> class="row1"><td
</li> class="col0">Type.Position</td><td
<li><div> (Optional) Meshes can have a LOD (level of detail optimization) that renders more or less details depending on distance from the camera.</div> class="col1">Position of the vertex (3 floats)</td></tr><tr
</li> class="row2"><td
</ul> class="col0">Type.Index</td><td
class="col1"> Specifies the index buffer, must contain integer data.</td></tr><tr
<p> class="row3"><td
class="col0">Type.TexCoord</td><td
You can use default <a href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s as meshes; load <a href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D models</a> (i.e. meshes created in external applications); or create free-form <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">custom meshes</a> programmatically. class="col1"> Texture coordinate</td></tr><tr
</p> class="row4"><td
class="col0">Type.TexCoord2</td><td
</div> class="col1"> Texture coordinate #2</td></tr><tr
class="row5"><td
<h2><a>Vertex Buffer</a></h2> class="col0">Type.Normal</td><td
<div> class="col1"> Normal vector, normalized.</td></tr><tr
class="row6"><td
<p> class="col0">Type.Tangent</td><td
class="col1"> Tangent vector, normalized.</td></tr><tr
The VertexBuffer contains a particular type of geometry data used by Meshes. Every VertexBuffer set on a Mesh is sent as an attribute to the vertex shader to be processed. class="row7"><td
class="col0">Type.Binormal</td><td
</p> class="col1"> Binormal vector, normalized.</td></tr><tr
<table> class="row8"><td
<tr> class="col0">Type.Color</td><td
<th>Vertex Buffer Type</th><th>Description</th> class="col1"> Color and Alpha (4 floats)</td></tr><tr
</tr> class="row9"><td
<tr> class="col0">Type.Size</td><td
<td>Type.Position </td><td>Position of the vertex (3 floats)</td> class="col1">The size of the point when using point buffers.</td></tr><tr
</tr> class="row10"><td
<tr> class="col0">Type.InterleavedData</td><td
<td>Type.Index </td><td> Specifies the index buffer, must contain integer data.</td> class="col1"> Specifies the source data for various vertex buffers when interleaving is used.</td></tr><tr
</tr> class="row11"><td
<tr> class="col0">Type.BindPosePosition</td><td
<td>Type.TexCoord </td><td> Texture coordinate</td> class="col1"> Inital vertex position, used with animation.</td></tr><tr
</tr> class="row12"><td
<tr> class="col0">Type.BindPoseNormal</td><td
<td>Type.TexCoord2 </td><td> Texture coordinate #2</td> class="col1"> Inital vertex normals, used with animation</td></tr><tr
</tr> class="row13"><td
<tr> class="col0">Type.BoneWeight</td><td
<td>Type.Normal </td><td> Normal vector, normalized.</td> class="col1"> Bone weights, used with animation</td></tr><tr
</tr> class="row14"><td
<tr> class="col0">Type.BoneIndex</td><td
<td>Type.Tangent </td><td> Tangent vector, normalized.</td> class="col1"> Bone indices, used with animation</td></tr></table></div><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td>Type.Binormal </td><td> Binormal vector, normalized.</td> class="row0"><th
</tr> class="col0">Mesh method</th><th
<tr> class="col1">Description</th></tr><tr
<td>Type.Color </td><td> Color and Alpha (4 floats)</td> class="row1"><td
</tr> class="col0" colspan="2">setLineWidth(1)</td></tr><tr
<tr> class="row2"><td
<td>Type.Size </td><td>The size of the point when using point buffers.</td> class="col0" colspan="2">setPointSize(4.0f)</td></tr><tr
</tr> class="row3"><td
<tr> class="col0" colspan="2">setBound(boundingVolume)</td></tr><tr
<td>Type.InterleavedData </td><td> Specifies the source data for various vertex buffers when interleaving is used.</td> class="row4"><td
</tr> class="col0">setStatic()</td><td
<tr> class="col1">Locks the mesh so you cannot modify it anymore, thus optimizing its data (faster).</td></tr><tr
<td>Type.BindPosePosition </td><td> Inital vertex position, used with animation.</td> class="row5"><td
</tr> class="col0">setDynamic()</td><td
<tr> class="col1">Unlocks the mesh so you can modified it, but this will un-optimize the data (slower).</td></tr><tr
<td>Type.BindPoseNormal </td><td> Inital vertex normals, used with animation</td> class="row6"><td
</tr> class="col0">setMode(Mesh.Mode.Points)</td><td
<tr> class="col1"> Used to set mesh modes, see below</td></tr><tr
<td>Type.BoneWeight </td><td> Bone weights, used with animation</td> class="row7"><td
</tr> class="col0" colspan="2">getId()</td></tr><tr
<tr> class="row8"><td
<td>Type.BoneIndex </td><td> Bone indices, used with animation</td> class="col0" colspan="2">getTriangle(int,tri)</td></tr><tr
</tr> class="row9"><td
</table> class="col0" colspan="2">scaleTextureCoordinates(Vector2f)</td></tr></table></div><div
<table> class="table sectionedit3"><table
<tr> class="inline"><tr
<th>Mesh method</th><th>Description</th> class="row0"><th
</tr> class="col0">Mesh Mode</th><th
<tr> class="col1">Description</th></tr><tr
<td>setLineWidth(1)</td> class="row1"><td
</tr> class="col0">Mesh.Mode.Points</td><td
<tr> class="col1">Show only corner points</td></tr><tr
<td>setPointSize(4.0f)</td> class="row2"><td
</tr> class="col0">Mesh.Mode.Lines</td><td
<tr> class="col1">Show lines</td></tr><tr
<td>setBound(boundingVolume)</td> class="row3"><td
</tr> class="col0">Mesh.Mode.LineLoop</td><td
<tr> class="col1">?</td></tr><tr
<td>setStatic()</td><td>Locks the mesh so you cannot modify it anymore, thus optimizing its data (faster).</td> class="row4"><td
</tr> class="col0">Mesh.Mode.LineStrip</td><td
<tr> class="col1">?</td></tr><tr
<td>setDynamic()</td><td>Unlocks the mesh so you can modified it, but this will un-optimize the data (slower).</td> class="row5"><td
</tr> class="col0">Mesh.Mode.Triangles</td><td
<tr> class="col1">?</td></tr><tr
<td>setMode(Mesh.Mode.Points)</td><td> Used to set mesh modes, see below</td> class="row6"><td
</tr> class="col0">Mesh.Mode.TriangleStrip</td><td
<tr> class="col1">?</td></tr><tr
<td>getId()</td> class="row7"><td
</tr> class="col0">Mesh.Mode.TriangleFan</td><td
<tr> class="col1">?</td></tr><tr
<td>getTriangle(int,tri)</td> class="row8"><td
</tr> class="col0">Mesh.Mode.Hybrid</td><td
<tr> class="col1">?</td></tr></table></div></div>
<td>scaleTextureCoordinates(Vector2f)</td>
</tr>
</table>
<table>
<tr>
<th>Mesh Mode</th><th>Description</th>
</tr>
<tr>
<td>Mesh.Mode.Points</td><td>Show only corner points</td>
</tr>
<tr>
<td>Mesh.Mode.Lines</td><td>Show lines</td>
</tr>
<tr>
<td>Mesh.Mode.LineLoop</td><td>?</td>
</tr>
<tr>
<td>Mesh.Mode.LineStrip</td><td>?</td>
</tr>
<tr>
<td>Mesh.Mode.Triangles</td><td>?</td>
</tr>
<tr>
<td>Mesh.Mode.TriangleStrip</td><td>?</td>
</tr>
<tr>
<td>Mesh.Mode.TriangleFan</td><td>?</td>
</tr>
<tr>
<td>Mesh.Mode.Hybrid</td><td>?</td>
</tr>
</table>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:mesh?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:mesh?do=export_xhtmlbody">view online version</a></em></p>

@ -1,36 +1,12 @@
<h1><a
<h1><a>Motion path</a></h1> name="motion_path">Motion path</a></h1><div
<div> class="level1"><p> When creating cinematics, we need a convenient way of making objects follow a path, or making smooth camera travelings.
That&#039;s where the MotionPath come in handy.</p></div><h2><a
<p> name="description">Description</a></h2><div
class="level2"><p> The MotionPath is a control over a Spatial object. that means that it&#039;s able to update the Spatial position on each frame.<br/> It contains a list of way points that are positions in world space that determine the general shape of the path.<br/> The accurate shape is computed using a linear interpolation or a <a
When creating cinematics, we need a convenient way of making objects follow a path, or making smooth camera travelings. href="http://www.mvps.org/directx/articles/catmull/">Catmull-Rom</a> spline interpolation.</p><ul><li
That&#039;s where the MotionPath come in handy. class="level1"><div
</p> class="li"> Linear interpolation result in straight segments between the way points.</div></li><li
class="level1"><div
</div> class="li"> Catmull-Rom splines allow to create a very smooth path with few way points, ensure that the curve goes through each way point, with the possibility to adjust the tension of the curve. This is the interpolation you are going to use in most cases</div></li></ul><p> more to come…</p></div>
<h2><a>Description</a></h2>
<div>
<p>
The MotionPath is a control over a Spatial object. that means that it&#039;s able to update the Spatial position on each frame.<br/>
It contains a list of way points that are positions in world space that determine the general shape of the path.<br/>
The accurate shape is computed using a linear interpolation or a <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.mvps.org/directx/articles/catmull/"><param name="text" value="<html><u>Catmull-Rom</u></html>"><param name="textColor" value="blue"></object> spline interpolation.
</p>
<ul>
<li><div> Linear interpolation result in straight segments between the way points.</div>
</li>
<li><div> Catmull-Rom splines allow to create a very smooth path with few way points, ensure that the curve goes through each way point, with the possibility to adjust the tension of the curve. This is the interpolation you are going to use in most cases</div>
</li>
</ul>
<p>
more to come…
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:motion_path?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:motion_path?do=export_xhtmlbody">view online version</a></em></p>

@ -1,68 +1,31 @@
<h1><a
<h1><a>Multiple Camera Views</a></h1> name="multiple_camera_views">Multiple Camera Views</a></h1><div
<div> class="level1"><p> You can split the screen and look into the 3D scene from different camera angles at the same time. In this example, we create four views (2x2) with the same aspect ratio as the normal view, but half the size.</p><p> The packages used in this example are <code>com.jme3.renderer.Camera</code> and <code>com.jme3.renderer.ViewPort</code>. You can get the full sample code here: <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java">TestMultiViews.java</a></p></div><h2><a
<p> name="set_up_the_first_view">Set up the First View</a></h2><div
class="level2"><p> We use the preconfigured Camera <code>cam</code> and <code>viewPort</code> from <code>SimpleApplication</code> for the first view.</p><pre>viewPort.setBackgroundColor&#40;ColorRGBA.Blue&#41;;
You can split the screen and look into the 3D scene from different camera angles at the same time. In this example, we create four views (2&times;2) with the same aspect ratio as the normal view, but half the size.
</p>
<p>
The packages used in this example are <code>com.jme3.renderer.Camera</code> and <code>com.jme3.renderer.ViewPort</code>. You can get the full sample code here: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java"><param name="text" value="<html><u>TestMultiViews.java</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<h2><a>Set up the First View</a></h2>
<div>
<p>
We use the preconfigured Camera <code>cam</code> and <code>viewPort</code> from <code>SimpleApplication</code> for the first view.
</p>
<pre>viewPort.setBackgroundColor&#40;ColorRGBA.Blue&#41;;
cam.setViewPort&#40;.5f, 1f, 0f, 0.5f&#41;; // resize the viewPort cam.setViewPort&#40;.5f, 1f, 0f, 0.5f&#41;; // resize the viewPort
cam.setLocation&#40;new Vector3f&#40;3.3212643f, 4.484704f, 4.2812433f&#41;&#41;; cam.setLocation&#40;new Vector3f&#40;3.3212643f, 4.484704f, 4.2812433f&#41;&#41;;
cam.setRotation&#40;new Quaternion &#40;-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f&#41;&#41;;</pre> cam.setRotation&#40;new Quaternion &#40;-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f&#41;&#41;;</pre><p> Place the main camera in the scene and rotate it in its start position.</p><p> We will have a detailed look at how we use setViewPort() to position and resize the default view later.</p></div><h2><a
<p> name="set_up_three_additional_views">Set up Three Additional Views</a></h2><div
Place the main camera in the scene and rotate it in its start position. class="level2"><p> Here is the outline for how you create the three other cams and viewPorts (<a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java">Full code sample is here</a>.) In the code snippet, <code>cam_n</code> stand for <code>cam_2</code> - <code>cam_4</code>, respectively, same for <code>view_n</code>.</p><ol><li
class="level1"><div
<p> class="li"> Clone the first cam to reuse its settings</div></li><li
We will have a detailed look at how we use setViewPort() to position and resize the default view later. class="level1"><div
</p> class="li"> Resize and position the cam&#039;s viewPort with setViewPort() – details below.</div></li><li
class="level1"><div
</div> class="li"> Place the cameras in the scene and rotate them.</div></li><li
class="level1"><div
<h2><a>Set up Three Additional Views</a></h2> class="li"> Create a main view for each camera</div></li><li
<div> class="level1"><div
class="li"> Reset the cameras&#039; enabled statuses</div></li><li
<p> class="level1"><div
class="li"> Attach the rootNode to be displayed to this view</div><ol><li
Here is the outline for how you create the three other cams and viewPorts (<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java"><param name="text" value="<html><u>Full code sample is here</u></html>"><param name="textColor" value="blue"></object>.) In the code snippet, <code>cam_n</code> stand for <code>cam_2</code> - <code>cam_4</code>, respectively, same for <code>view_n</code>. class="level2"><div
class="li"> It doesn&#039;t have to be rootNode, but that is the most common use case</div></li></ol></li><li
</p> class="level1"><div
<ol> class="li"> You can set other optional view properties such as backgroundColor</div></li></ol><pre>Camera cam_n = cam.clone&#40;&#41;;
<li><div> Clone the first cam to reuse its settings</div>
</li>
<li><div> Resize and position the cam&#039;s viewPort with setViewPort() – details below.</div>
</li>
<li><div> Place the cameras in the scene and rotate them.</div>
</li>
<li><div> Create a main view for each camera</div>
</li>
<li><div> Reset the cameras&#039; enabled statuses</div>
</li>
<li><div> Attach the rootNode to be displayed to this view</div>
<ol>
<li><div> It doesn&#039;t have to be rootNode, but that is the most common use case</div>
</li>
</ol>
</li>
<li><div> You can set other optional view properties such as backgroundColor</div>
</li>
</ol>
<pre>Camera cam_n = cam.clone&#40;&#41;;
cam_n.setViewPort&#40;...&#41;; // resize the viewPort cam_n.setViewPort&#40;...&#41;; // resize the viewPort
cam_n.setLocation&#40;new Vector3f&#40;...&#41;&#41;; cam_n.setLocation&#40;new Vector3f&#40;...&#41;&#41;;
cam_n.setRotation&#40;new Quaternion&#40;...&#41;&#41;; cam_n.setRotation&#40;new Quaternion&#40;...&#41;&#41;;
@ -70,36 +33,16 @@ cam_n.setRotation&#40;new Quaternion&#40;...&#41;&#41;;
ViewPort view_n = renderManager.createMainView&#40;&quot;View of camera #n&quot;, cam_n&#41;; ViewPort view_n = renderManager.createMainView&#40;&quot;View of camera #n&quot;, cam_n&#41;;
view_n.setClearEnabled&#40;true&#41;; view_n.setClearEnabled&#40;true&#41;;
view_n.attachScene&#40;rootNode&#41;; view_n.attachScene&#40;rootNode&#41;;
view_n.setBackgroundColor&#40;ColorRGBA.Black&#41;;</pre> view_n.setBackgroundColor&#40;ColorRGBA.Black&#41;;</pre></div><h2><a
</div> name="how_to_resize_and_position_the_viewports">How to resize and position the ViewPorts</a></h2><div
class="level2"><p> How does jme know which of the four views should appear where on the screen?</p><p> Imagine the view as a 1x1-sized box. By default, the settings is <code>cam.setViewPort(0f, 1f, 0f, 1f);</code>. This means the view takes up the whole box, from 0 to 1 left to right, and from 0 to 1 bottom to top.</p><p> In the <a
<h2><a>How to resize and position the ViewPorts</a></h2> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java">code sample</a>, note the following four lines:</p><pre>cam.setViewPort&#40; 0.5f, 1.0f, 0.0f, 0.5f&#41;;
<div>
<p>
How does jme know which of the four views should appear where on the screen?
</p>
<p>
Imagine the view as a 1&times;1-sized box. By default, the settings is <code>cam.setViewPort(0f, 1f, 0f, 1f);</code>. This means the view takes up the whole box, from 0 to 1 left to right, and from 0 to 1 bottom to top.
</p>
<p>
In the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/renderer/TestMultiViews.java"><param name="text" value="<html><u>code sample</u></html>"><param name="textColor" value="blue"></object>, note the following four lines:
</p>
<pre>cam.setViewPort&#40; 0.5f, 1.0f, 0.0f, 0.5f&#41;;
... ...
cam_2.setViewPort&#40;0.0f, 0.5f, 0.0f, 0.5f&#41;; cam_2.setViewPort&#40;0.0f, 0.5f, 0.0f, 0.5f&#41;;
... ...
cam_3.setViewPort&#40;0.0f, 0.5f, 0.5f, 1.0f&#41;; cam_3.setViewPort&#40;0.0f, 0.5f, 0.5f, 1.0f&#41;;
... ...
cam_4.setViewPort&#40;0.5f, 1.0f, 0.5f, 1.0f&#41;;</pre> cam_4.setViewPort&#40;0.5f, 1.0f, 0.5f, 1.0f&#41;;</pre><p> These viewport parameters are, in this order, the left - right - bottom - top extend of a camera&#039;s box on the screen. Note that we have set a few values to 0.5f – this is where we resize each view to half its default height and width.</p><pre>0.0 , 1.0 1.0 , 1.0
<p>
These viewport parameters are, in this order, the left - right - bottom - top extend of a camera&#039;s box on the screen. Note that we have set a few values to 0.5f – this is where we resize each view to half its default height and width.
</p>
<pre>
0.0 , 1.0 1.0 , 1.0
+----+----+ +----+----+
| | | | | |
|cam3|cam4| |cam3|cam4|
@ -107,35 +50,14 @@ These viewport parameters are, in this order, the left - right - bottom - top ex
| | | | | |
|cam2|cam | |cam2|cam |
+----+----+ +----+----+
0.0 , 0.0 1.0 , 0.0</pre> 0.0 , 0.0 1.0 , 0.0</pre><p> Example: Cam3&#039;s rect extends from bottom-left (0.0 , 0.5) to top-right (0.5 , 1.0)</p><ul><li
class="level1"><div
<p> class="li"> The left corner is at 0, and the right corner is 0.5 on the x axis.</div></li><li
Example: Cam3&#039;s rect extends from bottom-left (0.0 , 0.5) to top-right (0.5 , 1.0) class="level1"><div
</p> class="li"> The bottom of the box is at 0.5 and the top at 1.0 on the y axis.</div></li></ul></div><h2><a
<ul> name="other_layouts">Other Layouts</a></h2><div
<li><div> The left corner is at 0, and the right corner is 0.5 on the x axis. </div> class="level2"><p> This layout shows 2x2 views. For a split screen you may want to lay out two views, one above the other, or one next to the other.</p><p> If you scale the views in a way so that the aspect ratio changes, the views will obviously be distorted. In these cases, create custom camera objects with the right aspect ratio (redefine the default cam).</p><div
</li> class="tags"><span> <a
<li><div> The bottom of the box is at 0.5 and the top at 1.0 on the y axis.</div> href="/wiki/doku.php/tag:camera?do=showtag&amp;tag=tag%3Acamera">camera</a>, <a
</li> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
</ul>
</div>
<h2><a>Other Layouts</a></h2>
<div>
<p>
This layout shows 2&times;2 views. For a split screen you may want to lay out two views, one above the other, or one next to the other.
</p>
<p>
If you scale the views in a way so that the aspect ratio changes, the views will obviously be distorted. In these cases, create custom camera objects with the right aspect ratio (redefine the default cam).
</p>
<div><span>
<a href="/wiki/doku.php/tag:camera?do=showtag&amp;tag=tag%3Acamera">camera</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:multiple_camera_views?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:multiple_camera_views?do=export_xhtmlbody">view online version</a></em></p>

@ -1,105 +1,31 @@
<h1><a
<h1><a>Multithreading Optimization</a></h1> name="multithreading_optimization">Multithreading Optimization</a></h1><div
<div> class="level1"><p> First, make sure you know what <a
href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> are.</p><p> More complex games may feature complex mathematical operations or artificially intelligent calculations (such as path finding for several NPCs). If you make many time-intensive calls on the same thread (in the update loop), they will block one another, and thus slow down the game to a degree that makes it unplayable. If your game requires long running tasks, you should run them concurrently on separate threads, which speeds up the application considerably.</p><p> Often multithreading means having separate detached logical loops going on in parallel, which communicate about their state. (For example, one thread for AI, one Sound, one Graphics). However we recommend to use a global update loop for game logic, and do multithreading within that loop when it is appropriate. This approach scales way better to multiple cores and does not break up your code logic.</p><p> Effectively, each for-loop in the main update loop might be a chance for multithreading, if you can break it up into self-contained tasks.</p></div><h2><a
name="java_multithreading">Java Multithreading</a></h2><div
First, make sure you know what <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> are. class="level2"><p> The java.util.concurrent package provides a good foundation for multithreading and dividing work into tasks that can be executed concurrently (hence the name). The three basic components are the Executor, Callable Objects (the tasks), and Future Objects. You can <a
</p> href="http://download.oracle.com/javase/tutorial/essential/concurrency/">read about the concurrent package more here</a>, I will give just a short introduction.</p><ul><li
class="level1"><div
<p> class="li"> A Callable is a class with a method call() that gets executed on a thread in the Executor. It represents one task (e.g, path finding).</div></li><li
More complex games may feature complex mathematical operations or artificially intelligent calculations (such as path finding for several NPCs). If you make many time-intensive calls on the same thread (in the update loop), they will block one another, and thus slow down the game to a degree that makes it unplayable. If your game requires long running tasks, you should run them concurrently on separate threads, which speeds up the application considerably. class="level1"><div
</p> class="li"> The Executor is one central object that manages the threads that are running to execute the Callables. Every time a Callable is added to the Executor, the Executor returns a Future object for it.</div></li><li
class="level1"><div
<p> class="li"> A Future is an object that you use to check the status of an individual Callable&#039;s execution. It also gives you the return value in case one is created.</div></li></ul></div><h2><a
Often multithreading means having separate detached logical loops going on in parallel, which communicate about their state. (For example, one thread for AI, one Sound, one Graphics). However we recommend to use a global update loop for game logic, and do multithreading within that loop when it is appropriate. This approach scales way better to multiple cores and does not break up your code logic. name="multithreading_in_jme3">Multithreading in jME3</a></h2><div
</p> class="level2"><p> So how do we implement multithreading in jME3?</p><p> Let&#039;s take the example of a Control that controls an NPC Spatial. The NPC Control has to compute a lengthy pathfinding operation for each NPC. If we would execute the operations directly in the simpleUpdate() loop, it would block the game each time a NPC wants to move from A to B. Even if we move this behaviour into the update() method of a dedicated NPC Control, we would still get annoying freeze frames, because it still runs on the same update loop thread.</p><p> To avoid slowdown, we decide to keep the pathfinding operations in the NPC Control, <em>but execute it on another thread</em>.</p></div><h3><a
name="executor">Executor</a></h3><div
<p> class="level3"><p> You create the executor object in a global AppState (or the initSimpleApp() method), in any case in a high-level place where multiple controls can access it.</p><pre>/* This constructor creates a new executor with a core pool size of 4. */
Effectively, each for-loop in the main update loop might be a chance for multithreading, if you can break it up into self-contained tasks. ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor&#40;4&#41;;</pre><p> Pool size means the executor will keep four threads alive at any time. Having more threads in the pool means that more tasks can run concurrently. But a bigger pool only results in a speed gain if the PC can handle it! Allocating a pool that is uselessly large just wastes memory, so you need to find a good compromise: About the same to double the size of the number of cores in the computer makes sense.</p></div><h3><a
</p> name="control_class_fields">Control Class Fields</a></h3><div
class="level3"><p> In the NPC Control, we create the individual objects that the thread manipulates. In our example case (the pathfinding control), the task is about locations and path arrays, so we need the following variables:</p><pre>//The vector to store the desired location in:
</div>
<h2><a>Java Multithreading</a></h2>
<div>
<p>
The java.util.concurrent package provides a good foundation for multithreading and dividing work into tasks that can be executed concurrently (hence the name). The three basic components are the Executor, Callable Objects (the tasks), and Future Objects. You can <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://download.oracle.com/javase/tutorial/essential/concurrency/"><param name="text" value="<html><u>read about the concurrent package more here</u></html>"><param name="textColor" value="blue"></object>, I will give just a short introduction.
</p>
<ul>
<li><div> A Callable is a class with a method call() that gets executed on a thread in the Executor. It represents one task (e.g, path finding).</div>
</li>
<li><div> The Executor is one central object that manages the threads that are running to execute the Callables. Every time a Callable is added to the Executor, the Executor returns a Future object for it. </div>
</li>
<li><div> A Future is an object that you use to check the status of an individual Callable&#039;s execution. It also gives you the return value in case one is created.</div>
</li>
</ul>
</div>
<h2><a>Multithreading in jME3</a></h2>
<div>
<p>
So how do we implement multithreading in jME3?
</p>
<p>
Let&#039;s take the example of a Control that controls an NPC Spatial. The NPC Control has to compute a lengthy pathfinding operation for each NPC. If we would execute the operations directly in the simpleUpdate() loop, it would block the game each time a NPC wants to move from A to B. Even if we move this behaviour into the update() method of a dedicated NPC Control, we would still get annoying freeze frames, because it still runs on the same update loop thread.
</p>
<p>
To avoid slowdown, we decide to keep the pathfinding operations in the NPC Control, <em>but execute it on another thread</em>.
</p>
</div>
<h3><a>Executor</a></h3>
<div>
<p>
You create the executor object in a global AppState (or the initSimpleApp() method), in any case in a high-level place where multiple controls can access it.
</p>
<pre>/* This constructor creates a new executor with a core pool size of 4. */
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor&#40;4&#41;;</pre>
<p>
Pool size means the executor will keep four threads alive at any time. Having more threads in the pool means that more tasks can run concurrently. But a bigger pool only results in a speed gain if the PC can handle it! Allocating a pool that is uselessly large just wastes memory, so you need to find a good compromise: About the same to double the size of the number of cores in the computer makes sense.
</p>
</div>
<h3><a>Control Class Fields</a></h3>
<div>
<p>
In the NPC Control, we create the individual objects that the thread manipulates. In our example case (the pathfinding control), the task is about locations and path arrays, so we need the following variables:
</p>
<pre>//The vector to store the desired location in:
Vector3f desiredLocation = new Vector3f&#40;&#41;; Vector3f desiredLocation = new Vector3f&#40;&#41;;
//The MyWayList object that contains the result waylist: //The MyWayList object that contains the result waylist:
MyWayList wayList = null; MyWayList wayList = null;
//The future that is used to check the execution status: //The future that is used to check the execution status:
Future future = null;</pre> Future future = null;</pre><p> Here we also created the Future variable to track the state of this task.</p></div><h3><a
<p> name="control_update_method">Control Update() Method</a></h3><div
Here we also created the Future variable to track the state of this task. class="level3"><p> Next let&#039;s look at the update() call of the Control where the time-intensive task starts. In our example, the task is the <code>findWay</code> Callable (which contains the pathfinding process). So instead of spelling out the pathfinding process in the Control&#039;s update() loop, we start the process via <code>future = executor.submit(findWay);</code>.</p><pre>public void update&#40;float tpf&#41; &#123;
</p>
</div>
<h3><a>Control Update() Method</a></h3>
<div>
<p>
Next let&#039;s look at the update() call of the Control where the time-intensive task starts. In our example, the task is the <code>findWay</code> Callable (which contains the pathfinding process). So instead of spelling out the pathfinding process in the Control&#039;s update() loop, we start the process via <code>future = executor.submit(findWay);</code>.
</p>
<pre>public void update&#40;float tpf&#41; &#123;
try&#123; try&#123;
//If we have no waylist and not started a callable yet, do so! //If we have no waylist and not started a callable yet, do so!
if&#40;wayList == null &amp;&amp; future == null&#41;&#123; if&#40;wayList == null &amp;&amp; future == null&#41;&#123;
@ -128,47 +54,13 @@ Next let&#039;s look at the update() call of the Control where the time-intensiv
if&#40;wayList != null&#41;&#123; if&#40;wayList != null&#41;&#123;
//.... Success! Let's process the wayList and move the NPC... //.... Success! Let's process the wayList and move the NPC...
&#125; &#125;
&#125;</pre> &#125;</pre><p> Note how this logic makes its decision based on the Future object.</p><p> Remember not to mess with the class fields after starting the thread, because they are being accessed and modified on the new thread. In more obvious terms: You cannot change the &quot;desired location&quot; of the NPC while the path finder is calculating a different path. You have to cancel the current Future first.</p></div><h3><a
<p> name="the_callable">The Callable</a></h3><div
Note how this logic makes its decision based on the Future object. class="level3"><p> The next code sample shows the Callable that is dedicated to performing the long-running task (here, wayfinding). This is the task that used to block the rest of the application, and is now executed on a thread of its own. You implement the task in the Callable always in an inner method named <code>call()</code>.</p><p> The task code in the Callable should be self-contained! It should not write or read any data of objects that are managed by the scene graph or OpenGL thread directly. Even reading locations of Spatials can be problematic! So ideally all data that is needed for the wayfinding process should be available to the new thread when it starts already, possibly in a cloned version so no concurrent access to the data happens.</p><p> In reality, you might need access to the game state. If you must read or write a current state from the scene graph, you must have a clone of the data in your thread. There are only two ways:</p><ul><li
</p> class="level1"><div
class="li"> Use the execution queue <code>application.enqueue()</code> to create a sub-thread that clones the info. Only disadvantage is, it may be slower. <br/> The example below gets the <code>Vector3f location</code> from the scene object <code>mySpatial</code> using this way.</div></li><li
<p> class="level1"><div
Remember not to mess with the class fields after starting the thread, because they are being accessed and modified on the new thread. In more obvious terms: You cannot change the “desired location” of the NPC while the path finder is calculating a different path. You have to cancel the current Future first. class="li"> Create a separate World class that allows safe access to its data via synchronized methods to access the scene graph. Alternatively it can also internally use <code>application.enqueue()</code>. <br/> The following example gets the object <code>Data data = myWorld.getData();</code> using this way.</div></li></ul><p> These two ways are thread-safe, they don&#039;t mess up the game logic, and keep the Callable code readable.</p><pre>// A self-contained time-intensive task:
</p>
</div>
<h3><a>The Callable</a></h3>
<div>
<p>
The next code sample shows the Callable that is dedicated to performing the long-running task (here, wayfinding). This is the task that used to block the rest of the application, and is now executed on a thread of its own. You implement the task in the Callable always in an inner method named <code>call()</code>.
</p>
<p>
The task code in the Callable should be self-contained! It should not write or read any data of objects that are managed by the scene graph or OpenGL thread directly. Even reading locations of Spatials can be problematic! So ideally all data that is needed for the wayfinding process should be available to the new thread when it starts already, possibly in a cloned version so no concurrent access to the data happens.
</p>
<p>
In reality, you might need access to the game state. If you must read or write a current state from the scene graph, you must have a clone of the data in your thread. There are only two ways:
</p>
<ul>
<li><div> Use the execution queue <code>application.enqueue()</code> to create a sub-thread that clones the info. Only disadvantage is, it may be slower. <br/>
The example below gets the <code>Vector3f location</code> from the scene object <code>mySpatial</code> using this way.</div>
</li>
<li><div> Create a separate World class that allows safe access to its data via synchronized methods to access the scene graph. Alternatively it can also internally use <code>application.enqueue()</code>. <br/>
The following example gets the object <code>Data data = myWorld.getData();</code> using this way.</div>
</li>
</ul>
<p>
These two ways are thread-safe, they don&#039;t mess up the game logic, and keep the Callable code readable.
</p>
<pre>// A self-contained time-intensive task:
private Callable&lt;MyWayList&gt; findWay = new Callable&lt;MyWayList&gt;&#40;&#41;&#123; private Callable&lt;MyWayList&gt; findWay = new Callable&lt;MyWayList&gt;&#40;&#41;&#123;
public MyWayList call&#40;&#41; throws Exception &#123; public MyWayList call&#40;&#41; throws Exception &#123;
&nbsp; &nbsp;
@ -187,25 +79,14 @@ private Callable&lt;MyWayList&gt; findWay = new Callable&lt;MyWayList&gt;&#40;&#
&nbsp; &nbsp;
return wayList; return wayList;
&#125; &#125;
&#125;;</pre> &#125;;</pre></div><h2><a
</div> name="conclusion">Conclusion</a></h2><div
class="level2"><p> The cool thing about this appraoch is that every entity creates one self-contained Callable for the Executor, and they are all executed in parallel. In theory, you can have one thread per entity without changing anything else but the settings of the executor.</p><div
<h2><a>Conclusion</a></h2> class="tags"><span> <a
<div> href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>, <a
href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>, <a
<p> href="/wiki/doku.php/tag:performance?do=showtag&amp;tag=tag%3Aperformance">performance</a>, <a
href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>, <a
The cool thing about this appraoch is that every entity creates one self-contained Callable for the Executor, and they are all executed in parallel. In theory, you can have one thread per entity without changing anything else but the settings of the executor. href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>, <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
</p>
<div><span>
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>,
<a href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>,
<a href="/wiki/doku.php/tag:performance?do=showtag&amp;tag=tag%3Aperformance">performance</a>,
<a href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>,
<a href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading?do=export_xhtmlbody">view online version</a></em></p>

@ -1,145 +1,64 @@
<h1><a
<h1><a>Multiplayer Networking</a></h1> name="multiplayer_networking">Multiplayer Networking</a></h1><div
<div> class="level1"><p> This provides an overview of the new SpiderMonkey <acronym
title="Application Programming Interface">API</acronym> and a path for migrating from the old, now deprecated, <acronym
<p> title="Application Programming Interface">API</acronym> to the newer version. Much has changed.</p><p> The <a
href="/com/jme3/gde/core/docs/spidermonkey.html">original SpiderMonkey</a> implementation was a good concept and a clever implementation but suffered under the weight of rapid patches and some creeping design deficit. In the end, there were enough small problems, long-term maintenance issues, and limitations that a newer design was warranted.</p><p> Some things will be very similar but others have changed very much. Hopefully for the better.</p></div><h2><a
This provides an overview of the new SpiderMonkey <acronym title="Application Programming Interface">API</acronym> and a path for migrating from the old, now deprecated, <acronym title="Application Programming Interface">API</acronym> to the newer version. Much has changed. name="overview">Overview</a></h2><div
</p> class="level2"><p> Most of the new SpiderMonkey <acronym
title="Application Programming Interface">API</acronym> now exists as a set of interfaces and helper classes in the &#039;com.jme3.network&#039; package. For most users, this package and the &#039;message&#039; package will be all they need to worry about. The &#039;base&#039; and &#039;kernel&#039; packages only come into play when implementing custom network transports or alternate client/server protocols (<em>which are now possible</em>).</p><p> Clients and Servers can be created from the factory methods on the Network helper class. Once a Server instance is created and started, it can accept remote connections from Clients. The Client objects represent the client-side of a client→server connection. Within the Server, these are HostedConnections. This is a distinct change from the old <acronym
<p> title="Application Programming Interface">API</acronym>.</p><div
The <a href="/com/jme3/gde/core/docs/spidermonkey.html">original SpiderMonkey</a> implementation was a good concept and a clever implementation but suffered under the weight of rapid patches and some creeping design deficit. In the end, there were enough small problems, long-term maintenance issues, and limitations that a newer design was warranted. class="table sectionedit1"><table
</p> class="inline"><tr
class="row0"><th
<p> class="col0 leftalign"> Client</th><th
Some things will be very similar but others have changed very much. Hopefully for the better. class="col1 leftalign"></th><th
</p> class="col2 leftalign"> Server</th></tr><tr
class="row1"><td
</div> class="col0"> com.jme3.network.Client</td><td
class="col1"> ←→</td><td
<h2><a>Overview</a></h2> class="col2"> com.jme3.network.HostedConnection</td></tr></table></div><p> HostedConnections can hold application defined client-specific session attributes that the server-side listeners and services can use to track player information, etc..</p><p> MessageListeners can be registered with either the Client or the Server to be notified when new messages arrive. As before, these listeners can be registered to be notified about only specific
<div> types of messages.</p><p> ClientStateListeners can be registered with a Client to detect changes in connection state.</p><p> ConnectionListeners can be registered with a Server to be notified about HostedConnection arrivals and removals.</p></div><h2><a
name="what_s_gone">What&#039;s Gone?</a></h2><div
<p> class="level2"><p> All of &#039;connection&#039;, &#039;events&#039;, &#039;queue&#039;, &#039;service&#039;, &#039;streaming&#039;, and &#039;sync&#039; are now deprecated. The &#039;service&#039;, &#039;streaming&#039;, and &#039;sync&#039; packages were too difficult to easily port to the new <acronym
title="Application Programming Interface">API</acronym> and would have required additional code review for thread-related issues. Since the service manager model has _not_ been ported and will likely live on in a different way, it was better to let these go until better solutions evolve. For example, streaming is probably better done more tightly integrated with the core <acronym
Most of the new SpiderMonkey <acronym title="Application Programming Interface">API</acronym> now exists as a set of interfaces and helper classes in the &#039;com.jme3.network&#039; package. For most users, this package and the &#039;message&#039; package will be all they need to worry about. The &#039;base&#039; and &#039;kernel&#039; packages only come into play when implementing custom network transports or alternate client/server protocols (<em>which are now possible</em>). title="Application Programming Interface">API</acronym> and as actual java.io streams.</p></div><h2><a
</p> name="migration">Migration</a></h2><div
class="level2"></div><h3><a
<p> name="package_class_imports">Package/Class Imports</a></h3><div
Clients and Servers can be created from the factory methods on the Network helper class. Once a Server instance is created and started, it can accept remote connections from Clients. The Client objects represent the client-side of a client→server connection. Within the Server, these are HostedConnections. This is a distinct change from the old <acronym title="Application Programming Interface">API</acronym>. class="level3"><p> As a first pass, use the following table for conversion and then see specific class notes.</p><div
class="table sectionedit2"><table
</p> class="inline"><tr
<table> class="row0"><th
<tr> class="col0"> Old Class</th><th
<th> Client </th><th> </th><th> Server </th> class="col1"> New Class</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">com.jme3.network.connection.Client</td><td
<td> com.jme3.network.Client </td><td> ←→ </td><td> com.jme3.network.HostedConnection </td> class="col1"> com.jme3.network.Client or com.jme3.network.HostedConnection</td></tr><tr
</tr> class="row2"><td
</table> class="col0">com.jme3.network.connection.Server</td><td
class="col1"> com.jme3.network.Server</td></tr><tr
<p> class="row3"><td
HostedConnections can hold application defined client-specific session attributes that the server-side listeners and services can use to track player information, etc.. class="col0">com.jme3.network.event.MessageListener</td><td
</p> class="col1"> com.jme3.network.MessageListener</td></tr><tr
class="row4"><td
<p> class="col0">com.jme3.network.event.ConnectionListener</td><td
MessageListeners can be registered with either the Client or the Server to be notified when new messages arrive. As before, these listeners can be registered to be notified about only specific class="col1"> com.jme3.network.ClientStateListener or com.jme3.network.ConnectionListener</td></tr><tr
types of messages. class="row5"><td
</p> class="col0">com.jme3.network.event.MessageAdapter</td><td
class="col1"> no equivalent class, implement MessageListener directly</td></tr><tr
<p> class="row6"><td
ClientStateListeners can be registered with a Client to detect changes in connection state. class="col0">com.jme3.network.event.ConnectionAdapter</td><td
</p> class="col1"> no equivalent class, implement ClientStateListener or ConnectionListener directly</td></tr><tr
class="row7"><td
<p> class="col0">com.jme3.network.message.Message</td><td
ConnectionListeners can be registered with a Server to be notified about HostedConnection arrivals and removals. class="col1"> if used as a reference and not a superclass, com.jme3.network.Message. The base class stays the same for message subclasses.</td></tr></table></div><p> Doing all of those changes will certainly break your build… so now let&#039;s fix it.</p></div><h3><a
name="client_and_messagelistener">Client and MessageListener</a></h3><div
</p> class="level3"><p> This class is the hardest migration to perform. Do not get discouraged.</p><p> The old version used com.jme3.network.connection.Client for both client side and server side. So, depending on context, these references will either change to com.jme3.network.Client or com.jme3.network.HostedConnection. In the case where calling code is not client or server specific, then there is also the common com.jme3.network.MessageConnection interface.</p><p> In general, the actual client changes are of one of the following to types:</p><pre> Client client = new Client&#40; host, port &#41;;
</div>
<h2><a>What&#039;s Gone?</a></h2>
<div>
<p>
All of &#039;connection&#039;, &#039;events&#039;, &#039;queue&#039;, &#039;service&#039;, &#039;streaming&#039;, and &#039;sync&#039; are now deprecated. The &#039;service&#039;, &#039;streaming&#039;, and &#039;sync&#039; packages were too difficult to easily port to the new <acronym title="Application Programming Interface">API</acronym> and would have required additional code review for thread-related issues. Since the service manager model has _not_ been ported and will likely live on in a different way, it was better to let these go until better solutions evolve. For example, streaming is probably better done more tightly integrated with the core <acronym title="Application Programming Interface">API</acronym> and as actual java.io streams.
</p>
</div>
<h2><a>Migration</a></h2>
<div>
</div>
<h3><a>Package/Class Imports</a></h3>
<div>
<p>
As a first pass, use the following table for conversion and then see specific class notes.
</p>
<table>
<tr>
<th> Old Class </th><th> New Class </th>
</tr>
<tr>
<td>com.jme3.network.connection.Client </td><td> com.jme3.network.Client or com.jme3.network.HostedConnection </td>
</tr>
<tr>
<td>com.jme3.network.connection.Server </td><td> com.jme3.network.Server </td>
</tr>
<tr>
<td>com.jme3.network.event.MessageListener </td><td> com.jme3.network.MessageListener </td>
</tr>
<tr>
<td>com.jme3.network.event.ConnectionListener </td><td> com.jme3.network.ClientStateListener or com.jme3.network.ConnectionListener </td>
</tr>
<tr>
<td>com.jme3.network.event.MessageAdapter </td><td> no equivalent class, implement MessageListener directly </td>
</tr>
<tr>
<td>com.jme3.network.event.ConnectionAdapter </td><td> no equivalent class, implement ClientStateListener or ConnectionListener directly </td>
</tr>
<tr>
<td>com.jme3.network.message.Message </td><td> if used as a reference and not a superclass, com.jme3.network.Message. The base class stays the same for message subclasses. </td>
</tr>
</table>
<p>
Doing all of those changes will certainly break your build… so now let&#039;s fix it.
</p>
</div>
<h3><a>Client and MessageListener</a></h3>
<div>
<p>
This class is the hardest migration to perform. Do not get discouraged.
</p>
<p>
The old version used com.jme3.network.connection.Client for both client side and server side. So, depending on context, these references will either change to com.jme3.network.Client or com.jme3.network.HostedConnection. In the case where calling code is not client or server specific, then there is also the common com.jme3.network.MessageConnection interface.
</p>
<p>
In general, the actual client changes are of one of the following to types:
</p>
<pre> Client client = new Client&#40; host, port &#41;;
&nbsp; &nbsp;
...becomes... ...becomes...
&nbsp; &nbsp;
Client client = Network.connectToServer&#40; host, port &#41;;</pre> Client client = Network.connectToServer&#40; host, port &#41;; </pre><p> In the delayed connection case:</p><pre> Client client = new Client&#40;&#41;;
<p>
In the delayed connection case:
</p>
<pre> Client client = new Client&#40;&#41;;
... ...
client.connect&#40; host, port &#41;; client.connect&#40; host, port &#41;;
&nbsp; &nbsp;
@ -147,29 +66,9 @@ In the delayed connection case:
&nbsp; &nbsp;
NetworkClient client = Network.createClient&#40;&#41;; NetworkClient client = Network.createClient&#40;&#41;;
... ...
client.connectToServer&#40; host, port &#41;;</pre> client.connectToServer&#40; host, port &#41;;</pre><p> NetworkClient is a Client. The rest of your code can just refer to Client.</p><p> Those are the easy changes. The trickier ones are related to the MessageListeners.</p></div><h4><a
<p> name="messagelistener">MessageListener</a></h4><div
NetworkClient is a Client. The rest of your code can just refer to Client. class="level4"><p> By now you&#039;ve figured out that all of your MessageListeners are broken because the new method signature is different. The source of a message is no longer stored with the message and is instead provided to the MessageListener.</p><p> Depending on whether your MessageListener is being added to the Client or the Server, it will need to refer to either com.jme3.network.Client or com.jme3.network.HostedConnection in its messageReceived(), respectively. The MessageListener interface is generically typed to help make sure the right listener goes where it&#039;s supposed to and so the listener implementations don&#039;t have to cast all the time.</p><pre>// An example client-specific listener
</p>
<p>
Those are the easy changes. The trickier ones are related to the MessageListeners.
</p>
</div>
<h4><a>MessageListener</a></h4>
<div>
<p>
By now you&#039;ve figured out that all of your MessageListeners are broken because the new method signature is different. The source of a message is no longer stored with the message and is instead provided to the MessageListener.
</p>
<p>
Depending on whether your MessageListener is being added to the Client or the Server, it will need to refer to either com.jme3.network.Client or com.jme3.network.HostedConnection in its messageReceived(), respectively. The MessageListener interface is generically typed to help make sure the right listener goes where it&#039;s supposed to and so the listener implementations don&#039;t have to cast all the time.
</p>
<pre>// An example client-specific listener
public class MyClientListener implements MessageListener&lt;Client&gt; &#123; public class MyClientListener implements MessageListener&lt;Client&gt; &#123;
&nbsp; &nbsp;
public void messageReceived&#40; Client source, Message m &#41; &#123; public void messageReceived&#40; Client source, Message m &#41; &#123;
@ -191,149 +90,61 @@ public class MyGenericListener implements MessageListener&lt;MessageConnection&g
public void messageReceived&#40; MessageConnection source, Message m &#41; &#123; public void messageReceived&#40; MessageConnection source, Message m &#41; &#123;
... do limited stuff.... ... do limited stuff....
&#125; &#125;
&#125;</pre> &#125;</pre><p> Your listeners will fall into one of those three categories.</p><p><p><div
<p> class="noteclassic">Several of the old MessageListener&#039;s methods have gone away. The object-based methods didn&#039;t fit with the new <acronym
Your listeners will fall into one of those three categories. title="Application Programming Interface">API</acronym> and messageSent() seemed of little utility. It could be resurrected if there is demand.</div></p></p></div><h4><a
</p> name="client_method_changes">Client method changes</a></h4><div
class="level4"><p> Some of the methods on the old Client class have changed or been removed. Here is a basic summary:</p><div
<p> class="table sectionedit3"><table
<p><div>Several of the old MessageListener&#039;s methods have gone away. The object-based methods didn&#039;t fit with the new <acronym title="Application Programming Interface">API</acronym> and messageSent() seemed of little utility. It could be resurrected if there is demand. class="inline"><tr
</div></p> class="row0"><th
</p> class="col0"> Old Method</th><th
class="col1"> New Method</th></tr><tr
</div> class="row1"><td
class="col0"> Client.disconnect()</td><td
<h4><a>Client method changes</a></h4> class="col1"> Client.close() or HostedConnection.close(reason)</td></tr><tr
<div> class="row2"><td
class="col0"> Client.kick(reason)</td><td
<p> class="col1"> HostedConnection.close(reason)</td></tr><tr
class="row3"><td
Some of the methods on the old Client class have changed or been removed. Here is a basic summary: class="col0"> Client.getClientID()</td><td
class="col1"> Client.getId() or HostedConnection.getId()</td></tr><tr
</p> class="row4"><td
<table> class="col0"> Client.get/setPlayerID()</td><td
<tr> class="col1"> no equivalent</td></tr><tr
<th> Old Method </th><th> New Method </th> class="row5"><td
</tr> class="col0"> Client.get/setLabel()</td><td
<tr> class="col1"> no equivalent</td></tr></table></div></div><h4><a
<td> Client.disconnect() </td><td> Client.close() or HostedConnection.close(reason) </td> name="no_ioexceptions">No IOExceptions</a></h4><div
</tr> class="level4"><p> After you&#039;ve done all of that, the compiler will be complaining about the fact that send(), broadcast(), etc. no longer throw IOException. So remove all of those try/catch blocks.<p><div
<tr> class="noteclassic">The truth is that even in the old <acronym
<td> Client.kick(reason) </td><td> HostedConnection.close(reason) </td> title="Application Programming Interface">API</acronym>, expecting a real IOException from these methods was unreasonable because often times the message was queued and actually sent later by a separate thread. The new <acronym
</tr> title="Application Programming Interface">API</acronym> assumes that all underlying transports will operate this way and so forgoes the artificial annoyance or sense of security provided by these &#039;throws&#039; clauses. It also simplifies the calling code a great deal.</div></p></p><p> Only <acronym
<tr> title="Application Programming Interface">API</acronym> methods that actually perform direct IO (such as the Network.connectToServer() and NetworkClient.connectToServer() methods) will ever be declared to throw IOException.</p></div><h3><a
<td> Client.getClientID() </td><td> Client.getId() or HostedConnection.getId() </td> name="messagegetclient_and_messagegetconnection">Message.getClient() and Message.getConnection()</a></h3><div
</tr> class="level3"><p> This is important enough to deserve its own sub-heading because your code <strong>will</strong> break if you use these as they now return null. Any reason for calling them is now provided directly to the MessageListener in the form of the source Client or source HostedConnection.</p></div><h3><a
<tr> name="client_id_and_player_id">Client ID and Player ID</a></h3><div
<td> Client.get/setPlayerID() </td><td> no equivalent </td> class="level3"><p> The ID of the Client and HostedConnection are now the same at both ends of a connection and the ID is given out authoritatively by the hosting Server. This removes some of the inconsistency on when to use the old player ID and when to use the old client ID as the new client ID serves both purposes. This leaves the game to be able to define its own player ID based on whatever user criteria it wants.</p><p><p><div
</tr> class="noteclassic">Many of the reasons for accessing the client ID on the server can now be taken care of using the session attributes on HostedConnection. It seems like a common use-case for these IDs was to look-up player/client-specific information in a java.util.Map. This information can now be set directly on the HostedConnection.</div></p></p></div><h3><a
<tr> name="comjme3networkeventconnectionlistener">com.jme3.network.event.ConnectionListener</a></h3><div
<td> Client.get/setLabel() </td><td> no equivalent </td> class="level3"><p> Along with the shift from not using the same object at both ends of the client connection was a shift in the interfaces that are notified about those ends.</p><p> On the client, there is now com.jme3.network.ClientStateListener which is notified when the client fully connects to the server (including any internal handshaking) and when the client is disconnected.</p><p> On the server, com.jme3.network.ConnectionListener will be notified whenever new HostedConnections are added or removed. This listener isn&#039;t notified until the connection is fully setup (including any internal handshaking).</p><div
</tr> class="table sectionedit4"><table
</table> class="inline"><tr
class="row0"><th
</div> class="col0"> Old Method</th><th
class="col1"> New Method</th></tr><tr
<h4><a>No IOExceptions</a></h4> class="row1"><td
<div> class="col0"> clientConnected(Client)</td><td
class="col1"> connectionAdded(Server,HostedConnection)</td></tr><tr
<p> class="row2"><td
class="col0"> clientDisconnected(Client)</td><td
After you&#039;ve done all of that, the compiler will be complaining about the fact that send(), broadcast(), etc. no longer throw IOException. So remove all of those try/catch blocks. class="col1"> connectionRemoved(Server,HostedConnection)</td></tr></table></div></div><h2><a
<p><div>The truth is that even in the old <acronym title="Application Programming Interface">API</acronym>, expecting a real IOException from these methods was unreasonable because often times the message was queued and actually sent later by a separate thread. The new <acronym title="Application Programming Interface">API</acronym> assumes that all underlying transports will operate this way and so forgoes the artificial annoyance or sense of security provided by these &#039;throws&#039; clauses. It also simplifies the calling code a great deal. name="why_am_i_doing_this_again">Why am I doing this again?</a></h2><div
class="level2"><p> As you&#039;ve seen above, there are quite a few changes necessary to migrate to the new <acronym
</div></p> title="Application Programming Interface">API</acronym>. You might be asking yourself if it&#039;s worth the trouble.</p><p> The bottom line is that the old architecture had threading and stability issues that just couldn&#039;t be fixed in any reasonable way. Some were minor, others kind of severe… and they combined to make trouble. If you&#039;ve ever wondered why sometimes your clients connect and then the network connection hangs or stops sending data. Or if you&#039;ve ever wondered why UDP/unreliable messages get corrupted or somehow won&#039;t deserialize properly then you&#039;ve run into some of these issues.</p><p> Moreover, the lack of thread safety meant that user code sometimes had to do some strange and/or complicated work-arounds. The goal should be that the <acronym
</p> title="Application Programming Interface">API</acronym> should just work like it looks like it will with a minimum of hassle.</p><p> The new architecture is built from the ground up for threading stability and for a clean separation between the public <acronym
title="Application Programming Interface">API</acronym>, the message passing layer, and the underlying network transport implementations. You should be able to throw all kinds of stuff at it that would make the old system fall over and it should just hum along.</p><p> There will certainly be some growing pains as we work the kinks out of the new system but it is already much more stable in even the most basic of stress tests.</p><div
<p> class="tags"><span> <a
Only <acronym title="Application Programming Interface">API</acronym> methods that actually perform direct IO (such as the Network.connectToServer() and NetworkClient.connectToServer() methods) will ever be declared to throw IOException. href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
</p> href="/wiki/doku.php/tag:network?do=showtag&amp;tag=tag%3Anetwork">network</a> </span></div></div>
</div>
<h3><a>Message.getClient() and Message.getConnection()</a></h3>
<div>
<p>
This is important enough to deserve its own sub-heading because your code <strong>will</strong> break if you use these as they now return null. Any reason for calling them is now provided directly to the MessageListener in the form of the source Client or source HostedConnection.
</p>
</div>
<h3><a>Client ID and Player ID</a></h3>
<div>
<p>
The ID of the Client and HostedConnection are now the same at both ends of a connection and the ID is given out authoritatively by the hosting Server. This removes some of the inconsistency on when to use the old player ID and when to use the old client ID as the new client ID serves both purposes. This leaves the game to be able to define its own player ID based on whatever user criteria it wants.
</p>
<p>
<p><div>Many of the reasons for accessing the client ID on the server can now be taken care of using the session attributes on HostedConnection. It seems like a common use-case for these IDs was to look-up player/client-specific information in a java.util.Map. This information can now be set directly on the HostedConnection.
</div></p>
</p>
</div>
<h3><a>com.jme3.network.event.ConnectionListener</a></h3>
<div>
<p>
Along with the shift from not using the same object at both ends of the client connection was a shift in the interfaces that are notified about those ends.
</p>
<p>
On the client, there is now com.jme3.network.ClientStateListener which is notified when the client fully connects to the server (including any internal handshaking) and when the client is disconnected.
</p>
<p>
On the server, com.jme3.network.ConnectionListener will be notified whenever new HostedConnections are added or removed. This listener isn&#039;t notified until the connection is fully setup (including any internal handshaking).
</p>
<table>
<tr>
<th> Old Method </th><th> New Method </th>
</tr>
<tr>
<td> clientConnected(Client) </td><td> connectionAdded(Server,HostedConnection) </td>
</tr>
<tr>
<td> clientDisconnected(Client) </td><td> connectionRemoved(Server,HostedConnection) </td>
</tr>
</table>
</div>
<h2><a>Why am I doing this again?</a></h2>
<div>
<p>
As you&#039;ve seen above, there are quite a few changes necessary to migrate to the new <acronym title="Application Programming Interface">API</acronym>. You might be asking yourself if it&#039;s worth the trouble.
</p>
<p>
The bottom line is that the old architecture had threading and stability issues that just couldn&#039;t be fixed in any reasonable way. Some were minor, others kind of severe… and they combined to make trouble. If you&#039;ve ever wondered why sometimes your clients connect and then the network connection hangs or stops sending data. Or if you&#039;ve ever wondered why UDP/unreliable messages get corrupted or somehow won&#039;t deserialize properly then you&#039;ve run into some of these issues.
</p>
<p>
Moreover, the lack of thread safety meant that user code sometimes had to do some strange and/or complicated work-arounds. The goal should be that the <acronym title="Application Programming Interface">API</acronym> should just work like it looks like it will with a minimum of hassle.
</p>
<p>
The new architecture is built from the ground up for threading stability and for a clean separation between the public <acronym title="Application Programming Interface">API</acronym>, the message passing layer, and the underlying network transport implementations. You should be able to throw all kinds of stuff at it that would make the old system fall over and it should just hum along.
</p>
<p>
There will certainly be some growing pains as we work the kinks out of the new system but it is already much more stable in even the most basic of stress tests.
</p>
<div><span>
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:network?do=showtag&amp;tag=tag%3Anetwork">network</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:networking?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:networking?do=export_xhtmlbody">view online version</a></em></p>

@ -1,76 +1,50 @@
<h1><a
<h1><a>Creating User Interfaces with Nifty GUI</a></h1> name="creating_user_interfaces_with_nifty_gui">Creating User Interfaces with Nifty GUI</a></h1><div
<div> class="level1"><p> <a
href="/wiki/lib/exe/detail.php/jme3:advanced:nifty-gui.png?id=jme3%3Aadvanced%3Anifty_gui"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui.png?w=310&amp;h=250" class="medialeft" align="left" alt="" width="310" height="250" /></a></p><p> Although it is possible to embed a <a
href="/com/jme3/gde/core/docs/jme3/advanced/swing_canvas.html">jME3 canvas</a> in a Swing <acronym
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui.png"> title="Graphical User Interface">GUI</acronym> app, a 3D game typically runs full-screen, or in a window of its own. This soon raises the question of how to add a user interface: Most games respond to the escape key by displaying buttons that allow users to switch to different screens – for example to view high scores, customize settings, or load saved games.</p><p> This doc introduces you to <a
</p> href="http://nifty-gui.lessvoid.com/">Nifty GUI</a>, a Java library for graphical user interfaces (GUIs). Nifty <acronym
title="Graphical User Interface">GUI</acronym> (<code>de.lessvoid.nifty</code> package) is well integrated with jME3 via the <code>com.jme3.niftygui</code> package. You define the <acronym
<p> title="Graphical User Interface">GUI</acronym> layout in <acronym
Although it is possible to embed a <a href="/com/jme3/gde/core/docs/jme3/advanced/swing_canvas.html">jME3 canvas</a> in a Swing <acronym title="Graphical User Interface">GUI</acronym> app, a 3D game typically runs full-screen, or in a window of its own. This soon raises the question of how to add a user interface: Most games respond to the escape key by displaying buttons that allow users to switch to different screens – for example to view high scores, customize settings, or load saved games. title="Extensible Markup Language">XML</acronym> and call it from your Java code. All the JAR libraries that you need are already included in your jME3 download, so you do not need to install anything extra (Just make sure they are on the classpath).</p><p> <em>Typically, you lay out the Nifty <acronym
</p> title="Graphical User Interface">GUI</acronym> using <acronym
title="Extensible Markup Language">XML</acronym>, but using Java will soon be a second option.</em></p></div><h2><a
<p> name="overview">Overview</a></h2><div
This doc introduces you to <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://nifty-gui.lessvoid.com/"><param name="text" value="<html><u>Nifty GUI</u></html>"><param name="textColor" value="blue"></object>, a Java library for graphical user interfaces (GUIs). Nifty <acronym title="Graphical User Interface">GUI</acronym> (<code>de.lessvoid.nifty</code> package) is well integrated with jME3 via the <code>com.jme3.niftygui</code> package. You define the <acronym title="Graphical User Interface">GUI</acronym> layout in <acronym title="Extensible Markup Language">XML</acronym> and call it from your Java code. All the JAR libraries that you need are already included in your jME3 download, so you do not need to install anything extra (Just make sure they are on the classpath). class="level2"><p> <a
</p> href="/wiki/lib/exe/detail.php/jme3:advanced:nifty-gui-example.png?id=jme3%3Aadvanced%3Anifty_gui"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui-example.png?w=360&amp;h=203" class="mediaright" align="right" alt="" width="360" height="203" /></a></p><p> There are three steps needed to add a <acronym
<p> title="Graphical User Interface">GUI</acronym> to your jME3 game:</p><ol><li
<em>Typically, you lay out the Nifty <acronym title="Graphical User Interface">GUI</acronym> using <acronym title="Extensible Markup Language">XML</acronym>, but using Java will soon be a second option.</em> class="level1"><div
</p> class="li"> <a
href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Lay out the GUI in XML</a></div></li><li
</div> class="level1"><div
class="li"> Integrate the <acronym
<h2><a>Overview</a></h2> title="Graphical User Interface">GUI</acronym> into the Game</div><ul><li
<div> class="level2"><div
class="li"> <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Overlay the User Interface Over the Screen</a>, or</div></li><li
class="level2"><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui-example.png"> class="li"> <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Project the User Interface Onto a Texture</a></div></li></ul></li><li
class="level1"><div
<p> class="li"> <a
There are three steps needed to add a <acronym title="Graphical User Interface">GUI</acronym> to your jME3 game: href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol></div><h2><a
name="sample_code">Sample Code</a></h2><div
</p> class="level2"><ul><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Lay out the GUI in XML</a></div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java">TestNiftyGui.java</a></div></li><li
<li><div> Integrate the <acronym title="Graphical User Interface">GUI</acronym> into the Game</div> class="level1"><div
<ul> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Overlay the User Interface Over the Screen</a>, or</div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java">TestNiftyToMesh.java</a></div></li><li
</li> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Project the User Interface Onto a Texture</a></div> class="li"> You can find more sample code in the nifty-examples-1.3-SNAPSHOT.jar file.</div></li></ul></div><h2><a
</li> name="pro_tipuse_xml_schema">Pro Tip: Use XML Schema</a></h2><div
</ul> class="level2"><p> If you include the following <acronym
</li> title="Extensible Markup Language">XML</acronym> schema in the first lines of your NiftyGUI <acronym
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> title="Extensible Markup Language">XML</acronym> files, your IDE will give you helpful hints and code completion.</p><pre><span>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
</li>
</ol>
</div>
<h2><a>Sample Code</a></h2>
<div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java"><param name="text" value="<html><u>TestNiftyGui.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java"><param name="text" value="<html><u>TestNiftyToMesh.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> You can find more sample code in the nifty-examples-1.3-SNAPSHOT.jar file.</div>
</li>
</ul>
</div>
<h2><a>Pro Tip: Use XML Schema</a></h2>
<div>
<p>
If you include the following <acronym title="Extensible Markup Language">XML</acronym> schema in the first lines of your NiftyGUI <acronym title="Extensible Markup Language">XML</acronym> files, your IDE will give you helpful hints and code completion.
</p>
<pre><span>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span>&lt;nifty xmlns=&quot;http://nifty-gui.sourceforge.net/nifty.xsd&quot; </span> <span>&lt;nifty xmlns=&quot;http://nifty-gui.sourceforge.net/nifty.xsd&quot; </span>
<span> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </span> <span> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </span>
<span> xsi:schemaLocation=&quot;http://nifty-gui.sourceforge.net/nifty.xsd <span> xsi:schemaLocation=&quot;http://nifty-gui.sourceforge.net/nifty.xsd
@ -78,33 +52,26 @@ If you include the following <acronym title="Extensible Markup Language">XML</ac
&nbsp; &nbsp;
&lt;!-- Example: The IDE will now tell you that one &lt;screen&gt;&lt;/screen&gt; element is expected here, etc. --&gt; &lt;!-- Example: The IDE will now tell you that one &lt;screen&gt;&lt;/screen&gt; element is expected here, etc. --&gt;
&nbsp; &nbsp;
<span><span>&lt;/nifty&gt;</span></span></pre> <span><span>&lt;/nifty&gt;</span></span></pre></div><h2><a
</div> name="nifty_documentation">Nifty Documentation</a></h2><div
class="level2"><p> Learn more from the NiftyGUI page!</p><ul><li
<h2><a>Nifty Documentation</a></h2> class="level1"><div
<div> class="li"> <a
href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Tutorials">Go Through the Nifty Tutorials</a></div></li><li
<p> class="level1"><div
class="li"> <a
Learn more from the NiftyGUI page! href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Reference">Bookmark the Reference Guide</a></div></li><li
</p> class="level1"><div
<ul> class="li"> <a
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Tutorials"><param name="text" value="<html><u>Go Through the Nifty Tutorials</u></html>"><param name="textColor" value="blue"></object></div> href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Hello_World_Example">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Hello_World_Example</a></div></li><li
</li> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Reference"><param name="text" value="<html><u>Bookmark the Reference Guide</u></html>"><param name="textColor" value="blue"></object></div> class="li"> <a
</li> href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction</a></div></li><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Hello_World_Example"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Hello_World_Example</u></html>"><param name="textColor" value="blue"></object></div> class="level1"><div
</li> class="li"> <a
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction</u></html>"><param name="textColor" value="blue"></object></div> href="http://jmonkeyengine.org/groups/gui/forum/topic/anyone-succeeded-in-changing-text-in-nifty-programatically/#post-109510">Changing the Text in Nifty GUIs programmatically</a></div></li></ul><div
</li> class="tags"><span> <a
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/groups/gui/forum/topic/anyone-succeeded-in-changing-text-in-nifty-programatically/#post-109510"><param name="text" value="<html><u>Changing the Text in Nifty GUIs programmatically</u></html>"><param name="textColor" value="blue"></object></div> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
</li> href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, <a
</ul> href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a> </span></div></div>
<div><span>
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui?do=export_xhtmlbody">view online version</a></em></p>

@ -1,184 +1,136 @@
<h1><a
<h1><a>Interacting with the GUI from Java</a></h1> name="interacting_with_the_gui_from_java">Interacting with the GUI from Java</a></h1><div
<div> class="level1"><ol><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a></div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Java Interaction</strong></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div></li><li
</ol> class="level1"><div
class="li"> <strong>Nifty <acronym
<p> title="Graphical User Interface">GUI</acronym> Java Interaction</strong></div></li></ol><p> The main purpose of the <acronym
title="Graphical User Interface">GUI</acronym> is to send events back to your Java class that indicate what the users clicked, which settings they chose, which values they entered into a field, etc. In the Java class, you want to respond with an appropriate action, or store the entered settings in a file, etc.</p></div><h2><a
The main purpose of the <acronym title="Graphical User Interface">GUI</acronym> is to send events back to your Java class that indicate what the users clicked, which settings they chose, which values they entered into a field, etc. In the Java class, you want to respond with an appropriate action, or store the entered settings in a file, etc. name="connect_gui_to_java_controller">Connect GUI to Java Controller</a></h2><div
</p> class="level2"><p> How does the <acronym
title="Extensible Markup Language">XML</acronym> file send a message back to your Java application? You register a ScreenController (a Java class) to every NiftyGUI screen.
</div> Create a ScreenController by creating a Java class that implements the <code>de.lessvoid.nifty.screen.ScreenController</code> interface and its abtract methods.</p><pre>package my.game;
<h2><a>Connect GUI to Java Controller</a></h2>
<div>
<p>
How does the <acronym title="Extensible Markup Language">XML</acronym> file send a message back to your Java application? You register a ScreenController (a Java class) to every NiftyGUI screen.
</p>
<p>
Create a ScreenController by creating a Java class that implements the <code>de.lessvoid.nifty.screen.ScreenController</code> interface and its abtract methods.
</p>
<pre>package my.game;
import de.lessvoid.nifty.Nifty; import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen; import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController; import de.lessvoid.nifty.screen.ScreenController;
&nbsp;
public class MySettingsScreen implements ScreenController &#123; public class MySettingsScreen implements ScreenController &#123;
&nbsp; public MySettingsScreen&#40;MyGameData data &#41;&#123; /** constructor */ &#125;
public void bind&#40;Nifty nifty, Screen screen&#41; &#123; &#125; public void bind&#40;Nifty nifty, Screen screen&#41; &#123; &#125;
&nbsp;
public void onStartScreen&#40;&#41; &#123; &#125; public void onStartScreen&#40;&#41; &#123; &#125;
&nbsp;
public void onEndScreen&#40;&#41; &#123; &#125; public void onEndScreen&#40;&#41; &#123; &#125;
&#125;</pre> &#125;</pre><p> The name and package of your custom ScreenController class (here <code>my.game.MySettingsScreen</code>) goes into the controller parameter of the respective screen it belongs to:</p><pre><span><span>&lt;nifty&gt;</span></span>
<p>
The name and package of your custom ScreenController class (here <code>my.game.MySettingsScreen</code>) goes into the controller parameter of the respective screen it belongs to:
</p>
<pre><span><span>&lt;nifty&gt;</span></span>
<span>&lt;screen id=&quot;settings&quot; controller=&quot;my.game.MySettingsScreen&quot;&gt;</span> <span>&lt;screen id=&quot;settings&quot; controller=&quot;my.game.MySettingsScreen&quot;&gt;</span>
&lt;!-- layer and panel code ... --&gt; &lt;!-- layer and panel code ... --&gt;
<span><span>&lt;/screen&gt;</span></span> <span><span>&lt;/screen&gt;</span></span>
<span><span>&lt;/nifty&gt;</span></span></pre> <span><span>&lt;/nifty&gt;</span></span></pre><p> Now the Java class <code>my.game.MySettingsScreen</code> and this <acronym
<p> title="Graphical User Interface">GUI</acronym> screen (<code>settings</code>) are connected.</p></div><h2><a
Now the Java class <code>my.game.MySettingsScreen</code> and this <acronym title="Graphical User Interface">GUI</acronym> screen (<code>settings</code>) are connected. name="make_gui_and_java_interact">Make GUI and Java Interact</a></h2><div
</p> class="level2"><p> In most cases, you will want to pass game data in and out of the ScreenController. Note that you can pass any arguments into your ScreenController constructor. In the example above, the object with the necessary data is is <code>MyGameData data</code>.
You can use any of the three following approaches to make Java classes interact with the <acronym
</div> title="Graphical User Interface">GUI</acronym>, and you can also combine them, depending on what you want to do.</p></div><h3><a
name="gui_calls_a_void_java_method">GUI Calls a Void Java Method</a></h3><div
<h2><a>Make GUI and Java Interact</a></h2> class="level3"><p> To respond to an interaction, add the &lt;interact /&gt; element to a panel and specify the Java method you want to call. In this example, we want to call <code>sayHello()</code> when a panel on the screen is clicked.</p><pre>...
<div> <span>&lt;panel id=&quot;panel&quot; height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot;</span>
<p>
You can use any of the three following approaches to interact, and you can also combine them, depending on what you want to do.
</p>
</div>
<h3><a>GUI Calls a Void Java Method</a></h3>
<div>
<p>
To respond to an interaction, add the &lt;interact /&gt; element to a panel and specify the Java method you want to call. In this example, we want to call <code>sayHello()</code> when a panel on the screen is clicked.
</p>
<pre>...
<span>&lt;panel id=&quot;panel&quot; height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot; </span>
<span> backgroundColor=&quot;#f60f&quot; childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span> <span> backgroundColor=&quot;#f60f&quot; childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span>
<span>&lt;text id=&quot;text&quot; font=&quot;aurulent-sans-17.fnt&quot; color=&quot;#000f&quot; </span> <span>&lt;text id=&quot;text&quot; font=&quot;aurulent-sans-17.fnt&quot; color=&quot;#000f&quot;</span>
<span> text=&quot;Hello World!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span> <span> text=&quot;Hello World!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span>
<span>&lt;interact onClick=&quot;sayHello(hi)&quot;/&gt;</span> <span>&lt;interact onClick=&quot;sayHello(hi)&quot;/&gt;</span>
<span><span>&lt;/panel&gt;</span></span> <span><span>&lt;/panel&gt;</span></span>
...</pre> ...</pre><p> Back in this screen&#039;s Java class, we specify what the <code>sayHello()</code> method does. As you see, you can include String arguments in the call.</p><pre>public class MySettingsScreen implements ScreenController &#123;
<p>
Back in this screen&#039;s Java class, we specify what the <code>sayHello()</code> method does. As you see, you can include String arguments in the call.
</p>
<pre>public class MySettingsScreen implements ScreenController &#123;
... ...
public void sayHello&#40;String myarg&#41; &#123; public void sayHello&#40;String myarg&#41; &#123;
System.out.println&#40;&quot;Nifty says &quot;+myarg&#41;; System.out.println&#40;&quot;Nifty says &quot;+myarg&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="gui_gets_return_value_from_java_method">GUI Gets Return Value from Java Method</a></h3><div
class="level3"><p> You can send a message from Java to Nifty. In this example, the Java class <code>callThis()</code> in MySettingsScreen defines the Text that is displayed in the textfield after the words <code>Hello World, …!</code> First define a Java method in the screen controller, in this example, <code>callThis()</code>.</p><pre>public class MySettingsScreen implements ScreenController &#123;
<h3><a>GUI Gets Return Value from Java Method</a></h3>
<div>
<p>
You can send a message from Java to Nifty. In this example, the Java class <code>callThis()</code> in MySettingsScreen defines the Text that is displayed in the textfield after the words <code>Hello World, …!</code>
</p>
<p>
First define a Java method in the screen controller, in this example, <code>callThis()</code>.
</p>
<pre>public class MySettingsScreen implements ScreenController &#123;
... ...
public String callThis&#40;&#41; &#123; public String callThis&#40;&#41; &#123;
return &quot;my friend&quot;; return &quot;my friend&quot;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Nifty uses <code>${CALL.callThis()}</code> to get the return value of a method from your ScreenController Java class.</p><pre>...
<p> <span>&lt;panel id=&quot;panel&quot; height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot;</span>
Nifty uses <code>${CALL.callThis()}</code> to get the return value of a method from your ScreenController Java class.
</p>
<pre>...
<span>&lt;panel id=&quot;panel&quot; height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot; </span>
<span> backgroundColor=&quot;#f60f&quot; childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span> <span> backgroundColor=&quot;#f60f&quot; childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span>
<span>&lt;text id=&quot;text&quot; font=&quot;aurulent-sans-17.fnt&quot; color=&quot;#000f&quot; </span> <span>&lt;text id=&quot;text&quot; font=&quot;aurulent-sans-17.fnt&quot; color=&quot;#000f&quot;</span>
<span> text=&quot;Hello World, ${CALL.callThis()}!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span> <span> text=&quot;Hello World, ${CALL.callThis()}!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span>
<span>&lt;interact onClick=&quot;sayHello(hi)&quot;/&gt;</span> <span>&lt;interact onClick=&quot;sayHello(hi)&quot;/&gt;</span>
<span><span>&lt;/panel&gt;</span></span> <span><span>&lt;/panel&gt;</span></span>
...</pre> ...</pre><p> You can also use this for Strings and numeric values, e.g. when you read settings from a file, you read them like this.</p></div><h3><a
<p> name="java_modifies_nifty_elements_and_events">Java Modifies Nifty Elements and Events</a></h3><div
You can also use this for Strings and numeric values, e.g. when you read settings from a file, you read them like this. class="level3"><p> You can also alter the appearance and functions of your nifty elements from Java.
</p> Here&#039;s an example of how to change the image <code>myElement</code>:</p><pre>NiftyImage img = nifty.getRenderEngine&#40;&#41;.createImage&#40;&quot;Interface/Images/image.png&quot;, false&#41;;
</div>
<h3><a>Java Modifies Nifty Elements and Events</a></h3>
<div>
<p>
You can also alter the appearance and functions of your nifty elements from Java.
</p>
<p>
Here&#039;s an example of how to change the image <code>myElement</code>:
</p>
<pre>NiftyImage img = nifty.getRenderEngine&#40;&#41;.createImage&#40;&quot;Interface/Images/image.png&quot;, false&#41;;
Element niftyElement = nifty.getCurrentScreen&#40;&#41;.findElementByName&#40;&quot;myElement&quot;&#41;; Element niftyElement = nifty.getCurrentScreen&#40;&#41;.findElementByName&#40;&quot;myElement&quot;&#41;;
niftyElement.getRenderer&#40;ImageRenderer.class&#41;.setImage&#40;img&#41;;</pre> niftyElement.getRenderer&#40;ImageRenderer.class&#41;.setImage&#40;img&#41;;</pre><p> The same is valid for other elements, for example text fields:</p><pre>niftyElement.getRenderer&#40;TextRenderer.class&#41;.setText&#40;&quot;New text&quot;&#41;;</pre><p> Similarly, to change the onClick() event of an element, create an <code>ElementInteraction</code> object:</p><pre>Element niftyElement = nifty.getCurrentScreen&#40;&#41;.findElementByName&#40;&quot;myElement&quot;&#41;;
<p> niftyElement.getElementInteraction&#40;&#41;.getPrimary&#40;&#41;.setOnMouseOver&#40;new NiftyMethodInvoker&#40;nifty, &quot;myCustomMethod()&quot;, this&#41;&#41;;</pre><p> For this to work, there already needs to be an &lt; interact &gt; tag inside your xml element:</p><pre>&lt;interact onClick=&quot;doNothing()&quot;/&gt;</pre></div><h2><a
The same is valid for other elements, for example text fields: name="concepts_examples">Concepts &amp; Examples</a></h2><div
class="level2"><p> note: Nifty-gui 1.3 oriented.<br/></p></div><h3><a
</p> name="how_do_i_create_a_popup_menu_that_i_populate_in_java">How do I create a popup menu that I populate in Java?</a></h3><div
<pre>niftyElement.getRenderer&#40;TextRenderer.class&#41;.setText&#40;&quot;New text&quot;&#41;;</pre> class="level3"><p> Even though you create and populate the popup menu in Java you still need a &quot;placeholder&quot; in your <acronym
<p> title="Extensible Markup Language">XML</acronym> file, below is an example extract:</p><pre><span>&lt;useControls filename=&quot;nifty-default-controls.xml&quot;/&gt;</span>
Similarly, to change the onClick() event of an element, create an <code>ElementInteraction</code> object: ...
</p> <span>&lt;popup id=&quot;niftyPopupMenu&quot; childLayout=&quot;absolute-inside&quot;</span>
<pre>Element niftyElement = nifty.getCurrentScreen&#40;&#41;.findElementByName&#40;&quot;myElement&quot;&#41;; <span> controller=&quot;ControllerOfYourChoice&quot; width=&quot;10%&quot;&gt;</span>
niftyElement.setInteraction&#40;new ElementInteraction&#40;nifty&#41; &#123; <span>&lt;interact onClick=&quot;closePopup()&quot;</span>
&nbsp; <span> onSecondaryClick=&quot;closePopup()&quot; onTertiaryClick=&quot;closePopup()&quot; /&gt;</span>
@Override <span>&lt;control id=&quot;#menu&quot; name=&quot;niftyMenu&quot; /&gt;</span>
public void onClick&#40;&#41; &#123; <span><span>&lt;/popup&gt;</span></span>
// call java functions normally. ...</pre><p> A brief explanation of some the attributes above:</p><ul><li
niftyController.onElementClicked&#40;&#41;; class="level1"><div
super.onClick&#40;&#41;; class="li"> the popup id will be used within your Java code so that nifty knows which popup placeholder to create</div></li><li
class="level1"><div
class="li"> controller will tell nifty which Java class handles MenuItemActivatedEvent</div></li><li
class="level1"><div
class="li"> on(Secondary/Tertiary)Click tells nifty to close the popup if the user clicks anywhere except on the menu items (in this example)</div></li><li
class="level1"><div
class="li"> control id will be used by the Java class to define a control type (i.e. Menu)</div></li></ul><p> Java code within your defined ScreenController implementation:<br/></p><pre>private Element popup;
...
public void createMyPopupMenu&#40;&#41;&#123;
popup = nifty.createPopup&#40;&quot;niftyPopupMenu&quot;&#41;;
Menu.class&#41;;
myMenu.setWidth&#40;new SizeValue&#40;&quot;100px&quot;&#41;&#41;; //must be set
myMenu.addMenuItem&#40;&quot;Click me!&quot;, &quot;menuItemIcon.png&quot;, new menuItem&#40;&quot;menuItemid&quot;, &quot;blah blah&quot;&#41;&#41;; //menuItem is a custom class
nifty.subscribe&#40;nifty.getCurrentScreen&#40;&#41;, myMenu.getId&#40;&#41;, MenuItemActivatedEvent.class, new MenuItemActivatedEventSubscriber&#40;&#41;&#41;;
&#125;
public void showMenu&#40;&#41;&#123; //the method to trigger the menu
createMyPopupMenu&#40;&#41; //you should call this in your constructor rather than here if it is a menu that is going to be used many times
nifty.showPopup&#40;nifty.getCurrentScreen&#40;&#41;, popup.getId&#40;&#41;, null&#41;; //call the popup to screen of your choice
&#125;
private class menuItem&#123;
public String id;
public String name;
public menuItem&#40;String name&#41;&#123;
this.id= id;
this.name = name;
&#125; &#125;
&nbsp; &#125;</pre><ul><li
class="level1"><div
class="li"> createMyPopupMenu() creates the menu with set width so that you can populate it</div></li><li
class="level1"><div
class="li"> showMenu() is called by something to trigger the menu (i.e. could be a Key or some other method)</div></li></ul><p> To handle menu item events (i.e. calling a method when you click on a menu item) you subscribe a EventTopicSubscriber&lt;MenuItemActivatedEvent&gt; class implementation to a nifty screen and element.<br/></p><pre>private class MenuItemActivatedEventSubscriber implements EventTopicSubscriber&lt;MenuItemActivatedEvent&gt; &#123;
@Override @Override
public boolean onClick&#40;MouseInputEvent inputEvent&#41; &#123; public void onEvent&#40;final String id, final MenuItemActivatedEvent event&#41; &#123;
niftyController.onElementClicked&#40;&#41;; menuItem item = &#40;menuItem&#41; event.getItem&#40;&#41;;
return super.onClick&#40;inputEvent&#41;; if &#40;&quot;menuItemid&quot;.equals&#40;item.id&#41;&#41; &#123;
//do something !!!
&#125;
&#125; &#125;
&#125;&#41;;</pre> &#125;;</pre></div><h2><a
<p> name="useful_links">Useful Links</a></h2><div
For this to work, there already needs to be an &lt; interact &gt; tag inside your xml element: class="level2"><p> Nifty 1.3 controls Java Docs: <a
</p> href="http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty-default-controls/apidocs/">http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty-default-controls/apidocs/</a> <br/> <br/> Nifty 1.3 Java Docs: <a
<pre>&lt;interact onClick=&quot;doNothing()&quot;/&gt;</pre> href="http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty/apidocs/index.html">http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty/apidocs/index.html</a> <br/> <br/> Examples of standard controls in Nifty 1.3: <a
href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Nifty_Standard_Controls_%28Nifty_1.3%29">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Nifty_Standard_Controls_%28Nifty_1.3%29</a> <br/> <br/> Learn more: <a
<p> href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=MarkUp">Nifty Syntax</a></p><div
Learn more: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=MarkUp"><param name="text" value="<html><u>Nifty Syntax</u></html>"><param name="textColor" value="blue"></object> class="tags"><span> <a
href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, <a
</p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<div><span> href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>, <a
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a> </span></div></div>
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>,
<a href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_java_interaction?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_java_interaction?do=export_xhtmlbody">view online version</a></em></p>

@ -1,69 +1,54 @@
<h1><a
<h1><a>Integrating Nifty GUI: Overlay</a></h1> name="integrating_nifty_guioverlay">Integrating Nifty GUI: Overlay</a></h1><div
<div> class="level1"><ol><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a></div></li><li
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> class="level1"><div
</li> class="li"> <strong>Nifty <acronym
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div></li><li
</ol> class="level1"><div
class="li"> <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><p> Define a key (for example escape) that switches the <acronym
Define a key (for example escape) that switches the <acronym title="Graphical User Interface">GUI</acronym> on and off. title="Graphical User Interface">GUI</acronym> on and off.
You can either overlay the running game with the <acronym title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">project</a> it as a texture onto a mesh texture (but then you cannot click to select). You can either overlay the running game with the <acronym
</p> title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even <a
href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">project</a> it as a texture onto a mesh texture (but then you cannot click to select).
<p> On this page, we look at the overlay variant (more commonly used).</p><p> <a
On this page, we look at the overlay variant (more commonly used). href="/wiki/lib/exe/detail.php/jme3:advanced:nifty-gui-example.png?id=jme3%3Aadvanced%3Anifty_gui_overlay"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui-example.png?w=360&amp;h=203" class="mediacenter" alt="" width="360" height="203" /></a></p></div><h2><a
name="sample_code">Sample Code</a></h2><div
<p> class="level2"><ul><li
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui-example.png"> class="level1"><div
</p> class="li"> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java">TestNiftyGui.java</a></div></li></ul></div><h2><a
</div> name="overlaying_the_user_interface_over_the_screen">Overlaying the User Interface Over the Screen</a></h2><div
class="level2"><p> This code shows you how to overlay anything on the screen with the <acronym
<h2><a>Sample Code</a></h2> title="Graphical User Interface">GUI</acronym>. This is the most common usecase.</p><pre>NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay&#40;
<div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java"><param name="text" value="<html><u>TestNiftyGui.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<h2><a>Overlaying the User Interface Over the Screen</a></h2>
<div>
<p>
This code shows you how to overlay anything on the screen with the <acronym title="Graphical User Interface">GUI</acronym>. This is the most common usecase.
</p>
<pre>NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay&#40;
assetManager, inputManager, audioRenderer, guiViewPort&#41;; assetManager, inputManager, audioRenderer, guiViewPort&#41;;
/** Create a new NiftyGUI object */
Nifty nifty = niftyDisplay.getNifty&#40;&#41;; Nifty nifty = niftyDisplay.getNifty&#40;&#41;;
&nbsp; /** Read your XML and initialize your custom ScreenController */
// init Nifty start screen nifty.fromXml&#40;&quot;Interface/helloworld.xml&quot;, &quot;start&quot;, new MySettingsScreen&#40;data&#41;&#41;;
nifty.fromXml&#40;&quot;Interface/helloworld.xml&quot;, &quot;start&quot;&#41;;
&nbsp;
// attach the Nifty display to the gui view port as a processor // attach the Nifty display to the gui view port as a processor
guiViewPort.addProcessor&#40;niftyDisplay&#41;; guiViewPort.addProcessor&#40;niftyDisplay&#41;;
// disable the fly cam // disable the fly cam
flyCam.setDragToRotate&#40;true&#41;;</pre><hr /> flyCam.setDragToRotate&#40;true&#41;;</pre><p> The <code>MySettingsScreen</code> class is a custom de.lessvoid.nifty.screen.ScreenController in which you implement your <acronym
<ol> title="Graphical User Interface">GUI</acronym> behaviour. The variable <code>data</code> contains an object that you use to exchange state info with the game. See <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Nifty GUI Java Interaction</a> for details on how we created this class.</p><hr
</li> /><ol><li
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a></div></li><li
</li> class="level1"><div
</ol> class="li"> <strong>Nifty <acronym
<div><span> title="Graphical User Interface">GUI</acronym> Overlay</strong> or <a
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div></li><li
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a> class="level1"><div
</span></div> class="li"> <a
href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><div
</div> class="tags"><span> <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a> </span></div></div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_overlay?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_overlay?do=export_xhtmlbody">view online version</a></em></p>

@ -1,58 +1,39 @@
<h1><a
<h1><a>Integrating Nifty GUI: Projection</a></h1> name="integrating_nifty_guiprojection">Integrating Nifty GUI: Projection</a></h1><div
<div> class="level1"><ol><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a></div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Projection</strong></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym
</li> title="Graphical User Interface">GUI</acronym> Projection</strong></div></li><li
</ol> class="level1"><div
class="li"> <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><p> Define a key (for example escape) that switches the <acronym
Define a key (for example escape) that switches the <acronym title="Graphical User Interface">GUI</acronym> on and off. You can either <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">overlay</a> the running game with the <acronym title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even project it as a texture onto a mesh textures (but then you cannot click to select). title="Graphical User Interface">GUI</acronym> on and off. You can either <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">overlay</a> the running game with the <acronym
title="Graphical User Interface">GUI</acronym> (you will most likely pause the game then), or even project it as a texture onto a mesh textures (but then you cannot click to select).
<p> On this page, we look at the projection variant (less commonly used). <a
On this page, we look at the projection variant (less commonly used). href="/wiki/lib/exe/detail.php/jme3:advanced:nifty-gui.png?id=jme3%3Aadvanced%3Anifty_gui_projection"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui.png?w=310&amp;h=250" class="mediacenter" alt="" width="310" height="250" /></a></p></div><h2><a
name="sample_code">Sample Code</a></h2><div
<p> class="level2"><ul><li
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-gui.png"> class="level1"><div
</p> class="li"> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java">TestNiftyToMesh.java</a></div></li></ul></div><h2><a
</div> name="projecting_the_user_interface_onto_a_texture">Projecting the User Interface Onto a Texture</a></h2><div
class="level2"><p> You can project the Nifty <acronym
<h2><a>Sample Code</a></h2> title="Graphical User Interface">GUI</acronym> onto a texture, load the texture into a material, and assign it to a 3D mesh. Allthough this is possible the approach is rarely used since it is difficult to record clicks this way, you can only interact with this UI by keyboard or programmatically. (E.g. an action performed by a character standing in front of a &quot;computer&quot;)</p><pre>/** Create a new viewport for the GUI */
<div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyToMesh.java"><param name="text" value="<html><u>TestNiftyToMesh.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<h2><a>Projecting the User Interface Onto a Texture</a></h2>
<div>
<p>
You can project the Nifty <acronym title="Graphical User Interface">GUI</acronym> onto a texture, load the texture into a material, and assign it to a 3D mesh. Allthough this is possible the approach is rarely used since it is difficult to record clicks this way, you can only interact with this UI by keyboard or programmatically. (e.g. an action performed by a character standing in front of a “computer”)
</p>
<pre>/** Create a new viewport for the GUI */
ViewPort niftyView = renderManager.createPreView&#40;&quot;NiftyView&quot;, new Camera&#40;1024, 768&#41;&#41;; ViewPort niftyView = renderManager.createPreView&#40;&quot;NiftyView&quot;, new Camera&#40;1024, 768&#41;&#41;;
niftyView.setClearEnabled&#40;true&#41;; niftyView.setClearEnabled&#40;true&#41;;
&nbsp;
&nbsp;
/** Create a new NiftyJmeDisplay for the integration */ /** Create a new NiftyJmeDisplay for the integration */
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay&#40; NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay&#40;
assetManager, inputManager, audioRenderer, niftyView&#41;; assetManager, inputManager, audioRenderer, niftyView&#41;;
&nbsp; /** Create a new NiftyGUI object */
/** Create a new NiftyGUI object and read your XML */
Nifty nifty = niftyDisplay.getNifty&#40;&#41;; Nifty nifty = niftyDisplay.getNifty&#40;&#41;;
nifty.fromXml&#40;&quot;Interface/helloworld.xml&quot;, &quot;start&quot;&#41;; /** Read your XML and initialize your custom ScreenController */
&nbsp; nifty.fromXml&#40;&quot;Interface/helloworld.xml&quot;, &quot;start&quot;, new MySettingsScreen&#40;data&#41;&#41;;
/** We prepare a framebuffer for the texture niftytex */ /** We prepare a framebuffer for the texture niftytex */
niftyView.addProcessor&#40;niftyDisplay&#41;; niftyView.addProcessor&#40;niftyDisplay&#41;;
FrameBuffer fb = new FrameBuffer&#40;1024, 768, 0&#41;; FrameBuffer fb = new FrameBuffer&#40;1024, 768, 0&#41;;
@ -61,36 +42,32 @@ Texture2D niftytex = new Texture2D&#40;1024, 768, Format.RGB8&#41;;
fb.setColorTexture&#40;niftytex&#41;; fb.setColorTexture&#40;niftytex&#41;;
niftyView.setClearEnabled&#40;true&#41;; niftyView.setClearEnabled&#40;true&#41;;
niftyView.setOutputFrameBuffer&#40;fb&#41;; niftyView.setOutputFrameBuffer&#40;fb&#41;;
&nbsp;
/** This is the 3D cube we project the GUI on */ /** This is the 3D cube we project the GUI on */
Box&#40;Vector3f.ZERO, 1, 1, 1&#41;; Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;; Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/SimpleTextured.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.setTexture&#40;&quot;m_ColorMap&quot;, niftytex&#41;; /** Here comes the texture! */ mat.setTexture&#40;&quot;m_ColorMap&quot;, niftytex&#41;; /** Here comes the texture! */
geom.setMaterial&#40;mat&#41;; geom.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;geom&#41;;</pre> rootNode.attachChild&#40;geom&#41;;</pre><p> The MySettingsScreen class is a custom de.lessvoid.nifty.screen.ScreenController in which you implement your <acronym
<p> title="Graphical User Interface">GUI</acronym> behaviour. The variable <code>data</code> contains an object that you use to exchange state info with the game. See <a
You select buttons on this <acronym title="Graphical User Interface">GUI</acronym> with the arrow keys and then press return – Clicking them will not work. href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Nifty GUI Java Interaction</a> for details on how we created this class.
</p> Run the code sample. You select buttons on this <acronym
title="Graphical User Interface">GUI</acronym> with the arrow keys and then press return. Note that clicking on the texture will not work!
<p> Again, check the <a
Again, check the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Main_Page"><param name="text" value="<html><u>Nifty GUI wiki</u></html>"><param name="textColor" value="blue"></object> to get all the “bells and whistles”! href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Main_Page">Nifty GUI wiki</a> to get all the &quot;bells and whistles&quot; of the syntax!</p><hr
/><ol><li
</p> class="level1"><div
<hr /> class="li"> <a
<ol> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a></div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_xml_layout.html">Nifty GUI XML Layout</a> </div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> Projection</strong></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <strong>Nifty <acronym
</li> title="Graphical User Interface">GUI</acronym> Projection</strong></div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> class="level1"><div
</li> class="li"> <a
</ol> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><div
<div><span> class="tags"><span> <a
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, <a
<a href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a> href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a> </span></div></div>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_projection?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_projection?do=export_xhtmlbody">view online version</a></em></p>

@ -1,73 +1,52 @@
<h1><a
<h1><a>Laying out the GUI in XML</a></h1> name="laying_out_the_gui_in_xml">Laying out the GUI in XML</a></h1><div
<div> class="level1"><ol><li
<ol> class="level1"><div
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> Layout</strong></div> class="li"> <strong>Nifty <acronym
</li> title="Graphical User Interface">GUI</acronym> <acronym
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> title="Extensible Markup Language">XML</acronym> Layout</strong></div></li><li
</li> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a
</ol> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div></li><li
class="level1"><div
<p> class="li"> <a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-screen-layer-panel.png"> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><p> <a
</p> href="/wiki/lib/exe/detail.php/jme3:advanced:nifty-screen-layer-panel.png?id=jme3%3Aadvanced%3Anifty_gui_xml_layout"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/nifty-screen-layer-panel.png" class="media" alt="" /></a></p><p> You &quot;draw&quot; the <acronym
<p> title="Graphical User Interface">GUI</acronym> to the screen by writing <acronym
You “draw” the <acronym title="Graphical User Interface">GUI</acronym> to the screen by writing <acronym title="Extensible Markup Language">XML</acronym> code. We will be referring to the following elements: title="Extensible Markup Language">XML</acronym> code. We will be referring to the following elements:</p><ul><li
</p> class="level1"><div
<ul> class="li"> Every Nifty Gui is made up of screens.</div><ul><li
<li><div> Every Nifty Gui is made up of screens.</div> class="level2"><div
<ul> class="li"> Nifty can display only one screen at a time.</div></li><li
<li><div> Nifty can display only one screen at a time.</div> class="level2"><div
</li> class="li"> You must name the first screen <code>id=&quot;start&quot;</code>. Name any others whatever you like.</div></li><li
<li><div> You must name the first screen <code>id=“start”</code>. Name any others whatever you like.</div> class="level2"><div
</li> class="li"> Every screen is <a
<li><div> Every screen is <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">controlled by a Java class</a>.</div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">controlled by a Java class</a>.</div></li></ul></li><li
</li> class="level1"><div
</ul> class="li"> A screen contains one or more layers.</div><ul><li
</li> class="level2"><div
<li><div> A screen contains one or more layers. </div> class="li"> Layers are containers that impose an alignment on their content (vertical, horizontal, centered)</div></li><li
<ul> class="level2"><div
<li><div> Layers are containers that impose an alignment on their content (vertical, horizontal, centered)</div> class="li"> Layers can overlap (z-order), but cannot be nested.</div></li><li
</li> class="level2"><div
<li><div> Layers can overlap (z-order), but cannot be nested.</div> class="li"> Layers are usually transparent (but can be opaque).</div></li></ul></li><li
</li> class="level1"><div
<li><div> Layers are usually transparent (but can be opaque).</div> class="li"> A layer contains panels.</div><ul><li
</li> class="level2"><div
</ul> class="li"> Panels are containers that impose an alignment on their content (vertical, horizontal, centered)</div></li><li
</li> class="level2"><div
<li><div> A layer contains panels.</div> class="li"> Panels can be nested, but not overlap.</div></li><li
<ul> class="level2"><div
<li><div> Panels are containers that impose an alignment on their content (vertical, horizontal, centered)</div> class="li"> Panels are usually opaque (but can be transparent). ?</div></li></ul></li><li
</li> class="level1"><div
<li><div> Panels can be nested, but not overlap.</div> class="li"> A panel can contain images, text fields, buttons, controls.</div></li><li
</li> class="level1"><div
<li><div> Panels are usually opaque (but can be transparent). ?</div> class="li"> Every element has an id to refer to it.</div></li></ul></div><h2><a
</li> name="how_to_use_screens_and_layers">How to Use Screens and Layers</a></h2><div
</ul> class="level2"><p> Create an empty helloworld.xml file in the <code>assets/Interfaces/</code> directory of your project.</p><p> Here&#039;s a minimal example showing an empty centered layer on the start screen:</p><pre><span>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
</li>
<li><div> A panel can contain images, text fields, buttons, controls.</div>
</li>
<li><div> Every element has an id to refer to it.</div>
</li>
</ul>
</div>
<h2><a>How to Use Screens and Layers</a></h2>
<div>
<p>
Create an empty helloworld.xml file in the <code>assets/Interfaces/</code> directory of your project.
</p>
<p>
Here&#039;s a minimal example showing an empty centered layer on the start screen:
</p>
<pre><span>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span>&lt;nifty xmlns=&quot;http://nifty-gui.sourceforge.net/nifty.xsd&quot; </span> <span>&lt;nifty xmlns=&quot;http://nifty-gui.sourceforge.net/nifty.xsd&quot; </span>
<span> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </span> <span> xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; </span>
<span> xsi:schemaLocation=&quot;http://nifty-gui.sourceforge.net/nifty.xsd <span> xsi:schemaLocation=&quot;http://nifty-gui.sourceforge.net/nifty.xsd
@ -79,86 +58,40 @@ Here&#039;s a minimal example showing an empty centered layer on the start scree
<span><span>&lt;/layer&gt;</span></span> <span><span>&lt;/layer&gt;</span></span>
<span><span>&lt;/screen&gt;</span></span> <span><span>&lt;/screen&gt;</span></span>
&nbsp; &nbsp;
<span><span>&lt;/nifty&gt;</span></span></pre> <span><span>&lt;/nifty&gt;</span></span></pre><p> Into a layer, you add panels (text, images, etc), and specify their properties:</p></div><h3><a
<p> name="panel">Panel</a></h3><div
Into a layer, you add panels (text, images, etc), and specify their properties: class="level3"><p> A panels looks like a rectangular colored box.</p><pre>...
</p>
</div>
<h3><a>Panel</a></h3>
<div>
<p>
A panels looks like a rectangular colored box.
</p>
<pre>...
<span>&lt;panel height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot; backgroundColor=&quot;#f60f&quot;</span> <span>&lt;panel height=&quot;25%&quot; width=&quot;35%&quot; align=&quot;center&quot; valign=&quot;center&quot; backgroundColor=&quot;#f60f&quot;</span>
<span> childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span> <span> childLayout=&quot;center&quot; visibleToMouse=&quot;true&quot;&gt;</span>
<span><span>&lt;/panel&gt;</span></span> <span><span>&lt;/panel&gt;</span></span>
...</pre> ...</pre></div><h3><a
</div> name="text">Text</a></h3><div
class="level3"><pre>...
<h3><a>Text</a></h3>
<div>
<pre>...
<span>&lt;text font=&quot;verdana-24-shadow.fnt&quot; text=&quot;Hello World!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span> <span>&lt;text font=&quot;verdana-24-shadow.fnt&quot; text=&quot;Hello World!&quot; align=&quot;center&quot; valign=&quot;center&quot; /&gt;</span>
...</pre> ...</pre><p> or</p><pre>...
<p>
or
</p>
<pre>...
<span>&lt;label text=&quot;this is my text&quot; align=&quot;left&quot;/&gt;</span> <span>&lt;label text=&quot;this is my text&quot; align=&quot;left&quot;/&gt;</span>
...</pre> ...</pre></div><h3><a
</div> name="image">Image</a></h3><div
class="level3"><pre><span>&lt;image filename=&quot;Textures/jme-logo.png&quot; &gt;<span>&lt;/image&gt;</span></span></pre><p> Nifty additionally offers predefined controls – learn more from the NiftyGUI page:</p><ul><li
<h3><a>Image</a></h3> class="level1"><div
<div> class="li"> <a
<pre><span>&lt;image filename=&quot;Textures/jme-logo.png&quot; &gt;<span>&lt;/image&gt;</span></span></pre> href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction</a></div></li><li
<p> class="level1"><div
Nifty additionally offers predefined controls – learn more from the NiftyGUI page: class="li"> <a
</p> href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements</a></div></li></ul></div><h2><a
<ul> name="effects">Effects</a></h2><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction</u></html>"><param name="textColor" value="blue"></object></div> class="level2"><p> You can register effects to screen elements.</p><ul><li
</li> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements</u></html>"><param name="textColor" value="blue"></object></div> class="li"> Respond to element events such as onStartScreen, onEndScreen, onHover, onFocus, onActive,</div></li><li
</li> class="level1"><div
</ul> class="li"> Trigger effects that change movement, blending, size, color, fading, and much more.</div></li></ul><p> Here is an example that moves a panel when the startScreen opens. You place an &lt; effect &gt; tag inside the element that you want to want to be affected.</p><pre>...
</div>
<h2><a>Effects</a></h2>
<div>
<p>
You can register effects to screen elements.
</p>
<ul>
<li><div> Respond to element events such as onStartScreen, onEndScreen, onHover, onFocus, onActive,</div>
</li>
<li><div> Trigger effects that change movement, blending, size, color, fading, and much more.</div>
</li>
</ul>
<p>
Here is an example that moves a panel when the startScreen opens. You place an &lt; effect &gt; tag inside the element that you want to want to be affected.
</p>
<pre>...
<span>&lt;panel height=&quot;25%&quot; width=&quot;35%&quot; ...&gt;</span> <span>&lt;panel height=&quot;25%&quot; width=&quot;35%&quot; ...&gt;</span>
<span><span>&lt;effect&gt;</span></span> <span><span>&lt;effect&gt;</span></span>
<span>&lt;onStartScreen name=&quot;move&quot; mode=&quot;in&quot; direction=&quot;top&quot; </span> <span>&lt;onStartScreen name=&quot;move&quot; mode=&quot;in&quot; direction=&quot;top&quot; </span>
<span> length=&quot;300&quot; startDelay=&quot;0&quot; inherit=&quot;true&quot;/&gt;</span> <span> length=&quot;300&quot; startDelay=&quot;0&quot; inherit=&quot;true&quot;/&gt;</span>
<span><span>&lt;/effect&gt;</span></span> <span><span>&lt;/effect&gt;</span></span>
<span><span>&lt;/panel&gt;</span></span> <span><span>&lt;/panel&gt;</span></span>
...</pre> ...</pre><p> Playing sounds using nifty is also possible with effects as triggers. Remember to first register the sound you&#039;re going to play:</p><pre>...
<p>
Playing sounds using nifty is also possible with effects as triggers. Remember to first register the sound you&#039;re going to play:
</p>
<pre>...
<span>&lt;registerSound id=&quot;click&quot; filename=&quot;Sounds/Gui/ButtonClick.ogg&quot; /&gt;</span> <span>&lt;registerSound id=&quot;click&quot; filename=&quot;Sounds/Gui/ButtonClick.ogg&quot; /&gt;</span>
... ...
<span><span>&lt;label&gt;</span></span> <span><span>&lt;label&gt;</span></span>
@ -166,28 +99,23 @@ Playing sounds using nifty is also possible with effects as triggers. Remember t
<span>&lt;onClick name=&quot;playSound&quot; sound=&quot;click&quot;/&gt;</span> <span>&lt;onClick name=&quot;playSound&quot; sound=&quot;click&quot;/&gt;</span>
<span><span>&lt;/effect&gt;</span></span> <span><span>&lt;/effect&gt;</span></span>
<span><span>&lt;/label&gt;</span></span> <span><span>&lt;/label&gt;</span></span>
...</pre> ...</pre><p> Learn more from the NiftyGUI page:</p><ul><li
<p> class="level1"><div
class="li"> <a
Learn more from the NiftyGUI page: href="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects">http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects</a></div></li></ul><hr
</p> /><ol><li
<ul> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects"><param name="text" value="<html><u>http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Effects</u></html>"><param name="textColor" value="blue"></object></div> class="li"> <strong>Nifty <acronym
</li> title="Graphical User Interface">GUI</acronym> <acronym
</ul> title="Extensible Markup Language">XML</acronym> Layout</strong></div></li><li
<hr /> class="level1"><div
<ol> class="li"> <a
<li><div> <strong>Nifty <acronym title="Graphical User Interface">GUI</acronym> <acronym title="Extensible Markup Language">XML</acronym> Layout</strong></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_overlay.html">Nifty GUI Overlay</a> or <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html">Nifty GUI Projection</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_java_interaction.html">Interact with the GUI from Java</a></div></li></ol><div
</li> class="tags"><span> <a
</ol> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<div><span> href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a> </span></div></div>
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_xml_layout?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui_xml_layout?do=export_xhtmlbody">view online version</a></em></p>

@ -1,208 +1,178 @@
<h1><a
<h1><a>Particle Emmitter Settings</a></h1> name="particle_emmitter_settings">Particle Emmitter Settings</a></h1><div
<div> class="level1"><p> You cannot create a 3D model for delicate things like fire, smoke, or explosions. Particle Emitters are quite an efficient solution to create these kinds of effects: The emitter renders a series of flat orthogonal images and manipulates them in a way that creates the illusion of a anything from a delicate smoke cloud to individual flames, etc.</p><p> Creating an effect involves some trial and error to get the settings <em>just right</em>, and it&#039;s worth exploring the expressiveness of the options described below. <strong>Tip:</strong> Use the Scene Editor in the <a
href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to design and preview effects.</p><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:explosion-5.png?id=jme3%3Aadvanced%3Aparticle_emitters"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/explosion-5.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a> <a
You cannot create a 3D model for delicate things like fire, smoke, or explosions. Particle Emitters are quite an efficient solution to create these kinds of effects: The emitter renders a series of flat orthogonal images and manipulates them in a way that creates the illusion of a anything from a delicate smoke cloud to individual flames, etc. href="/wiki/lib/exe/detail.php/jme3:advanced:particle.png?id=jme3%3Aadvanced%3Aparticle_emitters"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/particle.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a> <a
href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-effect-fire.png?id=jme3%3Aadvanced%3Aparticle_emitters"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-effect-fire.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a> <a
Creating an effect involves some trial and error to get the settings <em>just right</em>, and it&#039;s worth exploring the expressiveness of the options described below. <strong>Tip:</strong> Use the Scene Editor in the <a href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to design and preview effects. href="/wiki/lib/exe/detail.php/jme3:advanced:butterfly-particle-emitter.png?id=jme3%3Aadvanced%3Aparticle_emitters"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/butterfly-particle-emitter.png?w=150&amp;h=100" class="media" alt="" width="150" height="100" /></a></p></div><h2><a
name="create_an_emitter">Create an Emitter</a></h2><div
<p> class="level2"><ol><li
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/explosion-5.png"> <img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/particle.png"> <img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-effect-fire.png"> <img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/butterfly-particle-emitter.png"> class="level1"><div
</p> class="li"> Create one emitter for each effect:<pre>ParticleEmitter explosion = new ParticleEmitter&#40;
&quot;My explosion effect&quot;, ParticleMesh.Type.Triangle, 30&#41;;</pre></div></li><li
</div> class="level1"><div
class="li"> Attach the emitter to the rootNode and position it in the scene:<pre>rootNode.attachChild&#40;explosion&#41;;
<h2><a>Create an Emitter</a></h2> explosion.setLocalTranslation&#40;bomb.getLocalTranslation&#40;&#41;&#41;;</pre></div></li><li
<div> class="level1"><div
<ol> class="li"> Trigger the effect by calling<pre>explosion.emitAllParticles&#40;&#41;</pre></div></li><li
<li><div> Create one emitter for each effect: <pre>ParticleEmitter explosion = new ParticleEmitter&#40; class="level1"><div
&quot;My explosion effect&quot;, ParticleMesh.Type.Triangle, 30&#41;;</pre></div> class="li"> End the effect by calling<pre>explosion.killAllParticles&#40;&#41;</pre></div></li></ol><p> Choose one of the following mesh shapes</p><ul><li
</li> class="level1"><div
<li><div> Attach the emitter to the rootNode and position it in the scene: <pre>rootNode.attachChild&#40;explosion&#41;; class="li"> ParticleMesh.Type.Triangle</div></li><li
explosion.setLocalTranslation&#40;bomb.getLocalTranslation&#40;&#41;&#41;;</pre></div> class="level1"><div
</li> class="li"> ParticleMesh.Type.Point</div></li></ul></div><h2><a
<li><div> Trigger the effect by calling <pre>explosion.emitAllParticles&#40;&#41;</pre></div> name="configure_parameters">Configure Parameters</a></h2><div
</li> class="level2"><p> Not all of these parameters are required for all kinds of effects. If you don&#039;t specify one of them, a default value will be used.</p><div
<li><div> End the effect by calling <pre>explosion.killAllParticles&#40;&#41;</pre></div> class="table sectionedit1"><table
</li> class="inline"><tr
</ol> class="row0"><th
class="col0 leftalign"> Parameter</th><th
<p> class="col1 leftalign"> Method</th><th
class="col2"> Default</th><th
Choose one of the following mesh shapes class="col3"> Description</th></tr><tr
</p> class="row1"><td
<ul> class="col0 leftalign"> number</td><td
<li><div> ParticleMesh.Type.Triangle</div> class="col1"> <code>setNumParticles()</code></td><td
</li> class="col2 leftalign"></td><td
<li><div> ParticleMesh.Type.Point</div> class="col3"> The maximum number of particles visible at the same time. Specified by user in constructor.</td></tr><tr
</li> class="row2"><td
</ul> class="col0 leftalign"> emission rate</td><td
class="col1"> <code>setParticlesPerSec()</code></td><td
</div> class="col2"> 20</td><td
class="col3"> Density of the effect, how many new particles are emitted per second. <br/> Set to zero to control the start of the effect. <br/> Set to a number for a constantly running effect.</td></tr><tr
<h2><a>Configure Parameters</a></h2> class="row3"><td
<div> class="col0 leftalign"> size</td><td
class="col1"> <code>setStartSize()</code>, <code>setEndSize()</code></td><td
<p> class="col2"> 0.2f, 2f</td><td
class="col3"> Set both to same value for constant size effect. <br/> Set to different values for shrink/grow effect.</td></tr><tr
Not all of these parameters are required for all kinds of effects. If you don&#039;t specify one of them, a default value will be used. class="row4"><td
class="col0 leftalign"> color</td><td
</p> class="col1"> <code>setStartColor()</code>, <code>setEndColor()</code></td><td
<table> class="col2"> gray, darkgray</td><td
<tr> class="col3"> Set both to the same color for single-colored effects (e.g. fog). <br/> Set both to different colors for a gradient effect (e.g. fire).</td></tr><tr
<th> Parameter </th><th> Method </th><th> Default </th><th> Description </th> class="row5"><td
</tr> class="col0 leftalign"> velocity/direction</td><td
<tr> class="col1"> <code>setInitialVelocity()</code></td><td
<td> number </td><td> <code>setNumParticles()</code> </td><td> </td><td> The maximum number of particles visible at the same time. Specified by user in constructor. </td> class="col2"> Vector3f(0,0,0)</td><td
</tr> class="col3"> A vector specifying how fast or slow particles fly, and it which direction.</td></tr><tr
<tr> class="row6"><td
<td> emission rate </td><td> <code>setParticlesPerSec()</code> </td><td> 20 </td><td> Density of the effect, how many new particles are emitted per second. <br/> class="col0 leftalign"> randomness</td><td
Set to zero to control the start of the effect. <br/> class="col1"> <code>setVelocityVariation()</code></td><td
Set to a number for a constantly running effect. </td> class="col2"> 0.2f</td><td
</tr> class="col3"> How much the direction/speed (<code>setInitialVelocity()</code>) can vary. <br/> 1 = Maximum variation (particles emit in random directions) <br/> 0 = No variation (particles fly straight with start velocity only).</td></tr><tr
<tr> class="row7"><td
<td> size </td><td> <code>setStartSize()</code>, <code>setEndSize()</code> </td><td> 0.2f, 2f </td><td> Set both to same value for constant size effect. <br/> class="col0 leftalign"> direction</td><td
Set to different values for shrink/grow effect. </td> class="col1"> <code>setFacingVelocity()</code></td><td
</tr> class="col2"> false</td><td
<tr> class="col3"> true = Flying particles pitch in the direction they&#039;re flying (e.g. missiles). <br/> false = Particles keep flying rotated the way they started (e.g. debris).</td></tr><tr
<td> color </td><td> <code>setStartColor()</code>, <code>setEndColor()</code> </td><td> gray, darkgray </td><td> Set both to the same color for single-colored effects (e.g. fog). <br/> class="row8"><td
Set both to different colors for a gradient effect (e.g. fire). </td> class="col0 leftalign"> direction</td><td
</tr> class="col1"> <code>setRandomAngle()</code></td><td
<tr> class="col2"> false</td><td
<td> velocity/direction </td><td> <code>setInitialVelocity()</code> </td><td> Vector3f(0,0,0) </td><td> A vector specifying how fast or slow particles fly, and it which direction. </td> class="col3"> true = Flying particle should face at a random angle (e.g. explosion). <br/> false = Flying particle flies straight.</td></tr><tr
</tr> class="row9"><td
<tr> class="col0 leftalign"> direction</td><td
<td> randomness </td><td> <code>setVelocityVariation()</code> </td><td> 0.2f </td><td> How much the direction/speed (<code>setInitialVelocity()</code>) can vary. <br/> class="col1"> <code>setFaceNormal()</code></td><td
1 = Maximum variation (particles emit in random directions) <br/> class="col2"> Vector3f.NAN</td><td
0 = No variation (particles fly straight with start velocity only). </td> class="col3"> Vector3f = Flying particles face in the given direction. <br/> Vector3f.NAN = Flying particles face the camera.</td></tr><tr
</tr> class="row10"><td
<tr> class="col0 leftalign"> lifetime</td><td
<td> direction </td><td> <code>setFacingVelocity()</code> </td><td> false </td><td> true = Flying particles pitch in the direction they&#039;re flying (e.g. missiles). <br/> class="col1"> <code>setLowLife()</code></td><td
false = Particles keep flying rotated the way they started (e.g. debris). </td> class="col2"> 3f</td><td
</tr> class="col3"> Minimum time period before particles fade</td></tr><tr
<tr> class="row11"><td
<td> direction </td><td> <code>setRandomAngle()</code> </td><td> false </td><td> true = Flying particle should face at a random angle (e.g. explosion). <br/> class="col0 leftalign"> lifetime</td><td
false = Flying particle flies straight. </td> class="col1"> <code>setHighLife()</code></td><td
</tr> class="col2"> 7f</td><td
<tr> class="col3"> Maximum time period before particles fade</td></tr><tr
<td> direction </td><td> <code>setFaceNormal()</code> </td><td> Vector3f.NAN </td><td> Vector3f = Flying particles face in the given direction. <br/> class="row12"><td
Vector3f.NAN = Flying particles face the camera. </td> class="col0 leftalign"> rotation</td><td
</tr> class="col1"> <code>setRotateSpeed()</code></td><td
<tr> class="col2"> 0f</td><td
<td> lifetime </td><td> <code>setLowLife()</code> </td><td> 3f </td><td> Minimum time period before particles fade </td> class="col3"> 0 = Flying particles don&#039;t spin. <br/> &gt; 0 = How fast particle spins while flying.</td></tr><tr
</tr> class="row13"><td
<tr> class="col0 leftalign"> gravity</td><td
<td> lifetime </td><td> <code>setHighLife()</code> </td><td> 7f </td><td> Maximum time period before particles fade </td> class="col1"> <code>setGravity()</code></td><td
</tr> class="col2"> 0.1f</td><td
<tr> class="col3"> &gt;0 = Particles fall &quot;down&quot; (e.g. debris, sparks). <br/> 0.0f = Particles keep flying (e.g. flames, zero g explosion.)</td></tr></table></div><p> Build up you effect by specifying one parameter after the other. If you change several parameters at the same time, it&#039;s difficult to tell which of the values caused which outcome.</p></div><h2><a
<td> rotation </td><td> <code>setRotateSpeed()</code> </td><td> 0f </td><td> 0 = Flying particles don&#039;t spin. <br/> name="create_an_effect_material">Create an Effect Material</a></h2><div
&gt; 0 = How fast particle spins while flying. </td> class="level2"><p> <a
</tr> href="/wiki/lib/exe/fetch.php?hash=b9f99a&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflash.png"><img
<tr> src="/wiki/lib/exe/fetch.php?hash=b9f99a&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflash.png" class="mediaright" align="right" alt="" width="128" height="128" /></a></p><p> Use the common Particle.j3md Material Definition to specify the shape of the particles. The shape is only limited by the texture you provide and can be anything – debris, flames, smoke, mosquitoes, leaves, butterflies… be creative.</p><pre> Material mat_flash = new Material&#40;
<td> gravity </td><td> <code>setGravity()</code> </td><td> 0.1f </td><td> &gt;0 = Particles fall “down” (e.g. debris, sparks). <br/>
0.0f = Particles keep flying (e.g. flames, zero g explosion.) </td>
</tr>
</table>
<p>
Build up you effect by specifying one parameter after the other. If you change several parameters at the same time, it&#039;s difficult to tell which of the values caused which outcome.
</p>
</div>
<h2><a>Create an Effect Material</a></h2>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
Use the common Particle.j3md Material Definition to specify the shape of the particles. The shape is only limited by the texture you provide and can be anything – debris, flames, smoke, mosquitoes, leaves, butterflies… be creative.
</p>
<pre> Material mat_flash = new Material&#40;
assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;; assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;;
mat_flash.setTexture&#40;&quot;Texture&quot;, mat_flash.setTexture&#40;&quot;Texture&quot;,
assetManager.loadTexture&#40;&quot;Effects/Explosion/flash.png&quot;&#41;&#41;; assetManager.loadTexture&#40;&quot;Effects/Explosion/flash.png&quot;&#41;&#41;;
flash.setMaterial&#40;debris_mat&#41;; flash.setMaterial&#40;debris_mat&#41;;
flash.setImagesX&#40;2&#41;; // columns flash.setImagesX&#40;2&#41;; // columns
flash.setImagesY&#40;2&#41;; // rows flash.setImagesY&#40;2&#41;; // rows
flash.setSelectRandomImage&#40;true&#41;;</pre> flash.setSelectRandomImage&#40;true&#41;;</pre><p> The effect texture can contain Sprite animations – a series of different pictures in equally spaced rows and columns.</p><ul><li
<p> class="level1"><div
The effect texture can contain Sprite animations – a series of different pictures in equally spaced rows and columns. class="li"> Specify the number of rows and columns</div></li><li
</p> class="level1"><div
<ul> class="li"> Specify whether you want to play the series in order or at random.</div></li></ul><p> Have a look at the following default textures and you will see that you can easily create your own Sprite textures after the same fashion.</p></div><h3><a
<li><div> Specify the number of rows and columns</div> name="default_particle_textures">Default Particle Textures</a></h3><div
</li> class="level3"><p> The Material is used together with grayscale texture: The black parts will be transparent and the white parts will be opaque.</p><p> The following effect textures are available by default from <code>test-data.jar</code>. You can also load your own textures from your assets directory.</p><div
<li><div> Specify whether you want to play the series in order or at random.</div> class="table sectionedit2"><table
</li> class="inline"><tr
</ul> class="row0"><th
class="col0 leftalign"> Texture Path</th><th
<p> class="col1"> Dimension</th><th
class="col2"> Preview</th></tr><tr
Have a look at the following default textures and you will see that you can easily create your own Sprite textures after the same fashion. class="row1"><td
</p> class="col0 leftalign"> Effects/Explosion/Debris.png</td><td
class="col1 leftalign"> 3*3</td><td
</div> class="col2"> <a
href="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png"><img
<h3><a>Default Particle Textures</a></h3> src="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<div> class="row2"><td
class="col0 leftalign"> Effects/Explosion/flame.png</td><td
<p> class="col1 leftalign"> 2*2</td><td
class="col2"> <a
The Material is used together with grayscale texture: The black parts will be transparent and the white parts will be opaque. href="/wiki/lib/exe/fetch.php?hash=27332f&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png"><img
</p> src="/wiki/lib/exe/fetch.php?hash=27332f&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
class="row3"><td
<p> class="col0 leftalign"> Effects/Explosion/flash.png</td><td
The following effect textures are available by default from <code>test-data.jar</code>. You can also load your own textures from your assets directory. class="col1 leftalign"> 2*2</td><td
class="col2"> <a
</p> href="/wiki/lib/exe/fetch.php?hash=b9f99a&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflash.png"><img
<table> src="/wiki/lib/exe/fetch.php?hash=b9f99a&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflash.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<tr> class="row4"><td
<th> Texture Path </th><th> Dimension </th><th> Preview </th> class="col0"> Effects/Explosion/roundspark.png</td><td
</tr> class="col1 leftalign"> 1*1</td><td
<tr> class="col2"> <a
<td> Effects/Explosion/Debris.png </td><td> 3*3 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> href="/wiki/lib/exe/fetch.php?hash=467d19&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Froundspark.png"><img
</tr> src="/wiki/lib/exe/fetch.php?hash=467d19&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Froundspark.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<tr> class="row5"><td
<td> Effects/Explosion/flame.png </td><td> 2*2 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col0 leftalign"> Effects/Explosion/shockwave.png</td><td
</tr> class="col1 leftalign"> 1*1</td><td
<tr> class="col2"> <a
<td> Effects/Explosion/flash.png </td><td> 2*2 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> href="/wiki/lib/exe/fetch.php?hash=fc0cbc&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fshockwave.png"><img
</tr> src="/wiki/lib/exe/fetch.php?hash=fc0cbc&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fshockwave.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<tr> class="row6"><td
<td> Effects/Explosion/roundspark.png </td><td> 1*1 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col0"> Effects/Explosion/smoketrail.png</td><td
</tr> class="col1 leftalign"> 1*3</td><td
<tr> class="col2"> <a
<td> Effects/Explosion/shockwave.png </td><td> 1*1 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> href="/wiki/lib/exe/fetch.php?hash=cb2aa9&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fsmoketrail.png"><img
</tr> src="/wiki/lib/exe/fetch.php?hash=cb2aa9&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fsmoketrail.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<tr> class="row7"><td
<td> Effects/Explosion/smoketrail.png </td><td> 1*3 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col0 leftalign"> Effects/Explosion/spark.png</td><td
</tr> class="col1 leftalign"> 1*1</td><td
<tr> class="col2"> <a
<td> Effects/Explosion/spark.png </td><td> 1*1 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> href="/wiki/lib/exe/fetch.php?hash=603e22&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fspark.png"><img
</tr> src="/wiki/lib/exe/fetch.php?hash=603e22&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fspark.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
<tr> class="row8"><td
<td> Effects/Smoke/Smoke.png </td><td> 1*15 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col0 leftalign"> Effects/Smoke/Smoke.png</td><td
</tr> class="col1"> 1*15</td><td
</table> class="col2"> <a
href="/wiki/lib/exe/fetch.php?hash=9adb0f&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FSmoke%2FSmoke.png"><img
<p> src="/wiki/lib/exe/fetch.php?hash=9adb0f&amp;w=96&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FSmoke%2FSmoke.png" class="media" alt="" width="96" height="32" /></a></td></tr></table></div><p> <strong>Tip:</strong> Use the <code>setStartColor()</code>/<code>setEndColor()</code> settings described above to colorize the textures.</p></div><h2><a
<strong>Tip:</strong> Use the <code>setStartColor()</code>/<code>setEndColor()</code> settings described above to colorize the textures. name="usage_example">Usage Example</a></h2><div
</p> class="level2"><pre> ParticleEmitter fire = new ParticleEmitter&#40;&quot;Emitter&quot;, ParticleMesh.Type.Triangle, 30&#41;;
</div>
<h2><a>Usage Example</a></h2>
<div>
<pre> ParticleEmitter fire = new ParticleEmitter&#40;&quot;Emitter&quot;, ParticleMesh.Type.Triangle, 30&#41;;
Material mat_red = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;; Material mat_red = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;;
mat_red.setTexture&#40;&quot;Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/flame.png&quot;&#41;&#41;; mat_red.setTexture&#40;&quot;Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/flame.png&quot;&#41;&#41;;
fire.setMaterial&#40;mat_red&#41;; fire.setMaterial&#40;mat_red&#41;;
@ -216,17 +186,8 @@ The following effect textures are available by default from <code>test-data.jar<
fire.setLowLife&#40;0.5f&#41;; fire.setLowLife&#40;0.5f&#41;;
fire.setHighLife&#40;3f&#41;; fire.setHighLife&#40;3f&#41;;
fire.setVelocityVariation&#40;0.3f&#41;; fire.setVelocityVariation&#40;0.3f&#41;;
rootNode.attachChild&#40;fire&#41;;</pre> rootNode.attachChild&#40;fire&#41;;</pre><p> Browse the full source code of all <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/#svn/branches/jme3/src/test/jme3test/effect">effect examples</a> here.</p><hr
Browse the full source code of all <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/#svn/branches/jme3/src/test/jme3test/effect"><param name="text" value="<html><u>effect examples</u></html>"><param name="textColor" value="blue"></object> here. /><p> See also: <a
href="/com/jme3/gde/core/docs/jme3/advanced/effects_overview.html">Effects Overview</a></p></div>
</p>
<hr />
<p>
See also: <a href="/com/jme3/gde/core/docs/jme3/advanced/effects_overview.html">Effects Overview</a>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:particle_emitters?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:particle_emitters?do=export_xhtmlbody">view online version</a></em></p>

@ -1,306 +1,145 @@
<h1><a
<h1><a>Physics: Gravity, Collisions, Forces</a></h1> name="physicsgravity_collisions_forces">Physics: Gravity, Collisions, Forces</a></h1><div
<div> class="level1"><p> The jMonkeyEngine3 has built-in support for <a
href="http://jbullet.advel.cz">jBullet physics</a> via the <code>com.jme3.bullet</code> package.
<p>
The jMonkeyEngine3 has built-in support for <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jbullet.advel.cz"><param name="text" value="<html><u>jBullet physics</u></html>"><param name="textColor" value="blue"></object> via the <code>com.jme3.bullet</code> package.
Game Physics are used in applications that simulate mass/gravity, collisions, and friction. Think of pool billiard or car racing simulations. Game Physics are used in applications that simulate mass/gravity, collisions, and friction. Think of pool billiard or car racing simulations.
</p> If you are looking for info on how to respond to physics events, read about <a
href="/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html">Physics Listeners</a>.</p></div><h2><a
<p> name="technical_overview">Technical Overview</a></h2><div
If you are looking for info on how to respond to physics events, read about <a href="/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html">Physics Listeners</a>. class="level2"><p> Bullet physics runs internally at 60fps by default. This rate is not dependent on the actual framerate and it does not lock the framerate at 60fps. Instead, when the actual fps is higher than the physics framerate the system will display interpolated positions for the physics objects. When the framerate is lower than the physics framerate the physics space will be stepped multiple times per frame to make up for the missing calculations.
</p>
</div>
<h2><a>Technical Overview</a></h2>
<div>
<p>
Bullet physics runs internally at 60fps by default. This rate is not dependent on the actual framerate and it does not lock the framerate at 60fps. Instead, when the actual fps is higher than the physics framerate the system will display interpolated positions for the physics objects. When the framerate is lower than the physics framerate the physics space will be stepped multiple times per frame to make up for the missing calculations.
</p>
<p>
A bullet physics space can be created with a BulletAppState. The updating and syncing of the actual physics objects happens in the following way: A bullet physics space can be created with a BulletAppState. The updating and syncing of the actual physics objects happens in the following way:
</p> A &quot;normal&quot; update loop with physics looks like this:</p><ol><li
class="level1"><div
<p> class="li"> collision callbacks (BulletAppState.update())</div></li><li
A “normal” update loop with physics looks like this: class="level1"><div
</p> class="li"> user update (simpleUpdate / update)</div></li><li
<ol> class="level1"><div
<li><div> collision callbacks (BulletAppState.update())</div> class="li"> physics to scenegraph syncing/applying (updateLogicalState())</div></li><li
</li> class="level1"><div
<li><div> user update (simpleUpdate / update)</div> class="li"> stepping physics (before / in parallel to Application.render())</div></li></ol><p> When you use physics, 1 unit (1.0f) equals 1 meter, weight is expressed in kilograms, most torque and rotation values are expressed in radians.</p></div><h2><a
</li> name="sample_code">Sample Code</a></h2><div
<li><div> physics to scenegraph syncing/applying (updateLogicalState())</div> class="level2"><p> Full code samples are here:</p><ul><li
</li> class="level1"><div
<li><div> stepping physics (before / in parallel to Application.render())</div> class="li"> <a
</li> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestBrickWall.java">TestBrickWall.java</a></div></li><li
</ol> class="level1"><div
class="li"> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestQ3.java">TestQ3.java</a></div></li><li
class="level1"><div
When you use physics, 1 unit (1.0f) equals 1 meter, weight is expressed in kilograms, most torque and rotation values are expressed in radians. class="li"> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestSimplePhysics.java">TestSimplePhysics.java</a></div></li><li
class="level1"><div
</div> class="li"> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java">TestWalkingChar.java</a></div></li></ul></div><h2><a
<h2><a>Sample Code</a></h2> name="physics_application">Physics Application</a></h2><div
<div> class="level2"><p> A short overview of how to write a jME application with Physics capabilities:
Do the following once per application to gain access to the <code>physicsSpace</code> object:</p><ol><li
<p> class="level1"><div
class="li"> Make you application extend <code>com.jme3.app.SimpleApplication</code>.</div></li><li
Full code samples are here: class="level1"><div
class="li"> Create a BulletAppState field:<pre>private BulletAppState bulletAppState;</pre></div></li><li
</p> class="level1"><div
<ul> class="li"> Initialize your bulletAppState and attach it to the state manager:<pre>public void simpleInitApp&#40;&#41; &#123;
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestBrickWall.java"><param name="text" value="<html><u>TestBrickWall.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestQ3.java"><param name="text" value="<html><u>TestQ3.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestSimplePhysics.java"><param name="text" value="<html><u>TestSimplePhysics.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java"><param name="text" value="<html><u>TestWalkingChar.java</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<h2><a>Physics Application</a></h2>
<div>
<p>
A short overview of how to write a jME application with Physics capabilities:
</p>
<p>
Do the following once per application to gain access to the <code>physicsSpace</code> object:
</p>
<ol>
<li><div> Make you application extend <code>com.jme3.app.SimpleApplication</code>.</div>
</li>
<li><div> Create a BulletAppState field: <pre>private BulletAppState bulletAppState;</pre></div>
</li>
<li><div> Initialize your bulletAppState and attach it to the state manager: <pre>public void simpleInitApp&#40;&#41; &#123;
bulletAppState = new BulletAppState&#40;&#41;; bulletAppState = new BulletAppState&#40;&#41;;
stateManager.attach&#40;bulletAppState&#41;; stateManager.attach&#40;bulletAppState&#41;;
...</pre></div> ...</pre></div></li></ol><p> You can also access the BulletAppState via the state manager:</p><pre>stateManager.getState&#40;BulletAppState.class&#41;</pre><p> For each Spatial that you want to be physical:</p><ol><li
</li> class="level1"><div
</ol> class="li"> Create a CollisionShape.</div></li><li
class="level1"><div
<p> class="li"> Create a PhysicsControl by supplying the CollisionShape and mass.</div><ul><li
class="level2"><div
You can also access the BulletAppState via the state manager: class="li"> E.g. <code>com.jme3.bullet.control.RigidBodyControl</code></div></li></ul></li><li
class="level1"><div
</p> class="li"> Add the PhysicsControl to the Spatial.</div></li><li
<pre>stateManager.getState&#40;BulletAppState.class&#41;</pre> class="level1"><div
<p> class="li"> Add the PhysicsControl to the physicsSpace object.</div></li><li
For each Spatial that you want to be physical: class="level1"><div
class="li"> Attach the Spatial to the rootNode, as usual.</div></li><li
</p> class="level1"><div
<ol> class="li"> (Optional) Implement the <code>PhysicsCollisionListener</code> interface to respond to <code>PhysicsCollisionEvent</code>s if desired.</div></li></ol></div><h3><a
<li><div> Create a CollisionShape.</div> name="collision_shapes">Collision Shapes</a></h3><div
</li> class="level3"><p> Before you can create a Physics Control, you must create a Collision Shape from the <code>com.jme3.bullet.collision.shapes</code> package.
<li><div> Create a PhysicsControl by supplying the CollisionShape and mass.</div> The Collision Shape is a simplified shape for which physics are easier to calculate than for the real shape of the model. This approach speeds up the simulation greatly.</p><div
<ul> class="table sectionedit1"><table
<li><div> E.g. <code>com.jme3.bullet.control.RigidBodyControl</code></div> class="inline"><tr
</li> class="row0"><th
</ul> class="col0 leftalign"> Shape</th><th
</li> class="col1"> Purpose</th></tr><tr
<li><div> Add the PhysicsControl to the Spatial.</div> class="row1"><td
</li> class="col0 leftalign"> BoxCollisionShape</td><td
<li><div> Add the PhysicsControl to the physicsSpace object.</div> class="col1"> Box shaped objects such as bricks, crates, simple obstacles. Does not roll.</td></tr><tr
</li> class="row2"><td
<li><div> Attach the Spatial to the rootNode, as usual.</div> class="col0 leftalign"> SphereCollisionShape</td><td
</li> class="col1"> Spherical objects such as balls. Can roll.</td></tr><tr
<li><div> (Optional) Implement the <code>PhysicsCollisionListener</code> interface to respond to <code>PhysicsCollisionEvent</code>s if desired.</div> class="row3"><td
</li> class="col0 leftalign"> CylinderCollisionShape</td><td
</ol> class="col1"> Tube-shaped pillars, disc-shaped wheels. Can roll on one side.</td></tr><tr
class="row4"><td
</div> class="col0 leftalign"> CapsuleCollisionShape</td><td
class="col1"> A compound of a cylinder plus two spheres at the top and bottom. Rotated upright, this shape is optimal for character nodes: A cylinder-shaped body does not get stuck at corners and vertical obstacles; the rounded top and bottom do not get stuck on stair steps and ground obstacles. Is locked to stay upright, does not roll.</td></tr><tr
<h3><a>Collision Shapes</a></h3> class="row5"><td
<div> class="col0 leftalign"> CompoundCollisionShape</td><td
class="col1"> A CompoundCollisionShape allows custom combinations of box/sphere/cylinder shapes to form another more complex shape.</td></tr><tr
<p> class="row6"><td
class="col0 leftalign"> MeshCollisionShape</td><td
Before you can create a Physics Control, you must create a Collision Shape from the <code>com.jme3.bullet.collision.shapes</code> package. class="col1"> A free-form mesh-accurate shape that wraps itself around a mesh. <br/> <strong>Limitations:</strong> Only non-mesh collision shapes (sphere, box, cylinder, compound) can collide with mesh-accurate collision shapes. The Mesh Collision Shape only works for static obstacles, e.g. for a game level model.</td></tr><tr
</p> class="row7"><td
class="col0 leftalign"> GImpactCollisionShape</td><td
<p> class="col1"> This free-form Mesh Collision Shape can be used for moving objects. Uses <a
The Collision Shape is a simplified shape for which physics are easier to calculate than for the real shape of the model. This approach speeds up the simulation greatly. href="http://gimpact.sourceforge.net/">http://gimpact.sourceforge.net/</a>. <strong>Limitations:</strong> CPU intensive, use sparingly! We recommend using HullCollisionShapes or CompoundShapes made of simple shapes if you need improved performance.</td></tr><tr
class="row8"><td
</p> class="col0"> HeightFieldCollisionShape</td><td
<table> class="col1"> Optimized Mesh Collision Shape for static terrains. This shape is much faster than a other Free-Form Mesh Shapes. Requires heightmap data.</td></tr><tr
<tr> class="row9"><td
<th> Shape </th><th> Purpose </th> class="col0"> HullCollisionShape</td><td
</tr> class="col1"> A collision shape that is based on a mesh but is a simplified convex version.</td></tr><tr
<tr> class="row10"><td
<td> BoxCollisionShape </td><td> Box shaped objects such as bricks, crates, simple obstacles. Does not roll. </td> class="col0"> SimplexCollisionShape</td><td
</tr> class="col1">A physical point, line, triangle, or quad Collision Shape, defined by one to four points.</td></tr><tr
<tr> class="row11"><td
<td> SphereCollisionShape </td><td> Spherical objects such as balls. Can roll. </td> class="col0"> PlaneCollisionShape</td><td
</tr> class="col1"> A 2D plane that can be used as flat solid floor or wall.</td></tr></table></div><p> Pick the right shape for the mesh for what you want to do: If you give a box a sphere collision shape, it will roll; if you give a ball a box collision shape, it will sit on a slope.
<tr> Let&#039;s look at the constructor:</p></div><h3><a
<td> CylinderCollisionShape </td><td> Tube-shaped pillars, disc-shaped wheels. Can roll on one side. </td> name="collision_shape_code_samples">Collision Shape Code Samples</a></h3><div
</tr> class="level3"><p> MeshCompoundShape and MeshCollisionShape are both mesh-accurate and are intended for immobile scene objects, such as terrains, buildings, or whole shooter levels. Limitation: Only collisions of non-mesh-accurate shapes (sphere, box, etc) shapes can be detected against mesh-accurate shapes.</p><pre>CompoundCollisionShape myComplexShape =
<tr> CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; myComplexGeometry &#41;;</pre><p> An angular, non-mesh-accurate compound shape:</p><pre>CompoundCollisionShape boxShape =
<td> CapsuleCollisionShape </td><td> A compound of a cylinder plus two spheres at the top and bottom. Rotated upright, this shape is optimal for character nodes: A cylinder-shaped body does not get stuck at corners and vertical obstacles; the rounded top and bottom do not get stuck on stair steps and ground obstacles. Is locked to stay upright, does not roll. </td> CollisionShapeFactory.createBoxCompoundShape&#40;&#40;Node&#41; someBox&#41;;</pre><p> SphereCollisionShape, BoxCollisionShape, CapsuleCollisionShape are also not mesh-accurate, but have better performance. The can be added to anything, and collisions between them and any other shape can be detected.</p><pre>SphereCollisionShape sphereShape =
</tr> new SphereCollisionShape&#40;1.0f&#41;;</pre></div><h2><a
<tr> name="physics_controls">Physics Controls</a></h2><div
<td> CompoundCollisionShape </td><td> A CompoundCollisionShape allows custom combinations of box/sphere/cylinder shapes to form another more complex shape. </td> class="level2"><p> Available PhysicsControls in the com.jme3.bullet.control package are:</p><div
</tr> class="table sectionedit2"><table
<tr> class="inline"><tr
<td> MeshCollisionShape </td><td> A free-form mesh-accurate shape that wraps itself around a mesh. <br/> class="row0"><th
<strong>Limitations:</strong> Only non-mesh collision shapes (sphere, box, cylinder, compound) can collide with mesh-accurate collision shapes. The Mesh Collision Shape only works for static obstacles, e.g. for a game level model. </td> class="col0">Physics Control</th><th
</tr> class="col1">Purpose</th></tr><tr
<tr> class="row1"><td
<td> GImpactCollisionShape </td><td> This free-form Mesh Collision Shape can be used for moving objects. Uses <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://gimpact.sourceforge.net/"><param name="text" value="<html><u>http://gimpact.sourceforge.net/</u></html>"><param name="textColor" value="blue"></object>. <strong>Limitations:</strong> CPU intensive, use sparingly! We recommend using HullCollisionShapes or CompoundShapes made of simple shapes if you need improved performance. </td> class="col0">RigidBodyControl</td><td
</tr> class="col1">Use for physical objects in the scene, e.g. projectiles and obstacles – things that are freely affected by physical forces, be it by collision or falling.</td></tr><tr
<tr> class="row2"><td
<td> HeightFieldCollisionShape </td><td> Optimized Mesh Collision Shape for static terrains. This shape is much faster than a other Free-Form Mesh Shapes. Requires heightmap data.</td> class="col0">CharacterControl</td><td
</tr> class="col1">Use for characters (persons, animals) that stand upright, orthogonally to the X/Z plane. When directional forces are applied to a CharacterControl&#039;ed Spatial, it does not tip over (as a RigidBodyControl&#039;ed Spatial would), but it moves upright (as a walking character would).</td></tr><tr
<tr> class="row3"><td
<td> HullCollisionShape </td><td> A collision shape that is based on a mesh but is a simplified convex version. </td> class="col0">GhostControl</td><td
</tr> class="col1">A GhostControl is a PhysicsControl that detects overlaps with other physical objects. A GhostControl is <em>non-solid</em> and moves with the Spatial it is attached to. Use this for game elements that do not have a visible solid Geometry: Aggro radius, motion detectors, photoelectric sensors, radioactive areas, life-draining ghosts, etc.</td></tr><tr
<tr> class="row4"><td
<td> SimplexCollisionShape </td><td>A physical point, line, triangle, or quad Collision Shape, defined by one to four points.</td> class="col0">VehicleControl <br/> PhysicsVehicleWheel</td><td
</tr> class="col1"> Implements <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/vehicles.html">terrestric vehicle</a> behaviour.</td></tr><tr
<td> PlaneCollisionShape </td><td> A 2D plane that can be used as flat solid floor or wall. </td> class="row5"><td
</tr> class="col0">RagDollControl</td><td
</table> class="col1"> Implements <a
href="/com/jme3/gde/core/docs/jme3/advanced/ragdoll.html">Ragdoll</a> behaviour.</td></tr></table></div><p> Bullet Physics are available in jME3 through a several classes. You will use PhysicsControls in 99% of the time.</p></div><h4><a
<p> name="bullet_physics_controls">Bullet Physics Controls</a></h4><div
class="level4"><p> PhysicsControls are the recommended way to use physics in a jME3 application. PhysicsControls are flexible and can be added to any Spatial to make it act according to physical properties. These Control classes directly extend Bullet Physics Objects.
Pick the right shape for the mesh for what you want to do: If you give a box a sphere collision shape, it will roll; if you give a ball a box collision shape, it will sit on a slope. Package: com.jme3.bullet.control</p></div><h4><a
</p> name="bullet_physics_objects">Bullet Physics Objects</a></h4><div
class="level4"><p> Physics Objects are mostly standard Bullet classes like RigidBody, GhostObject etc., that jME3&#039;s other classes are built upon. Advanced users can use these classes to create custom physics functions.
<p> Package: com.jme3.bullet.objects</p></div><h4><a
Let&#039;s look at the constructor: name="deprecated_bullet_physics_nodes">(Deprecated) Bullet Physics Nodes</a></h4><div
</p> class="level4"><p> <em>Physics Nodes have Bullet Controllers attached and wrap their methods to “simulate” the old physics nodes that were available before alpha-4. The setLocalTranslation/Rotation() info is transferred to the Bullet Objects for simplicity. </em> Do not use Physics Nodes, use PhysicsControls instead.
Package: com.jme3.bullet.nodes</p></div><h3><a
</div> name="physics_controls_code_samples">Physics Controls Code Samples</a></h3><div
class="level3"><p> The various Physics Control constructors expect a Collision Shape (here thingShape) and a mass (a float).</p><pre>RigidBodyControl myControl=new RigidBodyControl&#40; thingShape , 1.0f &#41;;</pre><p> To make the Physics Control visible in the scene, you must attach the Control to a Geometry (e.g. a model named myGeometry):</p><pre>myGeometry.addControl&#40;myControl&#41;;</pre><p> This code sample creates a physical Character:</p><pre>// Load a normal model
<h3><a>Collision Shape Code Samples</a></h3>
<div>
<p>
MeshCompoundShape and MeshCollisionShape are both mesh-accurate and are intended for immobile scene objects, such as terrains, buildings, or whole shooter levels. Limitation: Only collisions of non-mesh-accurate shapes (sphere, box, etc) shapes can be detected against mesh-accurate shapes.
</p>
<pre>CompoundCollisionShape myComplexShape =
CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; myComplexGeometry &#41;;</pre>
<p>
An angular, non-mesh-accurate compound shape:
</p>
<pre>CompoundCollisionShape boxShape =
CollisionShapeFactory.createBoxCompoundShape&#40;&#40;Node&#41; someBox&#41;;</pre>
<p>
SphereCollisionShape, BoxCollisionShape, CapsuleCollisionShape are also not mesh-accurate, but have better performance. The can be added to anything, and collisions between them and any other shape can be detected.
</p>
<pre>SphereCollisionShape sphereShape =
new SphereCollisionShape&#40;1.0f&#41;;</pre>
</div>
<h2><a>Physics Controls</a></h2>
<div>
<p>
Available PhysicsControls in the com.jme3.bullet.control package are:
</p>
<table>
<tr>
<th>Physics Control</th><th>Purpose</th>
</tr>
<tr>
<td>RigidBodyControl</td><td>Use for physical objects in the scene, e.g. projectiles and obstacles – things that are freely affected by physical forces, be it by collision or falling.</td>
</tr>
<tr>
<td>CharacterControl</td><td>Use for characters (persons, animals) that stand upright, orthogonally to the X/Z plane. When directional forces are applied to a CharacterControl&#039;ed Spatial, it does not tip over (as a RigidBodyControl&#039;ed Spatial would), but it moves upright (as a walking character would).</td>
</tr>
<tr>
<td>GhostControl</td><td>A GhostControl is a PhysicsControl that detects overlaps with other physical objects. A GhostControl is <em>non-solid</em> and moves with the Spatial it is attached to. Use this for game elements that do not have a visible solid Geometry: Aggro radius, motion detectors, photoelectric sensors, radioactive areas, life-draining ghosts, etc. </td>
</tr>
<tr>
<td>VehicleControl <br/>
PhysicsVehicleWheel</td><td> Implements <a href="/com/jme3/gde/core/docs/jme3/advanced/vehicles.html">terrestric vehicle</a> behaviour.</td>
</tr>
<tr>
<td>RagDollControl</td><td> Implements <a href="/com/jme3/gde/core/docs/jme3/advanced/ragdoll.html">Ragdoll</a> behaviour.</td>
</tr>
</table>
<p>
Bullet Physics are available in jME3 through a several classes. You will use PhysicsControls in 99% of the time.
</p>
</div>
<h4><a>Bullet Physics Controls</a></h4>
<div>
<p>
PhysicsControls are the recommended way to use physics in a jME3 application. PhysicsControls are flexible and can be added to any Spatial to make it act according to physical properties. These Control classes directly extend Bullet Physics Objects.
</p>
<p>
Package: com.jme3.bullet.control
</p>
</div>
<h4><a>Bullet Physics Objects</a></h4>
<div>
<p>
Physics Objects are mostly standard Bullet classes like RigidBody, GhostObject etc., that jME3&#039;s other classes are built upon. Advanced users can use these classes to create custom physics functions.
</p>
<p>
Package: com.jme3.bullet.objects
</p>
</div>
<h4><a>(Deprecated) Bullet Physics Nodes</a></h4>
<div>
<p>
<em>Physics Nodes have Bullet Controllers attached and wrap their methods to “simulate” the old physics nodes that were available before alpha-4. The setLocalTranslation/Rotation() info is transferred to the Bullet Objects for simplicity. </em> Do not use Physics Nodes, use PhysicsControls instead.
</p>
<p>
Package: com.jme3.bullet.nodes
</p>
</div>
<h3><a>Physics Controls Code Samples</a></h3>
<div>
<p>
The various Physics Control constructors expect a Collision Shape (here thingShape) and a mass (a float).
</p>
<pre>RigidBodyControl myControl=new RigidBodyControl&#40; thingShape , 1.0f &#41;;</pre>
<p>
To make the Physics Control visible in the scene, you must attach the Control to a Geometry (e.g. a model named myGeometry):
</p>
<pre>myGeometry.addControl&#40;myControl&#41;;</pre>
<p>
This code sample creates a physical Character:
</p>
<pre>// Load a normal model
Node model = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/myCharacterModel.mesh.xml&quot;&#41;; Node model = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/myCharacterModel.mesh.xml&quot;&#41;;
rootNode.attachChild&#40;model&#41;; rootNode.attachChild&#40;model&#41;;
// Create a appropriate physical shape for it // Create a appropriate physical shape for it
@ -308,264 +147,156 @@ CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape&#40;1.5f, 6f, 1&#
CharacterControl character_phys = new CharacterControl&#40;capsuleShape, 0.01f&#41;; CharacterControl character_phys = new CharacterControl&#40;capsuleShape, 0.01f&#41;;
// Attach physical properties to model and PhysicsSpace // Attach physical properties to model and PhysicsSpace
model.addControl&#40;character_phys&#41;; model.addControl&#40;character_phys&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;character_phys&#41;;</pre> bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;character_phys&#41;;</pre><p> Tip: Spheres and Boxes will fall back to their correct default Collision Shape if you don&#039;t specify a shape in the RigidBodyControl constructor. The following creates a box with Box Collision Shape:</p><pre>Box&#40;1,1,1&#41;;
<p>
Tip: Spheres and Boxes will fall back to their correct default Collision Shape if you don&#039;t specify a shape in the RigidBodyControl constructor. The following creates a box with Box Collision Shape:
</p>
<pre>Box&#40;1,1,1&#41;;
myBox.addControl&#40;new RigidBodyControl&#40; 1.0f &#41;&#41;; myBox.addControl&#40;new RigidBodyControl&#40; 1.0f &#41;&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;myBox&#41;;</pre> bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;myBox&#41;;</pre></div><h2><a
</div> name="physics_space">Physics Space</a></h2><div
class="level2"><p> The Physics Space is an object in BulletAppState that is like a rootNode for Physics Controls.</p><ol><li
<h2><a>Physics Space</a></h2> class="level1"><div
<div> class="li"> First specify parameters such as gravity and accuracy.<pre>bulletAppState.getPhysicsSpace&#40;&#41;.setGravity&#40;new Vector3f&#40;0f,-1f,0f&#41;&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.setAccuracy&#40;0.005f&#41;;</pre></div></li><li
<p> class="level1"><div
class="li"> Physics Controls must be added to the PhysicsSpace.<pre>bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;myPhysicsControl&#41;; ...</pre></div></li><li
The Physics Space is an object in BulletAppState that is like a rootNode for Physics Controls. class="level1"><div
</p> class="li"> Physics Control must be added to their Spatial.<pre>myModel.addControl&#40;myPhysicsControl&#41;; ...</pre></div></li><li
<ol> class="level1"><div
<li><div> First specify parameters such as gravity and accuracy.<pre>bulletAppState.getPhysicsSpace&#40;&#41;.setGravity&#40;new Vector3f&#40;0f,-1f,0f&#41;&#41;; class="li"> The Spatial must be attached to the rootNode, as always.<pre>rootNode.attachChild&#40;myModel&#41;; ...</pre></div></li><li
bulletAppState.getPhysicsSpace&#40;&#41;.setAccuracy&#40;0.005f&#41;;</pre></div> class="level1"><div
</li> class="li"> You remove physical objects from the scene like this:<pre>bulletAppState.getPhysicsSpace&#40;&#41;.remove&#40;myPhysicsControl&#41;;
<li><div> Physics Controls must be added to the PhysicsSpace.<pre>bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;myPhysicsControl&#41;; ...</pre></div> myModel.removeFromParent&#40;&#41;;</pre></div></li></ol></div><h2><a
</li> name="properties_of_physical_objects">Properties of Physical Objects</a></h2><div
<li><div> Physics Control must be added to their Spatial. <pre>myModel.addControl&#40;myPhysicsControl&#41;; ...</pre></div> class="level2"><p> On a PhysicsControl, you can set the following physical properties.</p><div
</li> class="table sectionedit3"><table
<li><div> The Spatial must be attached to the rootNode, as always. <pre>rootNode.attachChild&#40;myModel&#41;; ...</pre></div> class="inline"><tr
</li> class="row0"><th
<li><div> You remove physical objects from the scene like this: <pre>bulletAppState.getPhysicsSpace&#40;&#41;.remove&#40;myPhysicsControl&#41;; class="col0"> RigidBodyControl Method</th><th
myModel.removeFromParent&#40;&#41;;</pre></div> class="col1"> Property</th></tr><tr
</li> class="row1"><td
</ol> class="col0"> setFriction(1f)</td><td
class="col1"> Friction.</td></tr><tr
</div> class="row2"><td
class="col0"> setMass(1f)</td><td
<h2><a>Properties of Physical Objects</a></h2> class="col1"> Sets the mass. Dynamic objects have masses &gt; 0.0f. <br/> Static immobile obstacles (including buildings and terrains) have mass 0.0f.</td></tr><tr
<div> class="row3"><td
class="col0"> setPhysicsLocation()</td><td
<p> class="col1">Positions the object. Do not use setLocalTranslation().</td></tr><tr
class="row4"><td
On a PhysicsControl, you can set the following physical properties. class="col0"> setPhysicsRotation()</td><td
class="col1">Rotates the object. Do not use setLocalRotate().</td></tr><tr
</p> class="row5"><td
<table> class="col0"> setRestitution(0.0f)</td><td
<tr> class="col1"> How bouncy the object is. For a rubber object set this &gt; 0.0f. This setting has an impact on performance.</td></tr><tr
<th> RigidBodyControl Method </th><th> Property </th> class="row6"><td
</tr> class="col0"> setKinematic(true)</td><td
<tr> class="col1"> A kinematic node is not affected by gravity, but it is solid and affects other physics objects. It has a mass its position is updated from the spatials translation. You can attach joints to it.</td></tr><tr
<td> setFriction(1f) </td><td> Friction. </td> class="row7"><td
</tr> class="col0"> setGravity(new Vector3f(0f,-1f,0f))</td><td
<tr> class="col1"> You can change the gravity of a physics object after it was added to the physics space.</td></tr><tr
<td> setMass(1f) </td><td> Sets the mass. Dynamic objects have masses &gt; 0.0f. <br/> class="row8"><td
Static immobile obstacles (including buildings and terrains) have mass 0.0f. </td> class="col0"> setCcdMotionThreshold(0.1f)</td><td
</tr> class="col1"> The amount of motion in 1 physics tick to trigger the continuous motion detection.</td></tr><tr
<tr> class="row9"><th
<td> setPhysicsLocation()</td><td>Positions the object. Do not use setLocalTranslation().</td> class="col0"> CharacterControl Method</th><th
</tr> class="col1"> Property</th></tr><tr
<tr> class="row10"><td
<td> setPhysicsRotation()</td><td>Rotates the object. Do not use setLocalRotate().</td> class="col0"> setFallSpeed(1f)</td><td
</tr> class="col1"> Fall speed (down)</td></tr><tr
<tr> class="row11"><td
<td> setRestitution(0.0f) </td><td> How bouncy the object is. For a rubber object set this &gt; 0.0f. This setting has an impact on performance. </td> class="col0"> setJumpSpeed(1f)</td><td
</tr> class="col1"> Jump speed (up)</td></tr><tr
<tr> class="row12"><td
<td> setKinematic(true) </td><td> A kinematic node is not affected by gravity, but it is solid and affects other physics objects. It has a mass its position is updated from the spatials translation. You can attach joints to it. </td> class="col0 leftalign"> setMaxSlope(1.5f)</td><td
</tr> class="col1"> How steep the slopes are that the character can still climb.</td></tr><tr
<tr> class="row13"><td
<td> setGravity(new Vector3f(0f,-1f,0f)) </td><td> You can change the gravity of a physics object after it was added to the physics space. </td> class="col0"> setUpAxis(1)</td><td
</tr> class="col1"> 0 = X axis , 1 = Y axis , 2 = Z axis. E.g. for characters and vehicle, up is usually along the the Y axis.</td></tr><tr
<tr> class="row14"><td
<td> setCcdMotionThreshold(0.1f) </td><td> The amount of motion in 1 physics tick to trigger the continuous motion detection. </td> class="col0 leftalign"> setGravity(1f)</td><td
</tr> class="col1"> You can change the Gravity of a physics object after it was added to the physics space</td></tr></table></div></div><h3><a
</table> name="kinematic_vs_dynamic_vs_static">Kinematic vs Dynamic vs Static</a></h3><div
<table> class="level3"><p> Physical objects…</p><ul><li
<tr> class="level1"><div
<th> CharacterControl Method </th><th> Property </th> class="li"> must not overlap.</div></li><li
</tr> class="level1"><div
<tr> class="li"> can detect collisions and report several values about the impact.</div></li><li
<td> setFallSpeed(1f) </td><td> Fall speed (down) </td> class="level1"><div
</tr> class="li"> can respond dynamically or statically or kinematically to collisions.</div></li></ul></div><h4><a
<tr> name="dynamic">Dynamic</a></h4><div
<td> setJumpSpeed(1f) </td><td> Jump speed (up) </td> class="level4"><p> A dynamic physics object is one that falls when in mid-air, it bounces off obstacles, and is pushed around when it collides with another physical object. It has a mass.</p></div><h4><a
</tr> name="static">Static</a></h4><div
<tr> class="level4"><p> You can create static physical objects without mass. They are still treated as solid objects, but they cannot be dynamically pushed around. They act as static, immobile attached physical obstacles such as terrains and building models.</p></div><h4><a
<td> setMaxSlope(1.5f) </td><td> How steep the slopes are that the character can still climb. </td> name="kinematic">Kinematic</a></h4><div
</tr> class="level4"><p> Kinematic RigidBodys have a mass, but they are not affected by gravity. When non-kinematic objects collide with a kinematic object, only the non-kinematic ones are pushed away by the collision. The intesity of the kinematic&#039;s effect against other objects depends on their speed and mass: <code>E<sub>kin</sub> = mass * speed^2</code> (well, approximately, bullet doesn&#039;t use Einsteins formula ;)) <strong>Tip:</strong> Spatials with a kinematic RigidBodyControl can be moved programmatically, e.g. using setLocalTranslation() in the update() loop, or by an Animation Path. You can also &quot;hang them up in mid-air&quot; and attach other PhysicsNodes to them using <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">hinges and joints</a>.</p><pre>airhook.setKinematic&#40;true&#41;;</pre></div><h2><a
<td> setUpAxis(1)</td><td> 0 = X axis , 1 = Y axis , 2 = Z axis. E.g. for characters and vehicle, up is usually along the the Y axis. </td> name="forcesmoving_physical_objects">Forces: Moving Physical Objects</a></h2><div
</tr> class="level2"><p> Use the following methods to move physics objects.</p><div
<tr> class="table sectionedit4"><table
<td> setGravity(1f) </td><td> You can change the Gravity of a physics object after it was added to the physics space</td> class="inline"><tr
</tr> class="row0"><th
</table> class="col0"> Method</th><th
class="col1"> Motion</th></tr><tr
</div> class="row1"><td
class="col0"> setAngularVelocity(new Vector3f(0f,0f,1f))</td><td
<h3><a>Kinematic vs Dynamic vs Static</a></h3> class="col1"> Set the current rotational speed of the object; the x, y and z component are the speed of rotation around that axis.</td></tr><tr
<div> class="row2"><td
class="col0"> setLinearVelocity(new Vector3f(0f,0f,1f)) </td><td
<p> class="col1"> Set the current linear speed of this object</td></tr><tr
class="row3"><td
Physical objects… class="col0"> setWalkDirection(new Vector3f(0f,0f,0.1f))</td><td
</p> class="col1"> Make a physical character walk (characters are locked to prevent falling over and use a simple physics simulation). Use <code>setWalkDirection(Vector3f.ZERO)</code> to stop a directional motion.</td></tr><tr
<ul> class="row4"><td
<li><div> must not overlap. </div> class="col0"> applyCentralForce(…)</td><td
</li> class="col1 leftalign"> Move (push) the object once with a certain moment, expressed as a Vector3f.</td></tr><tr
<li><div> can detect collisions and report several values about the impact. </div> class="row5"><td
</li> class="col0"> applyForce(…)</td><td
<li><div> can respond dynamically or statically or kinematically to collisions.</div> class="col1"> Move (push) the object once with a certain moment, expressed as a Vector3f. Optionally, you can specify where on the object the pushing force hits.</td></tr><tr
</li> class="row6"><td
</ul> class="col0"> applyContinuousForce(…)</td><td
class="col1"> Keep moving (pushing) the object with continuous force in one direction, expressed as a Vector3f. Optionally, you can specifiy where on the object the pushing force hits. You can <code>applyContinuousForce(false)</code> to stop the force.</td></tr><tr
</div> class="row7"><td
class="col0"> applyTorque(…)</td><td
<h4><a>Dynamic</a></h4> class="col1"> Rotate (twist) the object once around its axes, expressed as a Vector3f.</td></tr><tr
<div> class="row8"><td
class="col0"> applyContinuousTorque(…)</td><td
<p> class="col1"> Keep rotating (twisting) the object continuously around its axes, expressed as a Vector3f. You can <code>applyContinuousTorque(false)</code> to stop the rotation.</td></tr><tr
class="row9"><td
A dynamic physics object is one that falls when in mid-air, it bounces off obstacles, and is pushed around when it collides with another physical object. It has a mass. class="col0"> applyImpulse(…)</td><td
</p> class="col1"> An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball.</td></tr><tr
class="row10"><td
</div> class="col0"> applyTorqueImpulse(…)</td><td
class="col1"> An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball.</td></tr><tr
<h4><a>Static</a></h4> class="row11"><td
<div> class="col0">clearForces()</td><td
class="col1">Cancels out all forces (force, torque) etc and stops the motion.</td></tr></table></div><p> <strong>Note:</strong> It is possible to position physics nodes using setLocalTranslation(), e.g. to place them in their start position in the scene. However you must be very careful not to cause an &quot;impossible state&quot; where one physical object overlaps with another! Within the game, you typically use the setters shown here exclusively.
<p> Physics also supports the following features:</p><div
class="table sectionedit5"><table
You can create static physical objects without mass. They are still treated as solid objects, but they cannot be dynamically pushed around. They act as static, immobile attached physical obstacles such as terrains and building models. class="inline"><tr
</p> class="row0"><th
class="col0"> Method</th><th
</div> class="col1"> Property</th></tr><tr
class="row1"><td
<h4><a>Kinematic</a></h4> class="col0"> setCollisionShape(collisionShape)</td><td
<div> class="col1">Changes the collision shape.</td></tr><tr
class="row2"><td
<p> class="col0"> setCollideWithGroups() <br/> setCollisionGroup() <br/> addCollideWithGroup(COLLISION_GROUP_01) <br/> removeCollideWithGroup(COLLISION_GROUP_01)</td><td
class="col1">Collision Groups are integer bit masks – enums are available in CollisionObject. All physics objects are by default in COLLISION_GROUP_01. Two objects collide when the collideWithGroups set of one contains the collisionGroup of the other.</td></tr><tr
Kinematic RigidBodys have a mass, but they are not affected by gravity. When non-kinematic objects collide with a kinematic object, only the non-kinematic ones are pushed away by the collision. The intesity of the kinematic&#039;s effect against other objects depends on their speed and mass: class="row3"><td
</p> class="col0"> setDamping(float, float)</td><td
class="col1">The first value is the linear threshold and the second the angular.</td></tr><tr
<p> class="row4"><td
<code>E<sub>kin</sub> = mass * speed^2</code> (well, approximately, bullet doesn&#039;t use Einsteins formula ;)) class="col0"> setAngularFactor(1f)</td><td
</p> class="col1">Set the amount of rotation that will be applied. A value of zero will cancel all rotational force outcome.</td></tr><tr
class="row5"><td
<p> class="col0"> setCcdSweptSphereRadius()</td><td
<strong>Tip:</strong> Spatials with a kinematic RigidBodyControl can be moved programmatically, e.g. using setLocalTranslation() in the update() loop, or by an Animation Path. You can also “hang them up in mid-air” and attach other PhysicsNodes to them using <a href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">hinges and joints</a>. class="col1">?</td></tr><tr
</p> class="row6"><td
<pre>airhook.setKinematic&#40;true&#41;;</pre> class="col0"> setSleepingThreshold(float,float)</td><td
</div> class="col1">Sets the sleeping thresholds wich define when the object gets deactivated to save ressources. Low values keep the object active when it barely moves. The first value is the linear threshold and the second the angular.</td></tr></table></div></div><h2><a
name="best_practices">Best Practices</a></h2><div
<h2><a>Forces: Moving Physical Objects</a></h2> class="level2"><p> You can control the game by triggering forces; or may want to respond to collisions, e.g. by substracting health points, or by playing a sound. To specify how the game responds to physics events, you use <a
<div> href="/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html">Physics Listeners</a>.
<p>
Use the following methods to move physics objects.
</p>
<table>
<tr>
<th> Method </th><th> Motion </th>
</tr>
<tr>
<td> setAngularVelocity(new Vector3f(0f,0f,1f)) </td><td> Set the current rotational speed of the object </td>
</tr>
<tr>
<td> setLinearVelocity(new Vector3f(0f,0f,1f)) </td><td> Set the current linear speed of this object </td>
</tr>
<tr>
<td> setWalkDirection(new Vector3f(0f,0f,0.1f))</td><td> Make a physical character walk (characters are locked to prevent falling over and use a simple physics simulation). Use <code>setWalkDirection(Vector3f.ZERO)</code> to stop a directional motion. </td>
</tr>
<tr>
<td> applyCentralForce(…) </td><td> Move (push) the object once with a certain moment, expressed as a Vector3f. </td>
</tr>
<tr>
<td> applyForce(…) </td><td> Move (push) the object once with a certain moment, expressed as a Vector3f. Optionally, you can specify where on the object the pushing force hits. </td>
</tr>
<tr>
<td> applyContinuousForce(…) </td><td> Keep moving (pushing) the object with continuous force in one direction, expressed as a Vector3f. Optionally, you can specifiy where on the object the pushing force hits. You can <code>applyContinuousForce(false)</code> to stop the force. </td>
</tr>
<tr>
<td> applyTorque(…) </td><td> Rotate (twist) the object once around its axes, expressed as a Vector3f. </td>
</tr>
<tr>
<td> applyContinuousTorque(…) </td><td> Keep rotating (twisting) the object continuously around its axes, expressed as a Vector3f. You can <code>applyContinuousTorque(false)</code> to stop the rotation.</td>
</tr>
<tr>
<td> applyImpulse(…) </td><td> An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball. </td>
</tr>
<tr>
<td> applyTorqueImpulse(…) </td><td> An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball. </td>
</tr>
<tr>
<td>clearForces()</td><td>Cancels out all forces (force, torque) etc and stops the motion.</td>
</tr>
</table>
<p>
<strong>Note:</strong> It is possible to position physics nodes using setLocalTranslation(), e.g. to place them in their start position in the scene. However you must be very careful not to cause an “impossible state” where one physical object overlaps with another! Within the game, you typically use the setters shown here exclusively.
</p>
<p>
Physics also supports the following features:
</p>
<table>
<tr>
<th> Method </th><th> Property </th>
</tr>
<tr>
<td> setCollisionShape(collisionShape)</td><td>Changes the collision shape.</td>
</tr>
<tr>
<td> setCollideWithGroups() <br/>
setCollisionGroup() <br/>
addCollideWithGroup(COLLISION_GROUP_01) <br/>
removeCollideWithGroup(COLLISION_GROUP_01)</td><td>Collision Groups are integer bit masks – enums are available in CollisionObject. All physics objects are by default in COLLISION_GROUP_01. Two objects collide when the collideWithGroups set of one contains the collisionGroup of the other.</td>
</tr>
<tr>
<td> setDamping(float, float)</td><td>The first value is the linear threshold and the second the angular.</td>
</tr>
<tr>
<td> setAngularFactor(1f)</td><td>Set the amount of rotation that will be applied. A value of zero will cancel all rotational force outcome.</td>
</tr>
<tr>
<td> setCcdSweptSphereRadius()</td><td>?</td>
</tr>
<tr>
<td> setSleepingThreshold(float,float)</td><td>Sets the sleeping thresholds wich define when the object gets deactivated to save ressources. Low values keep the object active when it barely moves. The first value is the linear threshold and the second the angular.</td>
</tr>
</table>
</div>
<h2><a>Best Practices</a></h2>
<div>
<p>
You can control the game by triggering forces; or may want to respond to collisions, e.g. by substracting health points, or by playing a sound. To specify how the game responds to physics events, you use <a href="/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html">Physics Listeners</a>.
</p>
<p>
Do not overuse physics nodes. Although the physics nodes are put to “sleep” when they are not moved, creating a world solely out of dynamic physics nodes will quickly bring you to the limits of your computer&#039;s capabilities. Do not overuse physics nodes. Although the physics nodes are put to “sleep” when they are not moved, creating a world solely out of dynamic physics nodes will quickly bring you to the limits of your computer&#039;s capabilities.
</p>
<p>
You can use normal non-physical Nodes in the same scene next to physical ones. Use the non-physical ones for non-solid things for which you do not want to detect collisions (ghost, foliage, plants, effects, …). This improves performance. You can use normal non-physical Nodes in the same scene next to physical ones. Use the non-physical ones for non-solid things for which you do not want to detect collisions (ghost, foliage, plants, effects, …). This improves performance.
</p>
<p>
If you get weird behaviour, such as physical nodes jittering wildy and being ejected for no apparent reason, it usually means you have created an impossible state. Verify that none of the collision shapes overlap. This can happen when you create physical nodes in positions that are too close to other nodes; or if you position a physical node using setLocalTranslation() and it touches another node&#039;s collision shape. If you get weird behaviour, such as physical nodes jittering wildy and being ejected for no apparent reason, it usually means you have created an impossible state. Verify that none of the collision shapes overlap. This can happen when you create physical nodes in positions that are too close to other nodes; or if you position a physical node using setLocalTranslation() and it touches another node&#039;s collision shape.
</p> For large static meshes like shooter levels or terrain its best to divide the mesh into multiple physics objects to allow the less cpu intense broadphase to filter out most collision items.</p></div>
<p>
For large static meshes like shooter levels or terrain its best to divide the mesh into multiple physics objects to allow the less cpu intense broadphase to filter out most collision items.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics?do=export_xhtmlbody">view online version</a></em></p>

@ -1,121 +1,47 @@
<h1><a
<h1><a>Physics Listeners</a></h1> name="physics_listeners">Physics Listeners</a></h1><div
<div> class="level1"><p> You can control physical objects by triggering forces. Or maybe you want to respond to collisions, e.g. by substracting health points, or by playing a sound. To specify how the game responds to such physics events, you use Physics Listeners.</p></div><h2><a
name="physics_tick_listener">Physics Tick Listener</a></h2><div
<p> class="level2"><p> The jBullet Physics implementation is stepped at a constant 60 physics ticks per second frame rate.
Applying forces or checking for overlaps only has an effect right at a physics update cycle, which is not every frame. If you do physics interactions at arbitrary spots in the simpleUpdate() loop, calls will be dropped at irregular intervals, because they happen out of cycle.</p></div><h3><a
You can control physical objects by triggering forces. Or maybe you want to respond to collisions, e.g. by substracting health points, or by playing a sound. To specify how the game responds to such physics events, you use Physics Listeners. name="when_not_to_use_tick_listener">When (Not) to Use Tick Listener?</a></h3><div
</p> class="level3"><p> When you write game mechanics that apply forces, you must implement a tick listener (com.jme3.bullet.PhysicsTickListener) for it. The tick listener makes certain the forces are not dropped, but applied in time for the next physics tick.
</div>
<h2><a>Physics Tick Listener</a></h2>
<div>
<p>
The jBullet Physics implementation is stepped at a constant 60 physics ticks per second frame rate.
Applying forces or checking for overlaps only has an effect right at a physics update cycle, which is not every frame. If you do physics interactions at arbitrary spots in the simpleUpdate() loop, calls will be dropped at irregular intervals, because they happen out of cycle.
</p>
</div>
<h3><a>When (Not) to Use Tick Listener?</a></h3>
<div>
<p>
When you write game mechanics that apply forces, you must implement a tick listener (com.jme3.bullet.PhysicsTickListener) for it. The tick listener makes certain the forces are not dropped, but applied in time for the next physics tick.
</p>
<p>
Also, when you check for overlaps of physical objects with a PhysicsGhostObject, you cannot just go <code>physicsSpace.add(ghost); ghost.getOverLappingObjects()</code> somewhere. You have to make certain 1 physics tick has passed before the overlapping objects list is filled with data. Again, the PhysicsTickListener does that for you. Also, when you check for overlaps of physical objects with a PhysicsGhostObject, you cannot just go <code>physicsSpace.add(ghost); ghost.getOverLappingObjects()</code> somewhere. You have to make certain 1 physics tick has passed before the overlapping objects list is filled with data. Again, the PhysicsTickListener does that for you.
</p> When your game mechanics however just poll the current state (e.g. location) of physical objects, or if you only use the Ghost control like a sphere trigger, then you don&#039;t need a PhysicsTickListener.</p></div><h3><a
name="how_to_listen_to_physics_ticks">How to Listen to Physics Ticks</a></h3><div
<p> class="level3"><p> Here&#039;s is the declaration of an examplary Physics Control that listens to ticks.</p><pre>public class MyCustomControl
When your game mechanics however just poll the current state (e.g. location) of physical objects, or if you only use the Ghost control like a sphere trigger, then you don&#039;t need a PhysicsTickListener. extends RigidBodyControl implements PhysicsTickListener &#123; ... &#125;</pre><p> When you implement the interface, you have to implement preTick() and postTick() methods.</p><ul><li
</p> class="level1"><div
class="li"> <code>prePhysicsTick()</code> is called before the step, here you apply forces (change the state).</div></li><li
</div> class="level1"><div
class="li"> <code>physicsTick()</code> is called after the step, here you poll the results (get the current state).</div></li></ul><pre>@override
<h3><a>How to Listen to Physics Ticks</a></h3>
<div>
<p>
Here&#039;s is the declaration of an examplary Physics Control that listens to ticks.
</p>
<pre>public class MyCustomControl
extends RigidBodyControl implements PhysicsTickListener &#123; ... &#125;</pre>
<p>
When you implement the interface, you have to implement preTick() and postTick() methods.
</p>
<ul>
<li><div> <code>prePhysicsTick()</code> is called before the step, here you apply forces (change the state).</div>
</li>
<li><div> <code>physicsTick()</code> is called after the step, here you poll the results (get the current state).</div>
</li>
</ul>
<pre>@override
public void prePhysicsTick&#40;PhysicsSpace space, float f&#41;&#123; public void prePhysicsTick&#40;PhysicsSpace space, float f&#41;&#123;
// apply state changes ... // apply state changes ...
&#125; &#125;
@override @override
public void physicsTick&#40;PhysicsSpace space, float f&#41;&#123; public void physicsTick&#40;PhysicsSpace space, float f&#41;&#123;
// poll game state ... // poll game state ...
&#125;</pre> &#125;</pre></div><h2><a
</div> name="physics_collision_listener">Physics Collision Listener</a></h2><div
class="level2"></div><h3><a
<h2><a>Physics Collision Listener</a></h2> name="when_not_to_use_collision_listener">When (Not) to Use Collision Listener</a></h3><div
<div> class="level3"><p> If you do not implement the Collision Listener interface (com.jme3.bullet.collision.PhysicsCollisionListener), a collisions will just mean that physical forces are applied automatically. If you just want &quot;Balls rolling, bricks falling&quot; you do not need a listener.
If however you want to respond to a collision event (com.jme3.bullet.collision.PhysicsCollisionEvent) with a custom action, then you need to implement the PhysicsCollisionListener interface. Typical actions triggered by collisions include:</p><ul><li
</div> class="level1"><div
class="li"> Increasing a counter (e.g. score points)</div></li><li
<h3><a>When (Not) to Use Collision Listener</a></h3> class="level1"><div
<div> class="li"> Decreasing a counter (e.g. health points)</div></li><li
class="level1"><div
<p> class="li"> Triggering an effect (e.g. explosion)</div></li><li
class="level1"><div
If you do not implement the Collision Listener interface (com.jme3.bullet.collision.PhysicsCollisionListener), a collisions will just mean that physical forces are applied automatically. If you just want “Balls rolling, bricks falling” you do not need a listener. class="li"> Playing a sound (e.g. explosion, ouch)</div></li><li
</p> class="level1"><div
class="li"> … and countless more, depending on your game</div></li></ul></div><h3><a
<p> name="how_to_listen_to_collisions">How to Listen to Collisions</a></h3><div
If however you want to respond to a collision event (com.jme3.bullet.collision.PhysicsCollisionEvent) with a custom action, then you need to implement the PhysicsCollisionListener interface. Typical actions triggered by collisions include: class="level3"><p> Again, here&#039;s the example declaration of a Physics Control that uses a collision listener.</p><pre>public class MyCustomControl
</p>
<ul>
<li><div> Increasing a counter (e.g. score points)</div>
</li>
<li><div> Decreasing a counter (e.g. health points)</div>
</li>
<li><div> Triggering an effect (e.g. explosion)</div>
</li>
<li><div> Playing a sound (e.g. explosion, ouch) </div>
</li>
<li><div> … and countless more, depending on your game</div>
</li>
</ul>
</div>
<h3><a>How to Listen to Collisions</a></h3>
<div>
<p>
Again, here&#039;s the example declaration of a Physics Control that uses a collision listener.
</p>
<pre>public class MyCustomControl
extends RigidBodyControl extends RigidBodyControl
implements PhysicsCollisionListener &#123; ... &#125;</pre> implements PhysicsCollisionListener &#123; ... &#125;</pre><p> To respond to the PhysicsCollisionEvent you have to override the <code>collision()</code> method. This gives you access to the event object. Mostly you will be interested in the identity of any two nodes that collided: <code>event.getNodeA()</code> and <code>event.getNodeB()</code>.
<p> After you identify the colliding nodes, specify the action to trigger when this pair collides. Note that you cannot know which one will be Node A or Node B, you have to deal with either variant.</p><pre> public void collision&#40;PhysicsCollisionEvent event&#41; &#123;
To respond to the PhysicsCollisionEvent you have to override the <code>collision()</code> method. This gives you access to the event object. Mostly you will be interested in the identity of any two nodes that collided: <code>event.getNodeA()</code> and <code>event.getNodeB()</code>.
</p>
<p>
After you identify the colliding nodes, specify the action to trigger when this pair collides. Note that you cannot know which one will be Node A or Node B, you have to deal with either variant.
</p>
<pre> public void collision&#40;PhysicsCollisionEvent event&#41; &#123;
if &#40; event.getNodeA&#40;&#41;.getName&#40;&#41;.equals&#40;&quot;player&quot;&#41; &#41; &#123; if &#40; event.getNodeA&#40;&#41;.getName&#40;&#41;.equals&#40;&quot;player&quot;&#41; &#41; &#123;
final Node node = event.getNodeA&#40;&#41;; final Node node = event.getNodeA&#40;&#41;;
/** ... do something with the node ... */ /** ... do something with the node ... */
@ -123,52 +49,31 @@ After you identify the colliding nodes, specify the action to trigger when this
final Node node = event.getNodeB&#40;&#41;; final Node node = event.getNodeB&#40;&#41;;
/** ... do something with the node ... */ /** ... do something with the node ... */
&#125; &#125;
&#125;</pre> &#125;</pre><p><p><div
<p> class="noteimportant">Note that after the collision() method ends, the PhysicsCollisionEvent is cleared. You must get all objects and values you need within the collision() method.</div></p></p></div><h3><a
<p><div>Note that after the collision() method ends, the PhysicsCollisionEvent is cleared. You must get all objects and values you need within the collision() method. name="reading_details_from_a_physicscollisionevent">Reading Details From a PhysicsCollisionEvent</a></h3><div
</div></p> class="level3"><p> The PhysicsCollisionEvent <code>event</code> gives you access to detailed information about the collision. You already know the event objects can identify which nodes collided, but it even knows how hard they collided:</p><div
</p> class="table sectionedit1"><table
class="inline"><tr
</div> class="row0"><th
class="col0 leftalign">Method</th><th
<h3><a>Reading Details From a PhysicsCollisionEvent</a></h3> class="col1">Purpose</th></tr><tr
<div> class="row1"><td
class="col0 leftalign"> getObjectA() <br/> getObjectB()</td><td
<p> class="col1"> The two participants in the collision. You cannot know in advance whether some node will be recorded as A or B, you always have to consider both cases.</td></tr><tr
class="row2"><td
The PhysicsCollisionEvent <code>event</code> gives you access to detailed information about the collision. You already know the event objects can identify which nodes collided, but it even knows how hard they collided: class="col0 leftalign"> getAppliedImpulse()</td><td
class="col1"> A float value representing the collision impulse</td></tr><tr
</p> class="row3"><td
<table> class="col0 leftalign"> getAppliedImpulseLateral1()</td><td
<tr> class="col1"> A float value representing the lateral collision impulse</td></tr><tr
<th>Method </th><th>Purpose</th> class="row4"><td
</tr> class="col0 leftalign"> getAppliedImpulseLateral2()</td><td
<tr> class="col1"> A float value representing the lateral collision impulse</td></tr><tr
<td> getNodeA() <br/> class="row5"><td
getNodeB() </td><td> The two participants in the collision. You cannot know in advance whether some node will be recorded as A or B, you always have to consider both cases. </td> class="col0 leftalign"> getCombinedFriction()</td><td
</tr> class="col1"> A float value representing the collision friction</td></tr><tr
<tr> class="row6"><td
<td> getAppliedImpulse() </td><td> A float value representing the collision impulse </td> class="col0 leftalign"> getCombinedRestitution()</td><td
</tr> class="col1"> A float value representing the collision restitution (bounciness)</td></tr></table></div><p> Note that after the collision method has been called the object is not valid anymore so you should copy any data you want to keep into local variables.</p></div>
<tr>
<td> getAppliedImpulseLateral1() </td><td> A float value representing the lateral collision impulse </td>
</tr>
<tr>
<td> getAppliedImpulseLateral2() </td><td> A float value representing the lateral collision impulse </td>
</tr>
<tr>
<td> getCombinedFriction() </td><td> A float value representing the collision friction </td>
</tr>
<tr>
<td> getCombinedRestitution() </td><td> A float value representing the collision restitution (bounciness) </td>
</tr>
</table>
<p>
Note that after the collision method has been called the object is not valid anymore so you should copy any data you want to keep into local variables.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics_listeners?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:physics_listeners?do=export_xhtmlbody">view online version</a></em></p>

@ -1,89 +1,24 @@
<h1><a
<h1><a>Rendering Water as Post-Process Effect</a></h1> name="rendering_water_as_post-process_effect">Rendering Water as Post-Process Effect</a></h1><div
<div> class="level1"><p> This awesome water effect is highly configurable and can render any type of water. It is is based on <a
href="http://www.gamedev.net/page/reference/index.html/_//feature/fprogramming/rendering-water-as-a-post-process-effect-r2642">Wojciech Toman’s Rendering Water as a Post-process Effect</a> published on gamedev.net. Here&#039;s a video:</p><p> <a
<p> href="http://www.youtube.com/watch?v=AWlUzgRN3Pc"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water-post.png" class="mediacenter" alt="" /></a></p></div><h2><a
This awesome water effect is highly configurable and can render any type of water. It is is based on <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.gamedev.net/page/reference/index.html/_//feature/fprogramming/rendering-water-as-a-post-process-effect-r2642"><param name="text" value="<html><u>Wojciech Toman’s Rendering Water as a Post-process Effect</u></html>"><param name="textColor" value="blue"></object> published on gamedev.net. Here&#039;s a video: name="the_theory">The Theory</a></h2><div
</p> class="level2"><p> In this article the author uses the effect in a deferred rendering process, taking advantage of the pre-computed position buffer and back buffer (a texture representing the screen’s pixels position in view space, and a texture of the rendered scene).</p><p> After some calculation this allows to reconstruct the position in world space for each pixel on the screen. If a pixel is under a given water height, let’s render it as a blue pixel! Blue pixel? Not exactly, we want waves, we want ripples, we want foam, we want reflection and refraction.</p><p> The GameDev.net article describes how those effects are achieved, but the main idea is to generate waves from a height map, create ripples from a normal map, blend in the foam texture when the water depth is below a certain height, compute the refraction color with a clever color extinction algorithm, and then, display the reflection and specular effect by computing a Fresnel term (like in standard water effect). In addition this effect, allow to blend the water shore with the ground to avoid the hard edges effect of classic water effects based on grids or quads.</p></div><h2><a
name="how_did_we_implement_it_in_jme3">How Did We Implement it in jME3?</a></h2><div
<p> class="level2"><p> jME3 default behavior is to use a forward rendering process, so there is no position buffer rendered that we can take advantage of. But while rendering the main scene to a frame buffer in the FilterPostPorcessor, we can write the hardware depth buffer to a texture, with nearly no additional cost.</p><p> I won’t go into the details of this, but there are several ways of reconstructing the world space position of a pixel from the depth buffer. The computational cost is higher than just fetching the position form a position buffer, but the bandwidth and the memory required is a lot lower.</p><p> We have the rendered scene in a texture, and we can reconstruct the position in world space of each pixel… We’re good to go!</p><p> See also: <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.youtube.com/watch?v=AWlUzgRN3Pc"><param name="text" value="<html><u>http://www.youtube.com/watch?v=AWlUzgRN3Pc</u></html>"><param name="textColor" value="blue"></object> href="http://jmonkeyengine.org/2011/01/15/new-advanced-water-effect-for-jmonkeyengine-3/#comment-609">JME3&#039;s Water Post-Process Effect</a> by Nehon</p></div><h2><a
</p> name="sample_code">Sample Code</a></h2><div
class="level2"><p> There are two test cases in the jME3 repository:</p><ul><li
</div> class="level1"><div
class="li"> <a
<h2><a>The Theory</a></h2> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWater.java">jme3/src/test/jme3test/water/TestPostWater.java</a> (ocean island)</div></li></ul><ul><li
<div> class="level1"><div
class="li"> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWaterLake.java">jme3/src/test/jme3test/water/TestPostWaterLake.java</a> (calm and muddy water pond)</div></li></ul></div><h3><a
name="using_the_water_filter">Using the Water Filter</a></h3><div
In this article the author uses the effect in a deferred rendering process, taking advantage of the pre-computed position buffer and back buffer (a texture representing the screen’s pixels position in view space, and a texture of the rendered scene). class="level3"><p> In the <code>simpleInitApp()</code> method, you attach your scene to the rootNode, typically a terrain with a sky. Remember to add a directional light, since the water relies on the light direction vector. The WaterFilter constrcutor expects a node with the scene attached that should be reflected in the water, and vector information from the light source&#039;s direction.</p><p> This is how you use the water filter post-processor code in your code:</p><pre>private FilterPostProcessor fpp;
</p>
<p>
After some calculation this allows to reconstruct the position in world space for each pixel on the screen. If a pixel is under a given water height, let’s render it as a blue pixel! Blue pixel? Not exactly, we want waves, we want ripples, we want foam, we want reflection and refraction.
</p>
<p>
The GameDev.net article describes how those effects are achieved, but the main idea is to generate waves from a height map, create ripples from a normal map, blend in the foam texture when the water depth is below a certain height, compute the refraction color with a clever color extinction algorithm, and then, display the reflection and specular effect by computing a Fresnel term (like in standard water effect). In addition this effect, allow to blend the water shore with the ground to avoid the hard edges effect of classic water effects based on grids or quads.
</p>
</div>
<h2><a>How Did We Implement it in jME3?</a></h2>
<div>
<p>
jME3 default behavior is to use a forward rendering process, so there is no position buffer rendered that we can take advantage of. But while rendering the main scene to a frame buffer in the FilterPostPorcessor, we can write the hardware depth buffer to a texture, with nearly no additional cost.
</p>
<p>
I won’t go into the details of this, but there are several ways of reconstructing the world space position of a pixel from the depth buffer. The computational cost is higher than just fetching the position form a position buffer, but the bandwidth and the memory required is a lot lower.
</p>
<p>
We have the rendered scene in a texture, and we can reconstruct the position in world space of each pixel… We’re good to go!
</p>
<p>
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/2011/01/15/new-advanced-water-effect-for-jmonkeyengine-3/#comment-609"><param name="text" value="<html><u>JME3&#039;s Water Post-Process Effect</u></html>"><param name="textColor" value="blue"></object> by Nehon
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<p>
There are two test cases in the jME3 repository:
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWater.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestPostWater.java</u></html>"><param name="textColor" value="blue"></object> (ocean island)</div>
</li>
</ul>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWaterLake.java"><param name="text" value="<html><u>jme3/src/test/jme3test/water/TestPostWaterLake.java</u></html>"><param name="textColor" value="blue"></object> (calm and muddy water pond)</div>
</li>
</ul>
</div>
<h3><a>Using the Water Filter</a></h3>
<div>
<p>
In the <code>simpleInitApp()</code> method, you attach your scene to the rootNode, typically a terrain with a sky. Remember to add a directional light, since the water relies on the light direction vector. The WaterFilter constrcutor expects a node with the scene attached that should be reflected in the water, and vector information from the light source&#039;s direction.
</p>
<p>
This is how you use the water filter post-processor code in your code:
</p>
<pre>private FilterPostProcessor fpp;
private WaterFilter water; private WaterFilter water;
private Vector3f lightDir = new Vector3f&#40;-4.9f, -1.3f, 5.9f&#41;; // same as light source private Vector3f lightDir = new Vector3f&#40;-4.9f, -1.3f, 5.9f&#41;; // same as light source
private float initialWaterHeight = 0.8f; // choose a value for your scene private float initialWaterHeight = 0.8f; // choose a value for your scene
@ -97,21 +32,9 @@ public void simpleInitApp&#40;&#41; &#123;
fpp.addFilter&#40;water&#41;; fpp.addFilter&#40;water&#41;;
viewPort.addProcessor&#40;fpp&#41;; viewPort.addProcessor&#40;fpp&#41;;
... ...
&#125;</pre> &#125;</pre><p> Usually you make the water reflect everything attached to the rootNode. But you can also give a custom node (a subnode of the rootNode) to the WaterFilter constructor that has only a subset of scene nodes attached. This would be a relevant optimization if you have lots of nodes that are far away from the water, or covered, and will never be reflected.</p></div><h3><a
<p> name="optionalwaves">Optional: Waves</a></h3><div
Usually you make the water reflect everything attached to the rootNode. But you can also give a custom node (a subnode of the rootNode) to the WaterFilter constructor that has only a subset of scene nodes attached. This would be a relevant optimization if you have lots of nodes that are far away from the water, or covered, and will never be reflected. class="level3"><p> If you want waves, set the water height in the update loop. We reuse the initialWaterHeight variable, and repeatedly reset the waterHeight value according to time. This causes the waves.</p><pre>private float time = 0.0f;
</p>
</div>
<h3><a>Optional: Waves</a></h3>
<div>
<p>
If you want waves, set the water height in the update loop. We reuse the initialWaterHeight variable, and repeatedly reset the waterHeight value according to time. This causes the waves.
</p>
<pre>private float time = 0.0f;
private float waterHeight = 0.0f; private float waterHeight = 0.0f;
&nbsp; &nbsp;
@Override @Override
@ -120,147 +43,155 @@ public void simpleUpdate&#40;float tpf&#41; &#123;
time += tpf; time += tpf;
waterHeight = &#40;float&#41; Math.cos&#40;&#40;&#40;time * 0.6f&#41; % FastMath.TWO_PI&#41;&#41; * 1.5f; waterHeight = &#40;float&#41; Math.cos&#40;&#40;&#40;time * 0.6f&#41; % FastMath.TWO_PI&#41;&#41; * 1.5f;
water.setWaterHeight&#40;initialWaterHeight + waterHeight&#41;; water.setWaterHeight&#40;initialWaterHeight + waterHeight&#41;;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="optionalwater_wave_and_color_effects">Optional: Water Wave and Color Effects</a></h3><div
class="level3"><p> <a
<h3><a>Optional: Water Wave and Color Effects</a></h3> href="/wiki/lib/exe/detail.php/jme3:advanced:water-post-muddy.png?id=jme3%3Aadvanced%3Apost-processor_water"><img
<div> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water-post-muddy.png?w=220&amp;h=172" class="mediacenter" alt="" width="220" height="172" /></a></p><p> All these effects are optional. Every setter also has a getter.</p><div
class="table sectionedit1"><table
<p> class="inline"><tr
class="row0"><th
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/water-post-muddy.png"> class="col0"> Water method example</th><th
</p> class="col1">Effects: Waves</th><th
class="col2">Default</th></tr><tr
<p> class="row1"><td
All these effects are optional. Every setter also has a getter. class="col0">water.setWaterHeight(-6);</td><td
class="col1">Use this waterheight method for causing waves.</td><td
</p> class="col2">0.0f</td></tr><tr
<table> class="row2"><td
<tr> class="col0">water.setMaxAmplitude(0.3f);</td><td
<th> Water method example</th><th>Effects: Waves </th><th>Default</th> class="col1">How high the highest waves are.</td><td
</tr> class="col2">1.0f</td></tr><tr
<tr> class="row3"><td
<td>water.setWaterHeight(-6);</td><td>Use this waterheight method for causing waves.</td><td>0.0f</td> class="col0">water.setWaveScale(0.008f);</td><td
</tr> class="col1">Sets the scale factor of the waves height map. The smaller the value, the bigger the waves!</td><td
<tr> class="col2"> 0.005f</td></tr><tr
<td>water.setMaxAmplitude(0.3f);</td><td>How high the highest waves are.</td><td>1.0f</td> class="row4"><td
</tr> class="col0">water.setWindDirection(new Vector2f(0,1))</td><td
<tr> class="col1">Sets the wind direction, which is the direction where the waves move</td><td
<td>water.setWaveScale(0.008f);</td><td>Sets the scale factor of the waves height map. The smaller the value, the bigger the waves!</td><td> 0.005f </td> class="col2">Vector2f(0.0f, -1.0f)</td></tr><tr
</tr> class="row5"><td
<tr> class="col0">water.setSpeed(0.7f);</td><td
<td>water.setWindDirection(new Vector2f(0,1))</td><td>Sets the wind direction, which is the direction where the waves move</td><td>Vector2f(0.0f, -1.0f)</td> class="col1">How fast the waves move. Set it to 0.0f for still water.</td><td
</tr> class="col2">1.0f</td></tr><tr
<tr> class="row6"><td
<td>water.setSpeed(0.7f);</td><td>How fast the waves move. Set it to 0.0f for still water.</td><td>1.0f</td> class="col0">water.setHeightTexture( (Texture2D) <br/> manager.loadTexture(&quot;Textures/waveheight.png&quot;) )</td><td
</tr> class="col1">This height map describes the shape of the waves</td><td
<tr> class="col2">&quot;Common/MatDefs/Water/Textures/heightmap.jpg&quot;</td></tr><tr
<td>water.setHeightTexture( (Texture2D) <br/> class="row7"><td
manager.loadTexture(“Textures/waveheight.png”) )</td><td>This height map describes the shape of the waves</td><td>“Common/MatDefs/Water/Textures/heightmap.jpg”</td> class="col0">water.setNormalTexture( (Texture2D) <br/> manager.loadTexture(&quot;Textures/wavenormals.png&quot;) )</td><td
</tr> class="col1">This normal map describes the shape of the waves</td><td
<tr> class="col2">&quot;Common/MatDefs/Water/Textures/gradient_map.jpg&quot;</td></tr><tr
<td>water.setNormalTexture( (Texture2D) <br/> class="row8"><td
manager.loadTexture(“Textures/wavenormals.png”) )</td><td>This normal map describes the shape of the waves</td><td>“Common/MatDefs/Water/Textures/gradient_map.jpg”</td> class="col0">water.setUseRipples(false);</td><td
</tr> class="col1">Switches the ripples effect on or off.</td><td
<tr> class="col2">true</td></tr><tr
<td>water.setUseRipples(false);</td><td>Switches the ripples effect on or off.</td><td>true</td> class="row9"><td
</tr> class="col0">water.setNormalScale(0.5f)</td><td
<tr> class="col1">Sets the normal scaling factors to apply to the normal map. The higher the value, the more small ripples will be visible on the waves.</td><td
<td>water.setNormalScale(0.5f)</td><td>Sets the normal scaling factors to apply to the normal map. The higher the value, the more small ripples will be visible on the waves.</td><td>1.0f</td> class="col2">1.0f</td></tr></table></div><div
</tr> class="table sectionedit2"><table
</table> class="inline"><tr
<table> class="row0"><th
<tr> class="col0"> Water method example</th><th
<th> Water method example</th><th> Effects: Color</th><th>Default</th> class="col1"> Effects: Color</th><th
</tr> class="col2">Default</th></tr><tr
<tr> class="row1"><td
<td>water.setLightDirection(new Vector3f(-0.37f,-0.50f,-0.78f))</td><td>Usually you set this to the same as the light source&#039;s direction. Use this to set the light direction if the sun is moving.</td><td>Value given to WaterFilter() constructor.</td> class="col0">water.setLightDirection(new Vector3f(-0.37f,-0.50f,-0.78f))</td><td
</tr> class="col1">Usually you set this to the same as the light source&#039;s direction. Use this to set the light direction if the sun is moving.</td><td
<tr> class="col2">Value given to WaterFilter() constructor.</td></tr><tr
<td>water.setLightColor(ColorRGBA.White)</td><td>Usually you set this to the same as the light source&#039;s color.</td><td>RGBA.White</td> class="row2"><td
</tr> class="col0">water.setLightColor(ColorRGBA.White)</td><td
<tr> class="col1">Usually you set this to the same as the light source&#039;s color.</td><td
<td>water.setWaterColor(ColorRGBA.Brown.mult(2.0f));</td><td>Sets the main water color.</td><td>greenish blue <br/> class="col2">RGBA.White</td></tr><tr
Vector3f(0.0f,0.5f,0.5f,1.0f)</td> class="row3"><td
</tr> class="col0">water.setWaterColor(ColorRGBA.Brown.mult(2.0f));</td><td
<tr> class="col1">Sets the main water color.</td><td
<td>water.setDeepWaterColor(ColorRGBA.Brown);</td><td>Sets the deep water color.</td><td>dark blue <br/> class="col2">greenish blue <br/> Vector3f(0.0f,0.5f,0.5f,1.0f)</td></tr><tr
Vector3f(0.0f, 0.0f,0.2f,1.0f)</td> class="row4"><td
</tr> class="col0">water.setDeepWaterColor(ColorRGBA.Brown);</td><td
<tr> class="col1">Sets the deep water color.</td><td
<td>water.setWaterTransparency(0.2f);</td><td>Sets how fast colors fade out. use this to control how clear (e.g. 0.05f) or muddy (0.2f) water is.</td><td> 0.1f </td> class="col2">dark blue <br/> Vector3f(0.0f, 0.0f,0.2f,1.0f)</td></tr><tr
</tr> class="row5"><td
<tr> class="col0">water.setWaterTransparency(0.2f);</td><td
<td>water.setColorExtinction(new Vector3f(10f,20f,30f));</td><td>Sets At what depth the refraction color extincts. The three values are RGB (red, green, blue) in this order. Play with these parameters to “muddy” the water.</td><td>Vector3f(5f,20f,30f)</td> class="col1">Sets how fast colors fade out. use this to control how clear (e.g. 0.05f) or muddy (0.2f) water is.</td><td
</tr> class="col2"> 0.1f</td></tr><tr
</table> class="row6"><td
<table> class="col0">water.setColorExtinction(new Vector3f(10f,20f,30f));</td><td
<tr> class="col1">Sets At what depth the refraction color extincts. The three values are RGB (red, green, blue) in this order. Play with these parameters to &quot;muddy&quot; the water.</td><td
<th> Water method example</th><th> Effects: Shore</th><th>Default</th> class="col2">Vector3f(5f,20f,30f)</td></tr></table></div><div
</tr> class="table sectionedit3"><table
<tr> class="inline"><tr
<td>water.setShoreHardness(1.0f);</td><td>Sets how soft the transition between shore and water should be. High values mean a harder transition between shore and water.</td><td>0.1f</td> class="row0"><th
</tr> class="col0"> Water method example</th><th
<tr> class="col1"> Effects: Shore</th><th
<td>water.setUseHQShoreline(false);</td><td>Renders shoreline with better quality ?</td><td>true</td> class="col2">Default</th></tr><tr
</tr> class="row1"><td
</table> class="col0">water.setShoreHardness(1.0f);</td><td
<table> class="col1">Sets how soft the transition between shore and water should be. High values mean a harder transition between shore and water.</td><td
<tr> class="col2">0.1f</td></tr><tr
<th> Water method example</th><th> Effects: Foam</th><th>Default</th> class="row2"><td
</tr> class="col0">water.setUseHQShoreline(false);</td><td
<tr> class="col1">Renders shoreline with better quality ?</td><td
<td>water.setUseFoam(false);</td><td>Switches the white foam on or off</td><td>true</td> class="col2">true</td></tr></table></div><div
</tr> class="table sectionedit4"><table
<tr> class="inline"><tr
<td>water.setFoamHardness(0.5f)</td><td>Sets how much the foam will blend with the shore to avoid a hard edged water plane.</td><td>1.0f</td> class="row0"><th
</tr> class="col0"> Water method example</th><th
<tr> class="col1"> Effects: Foam</th><th
<td>water.setFoamExistence(new Vector3f(0.5f,5f,1.0f))</td><td>The three values describe what depth foam starts to fade out, at what depth it is completely invisible, at what height foam for waves appears (+ waterHeight).</td><td>Vector3f(0.45f,4.35f,1.0f)</td> class="col2">Default</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">water.setUseFoam(false);</td><td
<td>water.setFoamTexture( (Texture2D) <br/> class="col1">Switches the white foam on or off</td><td
manager.loadTexture(“Textures/foam.png”) )</td><td>This foam texture will be used with WrapMode.Repeat</td><td>“Common/MatDefs/Water/Textures/foam.jpg”</td> class="col2">true</td></tr><tr
</tr> class="row2"><td
</table> class="col0">water.setFoamHardness(0.5f)</td><td
<table> class="col1">Sets how much the foam will blend with the shore to avoid a hard edged water plane.</td><td
<tr> class="col2">1.0f</td></tr><tr
<th> Water method example</th><th> Effects: Light</th><th>Default</th> class="row3"><td
</tr> class="col0">water.setFoamExistence(new Vector3f(0.5f,5f,1.0f))</td><td
<tr> class="col1">The three values describe what depth foam starts to fade out, at what depth it is completely invisible, at what height foam for waves appears (+ waterHeight).</td><td
<td>water.setSunScale(1f);</td><td>Sets how big the sun should appear in the light&#039;s specular effect on the water.</td><td>3.0f</td> class="col2">Vector3f(0.45f,4.35f,1.0f)</td></tr><tr
</tr> class="row4"><td
<tr> class="col0">water.setFoamTexture( (Texture2D) <br/> manager.loadTexture(&quot;Textures/foam.png&quot;) )</td><td
<td>water.setUseSpecular(false)</td><td>Switches specular effect on or off</td><td>true</td> class="col1">This foam texture will be used with WrapMode.Repeat</td><td
</tr> class="col2">&quot;Common/MatDefs/Water/Textures/foam.jpg&quot;</td></tr></table></div><div
<tr> class="table sectionedit5"><table
<td>water.setShininess(0.8f)</td><td>Sets the shininess of the water reflections</td><td>0.7f</td> class="inline"><tr
</tr> class="row0"><th
<tr> class="col0"> Water method example</th><th
<td>water.setUseRefraction(true)</td><td>Switches the refraction effect on or off.</td><td>true</td> class="col1"> Effects: Light</th><th
</tr> class="col2">Default</th></tr><tr
<tr> class="row1"><td
<td>water.setRefractionConstant(0.2f);</td><td>The lower the value, the less reflection can be seen on water. This is a constant related to the index of refraction (IOR) used to compute the fresnel term.</td><td>0.3f</td> class="col0">water.setSunScale(1f);</td><td
</tr> class="col1">Sets how big the sun should appear in the light&#039;s specular effect on the water.</td><td
<tr> class="col2">3.0f</td></tr><tr
<td>water.setRefractionStrength(-0.1)</td><td>This value modifies the current Fresnel term. If you want to weaken reflections use bigger value. If you want to empasize them, use a value smaller than 0.</td><td>0.0f</td> class="row2"><td
</tr> class="col0">water.setUseSpecular(false)</td><td
<tr> class="col1">Switches specular effect on or off</td><td
<td>water.setReflectionMapSize(256)</td><td>Sets the size of the reflection map. The higher, the better the quality, but the slower the effect.</td><td>512</td> class="col2">true</td></tr><tr
</tr> class="row3"><td
</table> class="col0">water.setShininess(0.8f)</td><td
class="col1">Sets the shininess of the water reflections</td><td
</div> class="col2">0.7f</td></tr><tr
class="row4"><td
<h3><a>Sound Effects</a></h3> class="col0">water.setUseRefraction(true)</td><td
<div> class="col1">Switches the refraction effect on or off.</td><td
class="col2">true</td></tr><tr
<p> class="row5"><td
class="col0">water.setRefractionConstant(0.2f);</td><td
You should also add audio nodes with water sounds to complete the effect. class="col1">The lower the value, the less reflection can be seen on water. This is a constant related to the index of refraction (IOR) used to compute the fresnel term.</td><td
</p> class="col2">0.3f</td></tr><tr
<pre>AudioNode waves = new AudioNode&#40;assetManager, &quot;Sound/Environment/Ocean Waves.ogg&quot;, false&#41;; class="row6"><td
class="col0">water.setRefractionStrength(-0.1)</td><td
class="col1">This value modifies the current Fresnel term. If you want to weaken reflections use bigger value. If you want to empasize them, use a value smaller than 0.</td><td
class="col2">0.0f</td></tr><tr
class="row7"><td
class="col0">water.setReflectionMapSize(256)</td><td
class="col1">Sets the size of the reflection map. The higher, the better the quality, but the slower the effect.</td><td
class="col2">512</td></tr></table></div></div><h3><a
name="sound_effects">Sound Effects</a></h3><div
class="level3"><p> You should also add audio nodes with water sounds to complete the effect.</p><pre>AudioNode waves = new AudioNode&#40;assetManager, &quot;Sound/Environment/Ocean Waves.ogg&quot;, false&#41;;
waves.setLooping&#40;true&#41;; waves.setLooping&#40;true&#41;;
audioRenderer.playSource&#40;waves&#41;;</pre> audioRenderer.playSource&#40;waves&#41;;</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:post-processor_water?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:post-processor_water?do=export_xhtmlbody">view online version</a></em></p>

@ -1,59 +1,31 @@
<h1><a
<h1><a>Ragdoll Physics</a></h1> name="ragdoll_physics">Ragdoll Physics</a></h1><div
<div> class="level1"><p> The jMonkeyEngine3 has built-in support for <a
href="http://jbullet.advel.cz">jBullet physics</a> via the <code>com.jme3.bullet</code> package. Physics are not only responsible for handing collisions, but they also make <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">hinges and joints</a> possible. One special example of physical joints are ragdoll physics, shown here.</p></div><h2><a
name="sample_code">Sample Code</a></h2><div
The jMonkeyEngine3 has built-in support for <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jbullet.advel.cz"><param name="text" value="<html><u>jBullet physics</u></html>"><param name="textColor" value="blue"></object> via the <code>com.jme3.bullet</code> package. Physics are not only responsible for handing collisions, but they also make <a href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">hinges and joints</a> possible. One special example of physical joints are ragdoll physics, shown here. class="level2"><ul><li
</p> class="level1"><div
class="li"> <a
</div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestRagDoll.java">TestRagDoll.java</a> (Tip: Click to pull the ragdoll up)</div></li><li
class="level1"><div
<h2><a>Sample Code</a></h2> class="li"> <a
<div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestBoneRagdoll.java">TestBoneRagdoll.java</a> – This ragdoll replaces a rigged model of a character in the moment it is &quot;shot&quot; to simulate a collapsing person. (Also note DoF of the limbs.)</div></li></ul></div><h2><a
<ul> name="preparing_the_physics_game">Preparing the Physics Game</a></h2><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestRagDoll.java"><param name="text" value="<html><u>TestRagDoll.java</u></html>"><param name="textColor" value="blue"></object> (Tip: Click to pull the ragdoll up)</div> class="level2"><ol><li
</li> class="level1"><div
</ul> class="li"> Create a SimpleApplication with a <a
href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a></div><ul><li
</div> class="level2"><div
class="li"> This gives us a PhysicsSpace for PhysicControls</div></li></ul></li><li
<h2><a>Preparing the Physics Game</a></h2> class="level1"><div
<div> class="li"> Add a physical floor (A box collision shape with mass zero)</div></li></ol></div><h2><a
<ol> name="creating_the_ragdoll">Creating the Ragdoll</a></h2><div
<li><div> Create a SimpleApplication with a <a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a> </div> class="level2"><p> <a
<ul> href="/wiki/lib/exe/detail.php/jme3:advanced:ragdoll.png?id=jme3%3Aadvanced%3Aragdoll"><img
<li><div> This gives us a PhysicsSpace for PhysicControls</div> src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/ragdoll.png?w=200&amp;h=150" class="mediaright" align="right" alt="" width="200" height="150" /></a> The ragdoll is a simple dummy that we build out of cylinder collision shapes. It has 11 limbs: shoulders, a body, and hips; plus 2 arms and 2 legs are made up of two limbs each. In your game, you replace the cylinders with your own limb models.</p></div><h3><a
</li> name="limbs">Limbs</a></h3><div
</ul> class="level3"><p> Since we&#039;re just creating the ragdoll for this example, all the limbs have the same shape, and we can write a simple helper method to create them. The function returns a PhysicsNode with CollisionShape with the width, height, location, and rotation (vertical or horizontal) that we specify. We choose a CapsuleCollisionShape (a cylinder with rounded top and bottom) so the limbs collide smoothly against one another.</p><pre>private Node createLimb&#40;float width, float height, Vector3f location, boolean rotate&#41; &#123;
</li>
<li><div> Add a physical floor (A box collision shape with mass zero)</div>
</li>
</ol>
</div>
<h2><a>Creating the Ragdoll</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/ragdoll.png">
</p>
<p>
The ragdoll is a simple dummy that we build out of cylinder collision shapes. It has 11 limbs: shoulders, a body, and hips; plus 2 arms and 2 legs are made up of two limbs each. In your game, you replace the cylinders with your own limb models.
</p>
</div>
<h3><a>Limbs</a></h3>
<div>
<p>
Since we&#039;re just creating the ragdoll for this example, all the limbs have the same shape, and we can write a simple helper method to create them. The function returns a PhysicsNode with CollisionShape with the width, height, location, and rotation (vertical or horizontal) that we specify. We choose a CapsuleCollisionShape (a cylinder with rounded top and bottom) so the limbs collide smoothly against one another.
</p>
<pre>private Node createLimb&#40;float width, float height, Vector3f location, boolean rotate&#41; &#123;
int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y; int axis = rotate ? PhysicsSpace.AXIS_X : PhysicsSpace.AXIS_Y;
CapsuleCollisionShape shape = new CapsuleCollisionShape&#40;width, height, axis&#41;; CapsuleCollisionShape shape = new CapsuleCollisionShape&#40;width, height, axis&#41;;
Node node = new Node&#40;&quot;Limb&quot;&#41;; Node node = new Node&#40;&quot;Limb&quot;&#41;;
@ -61,21 +33,15 @@ Since we&#039;re just creating the ragdoll for this example, all the limbs have
node.setLocalTranslation&#40;location&#41;; node.setLocalTranslation&#40;location&#41;;
node.addControl&#40;rigidBodyControl&#41;; node.addControl&#40;rigidBodyControl&#41;;
return node; return node;
&#125;</pre> &#125;</pre><p> We use this helper method to initialize the 11 limbs. Look at the screenshot above for orientation.</p><ul><li
<p> class="level1"><div
We use this helper method to initialize the 11 limbs. Look at the screenshot above for orientation. class="li"> All cylinders have the same diameter, 0.2f.</div></li><li
</p> class="level1"><div
<ul> class="li"> We make the body and shoulders longer than the other limbs, 1.0f instead of 0.5f.</div></li><li
<li><div> All cylinders have the same diameter, 0.2f.</div> class="level1"><div
</li> class="li"> We determine the coordinates for positioning the limbs to form a person.</div></li><li
<li><div> We make the body and shoulders longer than the other limbs, 1.0f instead of 0.5f.</div> class="level1"><div
</li> class="li"> The shoulders and hips are <em>vertical</em> cylinders, this is why we set the rotation to true.</div></li></ul><pre>Node shoulders = createLimb&#40;0.2f, 1.0f, new Vector3f&#40; 0.00f, 1.5f, 0&#41;, true&#41;;
<li><div> We determine the coordinates for positioning the limbs to form a person.</div>
</li>
<li><div> The shoulders and hips are <em>vertical</em> cylinders, this is why we set the rotation to true.</div>
</li>
</ul>
<pre>Node shoulders = createLimb&#40;0.2f, 1.0f, new Vector3f&#40; 0.00f, 1.5f, 0&#41;, true&#41;;
Node uArmL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.75f, 0.8f, 0&#41;, false&#41;; Node uArmL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.75f, 0.8f, 0&#41;, false&#41;;
Node uArmR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.75f, 0.8f, 0&#41;, false&#41;; Node uArmR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.75f, 0.8f, 0&#41;, false&#41;;
Node lArmL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.75f,-0.2f, 0&#41;, false&#41;; Node lArmL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.75f,-0.2f, 0&#41;, false&#41;;
@ -85,29 +51,15 @@ Node hips = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.00f,-0.5f, 0&#41
Node uLegL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.25f,-1.2f, 0&#41;, false&#41;; Node uLegL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.25f,-1.2f, 0&#41;, false&#41;;
Node uLegR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.25f,-1.2f, 0&#41;, false&#41;; Node uLegR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.25f,-1.2f, 0&#41;, false&#41;;
Node lLegL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.25f,-2.2f, 0&#41;, false&#41;; Node lLegL = createLimb&#40;0.2f, 0.5f, new Vector3f&#40;-0.25f,-2.2f, 0&#41;, false&#41;;
Node lLegR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.25f,-2.2f, 0&#41;, false&#41;;</pre> Node lLegR = createLimb&#40;0.2f, 0.5f, new Vector3f&#40; 0.25f,-2.2f, 0&#41;, false&#41;;</pre><p> We now have the outline of a person. But if we ran the application now, the individual limbs would fall down independently of one another – the ragdoll is still lacking joints.</p></div><h3><a
<p> name="joints">Joints</a></h3><div
We now have the outline of a person. But if we ran the application now, the individual limbs would fall down independently of one another – the ragdoll is still lacking joints. class="level3"><p> As before, we write a small helper method. This time its purpose is to quickly join two limbs A and B at the connection point that we specify.</p><ul><li
</p> class="level1"><div
class="li"> We convert A&#039;s and B&#039;s connectionPoint vector from world coordinate space to local coordinate space.</div></li><li
</div> class="level1"><div
class="li"> We use a ConeJoint, a special joint that approximates the degree of freedom that limbs typically have. The ConeJoint constructor requires the two nodes, and the two local pivot coordinates that we just determined.</div></li><li
<h3><a>Joints</a></h3> class="level1"><div
<div> class="li"> We set the joints limits to allow swinging, but not twisting.</div></li></ul><pre>private PhysicsJoint join&#40;Node A, Node B, Vector3f connectionPoint&#41; &#123;
<p>
As before, we write a small helper method. This time its purpose is to quickly join two limbs A and B at the connection point that we specify.
</p>
<ul>
<li><div> We convert A&#039;s and B&#039;s connectionPoint vector from world coordinate space to local coordinate space.</div>
</li>
<li><div> We use a ConeJoint, a special joint that approximates the degree of freedom that limbs typically have. The ConeJoint constructor requires the two nodes, and the two local pivot coordinates that we just determined.</div>
</li>
<li><div> We set the joints limits to allow swinging, but not twisting.</div>
</li>
</ul>
<pre>private PhysicsJoint join&#40;Node A, Node B, Vector3f connectionPoint&#41; &#123;
Vector3f pivotA = A.worldToLocal&#40;connectionPoint, new Vector3f&#40;&#41;&#41;; Vector3f pivotA = A.worldToLocal&#40;connectionPoint, new Vector3f&#40;&#41;&#41;;
Vector3f pivotB = B.worldToLocal&#40;connectionPoint, new Vector3f&#40;&#41;&#41;; Vector3f pivotB = B.worldToLocal&#40;connectionPoint, new Vector3f&#40;&#41;&#41;;
ConeJoint joint = new ConeJoint&#40;A.getControl&#40;RigidBodyControl.class&#41;, ConeJoint joint = new ConeJoint&#40;A.getControl&#40;RigidBodyControl.class&#41;,
@ -115,36 +67,18 @@ As before, we write a small helper method. This time its purpose is to quickly j
pivotA, pivotB&#41;; pivotA, pivotB&#41;;
joint.setLimit&#40;1f, 1f, 0&#41;; joint.setLimit&#40;1f, 1f, 0&#41;;
return joint; return joint;
&#125;</pre> &#125;</pre><p> We use the helper method to connect all limbs with joints where they belong, at one end of the limb.</p><pre>join&#40;body, shoulders, new Vector3f&#40; 0.00f, 1.4f, 0&#41;&#41;;
<p>
We use the helper method to connect all limbs with joints where they belong, at one end of the limb.
</p>
<pre>join&#40;body, shoulders, new Vector3f&#40; 0.00f, 1.4f, 0&#41;&#41;;
join&#40;body, hips, new Vector3f&#40; 0.00f, -0.5f, 0&#41;&#41;; join&#40;body, hips, new Vector3f&#40; 0.00f, -0.5f, 0&#41;&#41;;
&nbsp;
join&#40;uArmL, shoulders, new Vector3f&#40;-0.75f, 1.4f, 0&#41;&#41;; join&#40;uArmL, shoulders, new Vector3f&#40;-0.75f, 1.4f, 0&#41;&#41;;
join&#40;uArmR, shoulders, new Vector3f&#40; 0.75f, 1.4f, 0&#41;&#41;; join&#40;uArmR, shoulders, new Vector3f&#40; 0.75f, 1.4f, 0&#41;&#41;;
join&#40;uArmL, lArmL, new Vector3f&#40;-0.75f, 0.4f, 0&#41;&#41;; join&#40;uArmL, lArmL, new Vector3f&#40;-0.75f, 0.4f, 0&#41;&#41;;
join&#40;uArmR, lArmR, new Vector3f&#40; 0.75f, 0.4f, 0&#41;&#41;; join&#40;uArmR, lArmR, new Vector3f&#40; 0.75f, 0.4f, 0&#41;&#41;;
&nbsp;
join&#40;uLegL, hips, new Vector3f&#40;-0.25f, -0.5f, 0&#41;&#41;; join&#40;uLegL, hips, new Vector3f&#40;-0.25f, -0.5f, 0&#41;&#41;;
join&#40;uLegR, hips, new Vector3f&#40; 0.25f, -0.5f, 0&#41;&#41;; join&#40;uLegR, hips, new Vector3f&#40; 0.25f, -0.5f, 0&#41;&#41;;
join&#40;uLegL, lLegL, new Vector3f&#40;-0.25f, -1.7f, 0&#41;&#41;; join&#40;uLegL, lLegL, new Vector3f&#40;-0.25f, -1.7f, 0&#41;&#41;;
join&#40;uLegR, lLegR, new Vector3f&#40; 0.25f, -1.7f, 0&#41;&#41;;</pre> join&#40;uLegR, lLegR, new Vector3f&#40; 0.25f, -1.7f, 0&#41;&#41;;</pre><p> Now the ragdoll is connected. If we ran the app now, the doll would collapse, but the limbs would stay together.</p></div><h3><a
<p> name="attaching_everything_to_the_scene">Attaching Everything to the Scene</a></h3><div
Now the ragdoll is connected. If we ran the app now, the doll would collapse, but the limbs would stay together. class="level3"><p> We create one (non-physical) Node named ragDoll, and attach all other nodes to it.</p><pre>ragDoll.attachChild&#40;shoulders&#41;;
</p>
</div>
<h3><a>Attaching Everything to the Scene</a></h3>
<div>
<p>
We create one (non-physical) Node named ragDoll, and attach all other nodes to it.
</p>
<pre>ragDoll.attachChild&#40;shoulders&#41;;
ragDoll.attachChild&#40;body&#41;; ragDoll.attachChild&#40;body&#41;;
ragDoll.attachChild&#40;hips&#41;; ragDoll.attachChild&#40;hips&#41;;
ragDoll.attachChild&#40;uArmL&#41;; ragDoll.attachChild&#40;uArmL&#41;;
@ -154,46 +88,15 @@ ragDoll.attachChild&#40;lArmR&#41;;
ragDoll.attachChild&#40;uLegL&#41;; ragDoll.attachChild&#40;uLegL&#41;;
ragDoll.attachChild&#40;uLegR&#41;; ragDoll.attachChild&#40;uLegR&#41;;
ragDoll.attachChild&#40;lLegL&#41;; ragDoll.attachChild&#40;lLegL&#41;;
ragDoll.attachChild&#40;lLegR&#41;;</pre> ragDoll.attachChild&#40;lLegR&#41;;</pre><p> To use the ragdoll in a scene, we attach its main node to the rootNode, and to the PhysicsSpace.</p><pre>rootNode.attachChild&#40;ragDoll&#41;;
<p> bulletAppState.getPhysicsSpace&#40;&#41;.addAll&#40;ragDoll&#41;;</pre></div><h2><a
To use the ragdoll in a scene, we attach its main node to the rootNode, and to the PhysicsSpace. name="applying_forces">Applying Forces</a></h2><div
</p> class="level2"><p> To pull the doll up, you could add an input handler that triggers the following action:</p><pre>Vector3f upforce = new Vector3f&#40;0, 200, 0&#41;;
<pre>rootNode.attachChild&#40;ragDoll&#41;; shoulders.applyContinuousForce&#40;true, upforce&#41;;</pre><p> We can use the action to pick the doll up and put it back on its feet, or what ever. Read more about <a
bulletAppState.getPhysicsSpace&#40;&#41;.addAll&#40;ragDoll&#41;;</pre> href="/com/jme3/gde/core/docs/jme3/advanced/physics#forcesmoving_physical_objects.html">Forces</a> here.</p></div><h2><a
</div> name="detecting_collisions">Detecting Collisions</a></h2><div
class="level2"><p> Read the <a
<h2><a>Applying Forces</a></h2> href="/com/jme3/gde/core/docs/jme3/advanced/physics#responding_to_a_physicscollisionevent.html">Responding to a PhysicsCollisionEvent</a> chapter in the general physics documentation on how to detect collisions.</p></div><h2><a
<div> name="best_practices">Best Practices</a></h2><div
class="level2"><p> If you are seeing weird behaviour in a ragdoll – such as exploding into pieces and then reassembling – check your collision shapes. Verify you did not position the limbs too close to one another when assmebling the ragdoll. You typically see physical nodes being ejected when their collision shapes intersect, which puts physics in an impossible state.</p></div>
<p>
To pull the doll up, you could add an input handler that triggers the following action:
</p>
<pre>Vector3f upforce = new Vector3f&#40;0, 200, 0&#41;;
shoulders.applyContinuousForce&#40;true, upforce&#41;;</pre>
<p>
We can use the action to pick the doll up and put it back on its feet, or what ever. Read more about <a href="/com/jme3/gde/core/docs/jme3/advanced/physics#forcesmoving_physical_objects.html">Forces</a> here.
</p>
</div>
<h2><a>Detecting Collisions</a></h2>
<div>
<p>
Read the <a href="/com/jme3/gde/core/docs/jme3/advanced/physics#responding_to_a_physicscollisionevent.html">Responding to a PhysicsCollisionEvent</a> chapter in the general physics documentation on how to detect collisions.
</p>
</div>
<h2><a>Best Practices</a></h2>
<div>
<p>
If you are seeing weird behaviour in a ragdoll – such as exploding into pieces and then reassembling – check your collision shapes. Verify you did not position the limbs too close to one another when assmebling the ragdoll. You typically see physical nodes being ejected when their collision shapes intersect, which puts physics in an impossible state.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:ragdoll?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:ragdoll?do=export_xhtmlbody">view online version</a></em></p>

@ -1,62 +1,33 @@
<h1><a
<h1><a>Shapes</a></h1> name="shapes">Shapes</a></h1><div
<div> class="level1"><p> The simplest type of Meshes are jME&#039;s default Shapes. You can use Shapes to build complex Geometries. Shapes are created without using the AssetManager.</p><p> <strong>3D shapes:</strong></p><ul><li
class="level1"><div
<p> class="li"> com.jme3.scene.shape.Sphere – A ball or elipsoid.</div></li><li
class="level1"><div
The simplest type of Meshes are jME&#039;s default Shapes. You can use Shapes to build complex Geometries. Shapes are created without using the AssetManager. class="li"> com.jme3.scene.shape.Box – A cube or cuboid.</div></li><li
</p> class="level1"><div
class="li"> com.jme3.scene.shape.Cylinder – A disk or pillar.</div></li><li
<p> class="level1"><div
<strong>3D shapes:</strong> class="li"> com.jme3.scene.shape.Dome – Half a sphere.</div></li><li
</p> class="level1"><div
<ul> class="li"> com.jme3.scene.shape.Torus – An single-holed torus (&quot;donut&quot;).</div></li><li
<li><div> com.jme3.scene.shape.Sphere – A ball or elipsoid.</div> class="level1"><div
</li> class="li"> com.jme3.scene.shape.PQTorus – A parameterized torus, also known as PQ torus. Looks like a <a
<li><div> com.jme3.scene.shape.Box – A cube or cuboid.</div> href="http://en.wikipedia.org/wiki/Torus_knot">donut knotted into spirals</a>.</div></li></ul><p> <strong>Non-3D shapes:</strong></p><ul><li
</li> class="level1"><div
<li><div> com.jme3.scene.shape.Cylinder – A disk or pillar.</div> class="li"> com.jme3.scene.shape.Quad – A flat 2D rectangle (has two sides)</div></li><li
</li> class="level1"><div
<li><div> com.jme3.scene.shape.Dome – Half a sphere.</div> class="li"> com.jme3.scene.shape.Line – A 1D line (has a length)</div></li><li
</li> class="level1"><div
<li><div> com.jme3.scene.shape.Torus – An single-holed torus (“donut”).</div> class="li"> come.jme3.math.Ray – A 1D line (has length, direction, start point, but no end)</div></li></ul></div><h2><a
</li> name="usage">Usage</a></h2><div
<li><div> com.jme3.scene.shape.PQTorus – A parameterized torus, also known as PQ torus. Looks like a <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/Torus_knot"><param name="text" value="<html><u>donut knotted into spirals</u></html>"><param name="textColor" value="blue"></object>.</div> class="level2"><p> To add a shape to the scene:</p><ol><li
</li> class="level1"><div
</ul> class="li"> Create the base mesh shape</div></li><li
class="level1"><div
<p> class="li"> Wrap it into a Geometry</div></li><li
class="level1"><div
<strong>Non-3D shapes:</strong> class="li"> Attach the Geometry to the rootNode to make it visible.</div></li></ol><pre>Sphere sphereMesh = new Sphere&#40;32, 32, 10, false, true&#41;;
</p>
<ul>
<li><div> com.jme3.scene.shape.Quad – A flat 2D rectangle (has two sides)</div>
</li>
<li><div> com.jme3.scene.shape.Line – A 1D line (has a length)</div>
</li>
<li><div> come.jme3.math.Ray – A 1D line (has length, direction, start point, but no end)</div>
</li>
</ul>
</div>
<h2><a>Usage</a></h2>
<div>
<p>
To add a shape to the scene:
</p>
<ol>
<li><div> Create the base mesh shape</div>
</li>
<li><div> Wrap it into a Geometry</div>
</li>
<li><div> Attach the Geometry to the rootNode to make it visible.</div>
</li>
</ol>
<pre>Sphere sphereMesh = new Sphere&#40;32, 32, 10, false, true&#41;;
Geometry sphere = new Geometry&#40;&quot;Sky&quot;, sphereMesh&#41;; Geometry sphere = new Geometry&#40;&quot;Sky&quot;, sphereMesh&#41;;
rootNode.attachChild&#40;sphere&#41;;</pre> rootNode.attachChild&#40;sphere&#41;;</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:shape?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:shape?do=export_xhtmlbody">view online version</a></em></p>

@ -1,100 +1,42 @@
<h1><a
<h1><a>How to add a Sky to your Scene</a></h1> name="how_to_add_a_sky_to_your_scene">How to add a Sky to your Scene</a></h1><div
<div> class="level1"><p> <br/></p><p> Here is an example for how you add a static horizon (a background landscape and a sky) to a scene.
Having a discernable horizon with a suitable landscape (or space, or ocean, or whatever) in the background makes scenes look more realistic than just a single-colored &quot;sky&quot; background.</p></div><h2><a
<p> name="adding_the_sky">Adding the Sky</a></h2><div
class="level2"><p> Adding a sky is extremely easy using the <code>com.jme3.util.SkyFactory</code>.</p><pre>rootNode.attachChild&#40;SkyFactory.createSky&#40;
<br/> assetManager, &quot;Textures/Sky/Bright/BrightSky.dds&quot;, false&#41;&#41;;</pre><p> To add a sky you need to supply:</p><ol><li
class="level1"><div
</p> class="li"> The assetManager object to use</div></li><li
class="level1"><div
<p> class="li"> A cube or sphere map texture of the sky</div></li><li
Here is an example for how you add a static horizon (a background landscape and a sky) to a scene. class="level1"><div
Having a discernable horizon with a suitable landscape (or space, or ocean, or whatever) in the background makes scenes look more realistic than just a single-colored “sky” background. class="li"> Set the boolean to true if you are using a sphere map texture. For a cube map, use false. <br/> Tip: Cube map is the default. You would know if you had created a sphere map.</div></li></ol><p> Internally, the SkyFactory calls the following methods:</p><ol><li
</p> class="level1"><div
class="li"> <code>sky.setQueueBucket(Bucket.Sky);</code> makes certain the sky is rendered in the right order, behind everything else.</div></li><li
</div> class="level1"><div
class="li"> <code>sky.setCullHint(Spatial.CullHint.Never);</code> makes certain that the sky is never culled.</div></li><li
<h2><a>Adding the Sky</a></h2> class="level1"><div
<div> class="li"> The SkyFactory uses the internal jME3 material definition <code>Sky.j3md</code>. This Material definition works with sphere and cube maps.</div></li></ol></div><h2><a
name="creating_the_textures">Creating the Textures</a></h2><div
<p> class="level2"><p> As the sky texture we use the sample BrightSky.dds file from jme3test-test-data.</p><p> How to create a sky textures?</p><ul><li
class="level1"><div
Adding a sky is extremely easy using the <code>com.jme3.util.SkyFactory</code>. class="li"> There are many tools out there that generate cube and sphere maps. <br/> Examples for landscape texture generators are Terragen or Bryce.</div></li><li
</p> class="level1"><div
<pre>rootNode.attachChild&#40;SkyFactory.createSky&#40; class="li"> The actual texture size does not matter, as long as you add the Sky Geometry to the Sky bucket: Everything in the sky bucket will always be infinitely far away behind everything else, and never intersect with your scene. <br/> Of course the higher the resolution, the better it will look. On the other hand, if the graphic is too big, it will slow the game down.</div></li><li
assetManager, &quot;Textures/Sky/Bright/BrightSky.dds&quot;, false&#41;&#41;;</pre> class="level1"><div
<p> class="li"> A box or sphere map is the simplest solution. But you can use any Node as sky, even complex sets of geometries and quads with animated clouds, blinking stars, city skylines, etc.</div></li><li
To add a sky you need to supply: class="level1"><div
</p> class="li"> JME3 supports cube maps in <acronym
<ol> title="Portable Network Graphics">PNG</acronym>, <acronym
<li><div> The assetManager object to use</div> title="Joint Photographics Experts Group">JPG</acronym>, or (compressed) DDS format.</div></li></ul><p> Box or Sphere?</p><ul><li
</li> class="level1"><div
<li><div> A cube or sphere map texture of the sky</div> class="li"> If you have access to cube map textures, then use a SkyBox</div><ul><li
</li> class="level2"><div
<li><div> Set the boolean to true if you are using a sphere map texture. For a cube map, use false. <br/> class="li"> <a
Tip: Cube map is the default. You would know if you had created a sphere map.</div> href="http://1.bp.blogspot.com/_uVsWqMqIGQU/SN0IZEE117I/AAAAAAAAAPs/4lfHx1Erdqg/s1600/skybox">SkyBox examples</a></div></li></ul></li><li
</li> class="level1"><div
</ol> class="li"> If you have access to sphere map textures – specially projected sky images that fit inside a sphere – then you use a SkySphere or SkyDome.</div><ul><li
class="level2"><div
<p> class="li"> <a
href="http://wiki.delphigl.com/index.php/Datei:Skysphere.jpg">SkySphere example</a></div></li></ul></li></ul></div>
Internally, the SkyFactory calls the following methods:
</p>
<ol>
<li><div> <code>sky.setQueueBucket(Bucket.Sky);</code> makes certain the sky is rendered in the right order, behind everything else.</div>
</li>
<li><div> <code>sky.setCullHint(Spatial.CullHint.Never);</code> makes certain that the sky is never culled.</div>
</li>
<li><div> The SkyFactory uses the internal jME3 material definition <code>Sky.j3md</code>. This Material definition works with sphere and cube maps. </div>
</li>
</ol>
</div>
<h2><a>Creating the Textures</a></h2>
<div>
<p>
As the sky texture we use the sample BrightSky.dds file from jme3test-test-data.
</p>
<p>
How to create a sky textures?
</p>
<ul>
<li><div> There are many tools out there that generate cube and sphere maps. <br/>
Examples for landscape texture generators are Terragen or Bryce.</div>
</li>
<li><div> The actual texture size does not matter, as long as you add the Sky Geometry to the Sky bucket: Everything in the sky bucket will always be infinitely far away behind everything else, and never intersect with your scene. <br/>
Of course the higher the resolution, the better it will look. On the other hand, if the graphic is too big, it will slow the game down. </div>
</li>
<li><div> A box or sphere map is the simplest solution. But you can use any Node as sky, even complex sets of geometries and quads with animated clouds, blinking stars, city skylines, etc.</div>
</li>
<li><div> JME3 supports cube maps in <acronym title="Portable Network Graphics">PNG</acronym>, <acronym title="Joint Photographics Experts Group">JPG</acronym>, or (compressed) DDS format.</div>
</li>
</ul>
<p>
Box or Sphere?
</p>
<ul>
<li><div> If you have access to cube map textures, then use a SkyBox</div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://1.bp.blogspot.com/_uVsWqMqIGQU/SN0IZEE117I/AAAAAAAAAPs/4lfHx1Erdqg/s1600/skybox"><param name="text" value="<html><u>SkyBox examples</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</li>
<li><div> If you have access to sphere map textures – specially projected sky images that fit inside a sphere – then you use a SkySphere or SkyDome. </div>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://wiki.delphigl.com/index.php/Datei:Skysphere.jpg"><param name="text" value="<html><u>SkySphere example</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:sky?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:sky?do=export_xhtmlbody">view online version</a></em></p>

@ -1,102 +1,59 @@
<h1><a
<h1><a>Spatial</a></h1> name="spatial">Spatial</a></h1><div
<div> class="level1"><p> This is an introduction to the concept of of Spatials, the elements of the 3D scene graph. The scene graph is a data structure that manages all objects in your 3D world. For example it keeps track of the 3D models that you load and position. When you extend a Java class from com.jme3.app.SimpleApplication, you inherit the scene graph and rootNode.</p><p> The main element of the scene graph is a Spatial called rootNode. All other Spatials are <em>attached</em> to the rootNode in a parent-child relationship. If you think you want to understand the scene graph better, please read <a
href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html">Scenegraph for dummies</a> first.</p></div><h2><a
<p> name="node_versus_geometry">Node versus Geometry</a></h2><div
class="level2"><p> A Spatial is either a Node or a Geometry.</p><p> <a
This is an introduction to the concept of of Spatials, the elements of the 3D scene graph. The scene graph is a data structure that manages all objects in your 3D world. For example it keeps track of the 3D models that you load and position. When you extend a Java class from com.jme3.app.SimpleApplication, you inherit the scene graph and rootNode. href="/wiki/lib/exe/detail.php/jme3:intermediate:scene-graph.png?id=jme3%3Aadvanced%3Aspatial"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/scene-graph.png" class="mediacenter" alt="" /></a></p><div
class="table sectionedit1"><table
<p> class="inline"><tr
The main element of the scene graph is a Spatial called rootNode. All other Spatials are <em>attached</em> to the rootNode in a parent-child relationship. If you think you want to understand the scene graph better, please read <a href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html">Scenegraph for dummies</a> first. class="row0"><td
</p> class="col0 leftalign"></td><th
class="col1" colspan="2"> Spatials</th></tr><tr
</div> class="row1"><th
class="col0"> Purpose:</th><td
<h2><a>Node versus Geometry</a></h2> class="col1" colspan="2"> A Spatial is an abstract data structure that stores transformations (translation, rotation, scale) of elements of the scene graph. A Spatial can be saved and loaded using the AssetManager.</td></tr><tr
<div> class="row2"><td
class="col0 leftalign"></td><th
<p> class="col1"> com.jme3.scene.Geometry</th><th
class="col2"> com.jme3.scene.Node</th></tr><tr
A Spatial is either a Node or a Geometry. class="row3"><th
</p> class="col0"> Visibility:</th><td
class="col1"> A Geometry represents a visible 3-D object in the scene graph.</td><td
<p> class="col2"> A Node is an invisible &quot;handle&quot; for a group of objects in the scene graph.</td></tr><tr
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/scene-graph.png"> class="row4"><th
class="col0 leftalign"> Purpose:</th><td
</p> class="col1"> Use Geometries to represent an object&#039;s looks: Every Geometry contains a polygon mesh and a material, specifying its shape, color, texture, and opacity/transparency. <br/> You can attach a Geometry to an Node.</td><td
<table> class="col2"> Use nodes to structure and group Geometries and other Nodes. Every Node is attached to parent node, and the node can have children attached to itself. When you transform a parent node, all its children are transformed as well.</td></tr><tr
<tr> class="row5"><th
<td> </td><th> Spatials </th> class="col0 leftalign"> Content:</th><td
</tr> class="col1"> Transformations, mesh, material.</td><td
<tr> class="col2"> Transformations. No mesh, no material.</td></tr><tr
<th> Purpose: </th><td> A Spatial is an abstract data structure that stores transformations (translation, rotation, scale) of elements of the scene graph. A Spatial can be saved and loaded using the AssetManager. </td> class="row6"><th
</tr> class="col0 leftalign"> Examples:</th><td
<tr> class="col1"> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc…</td><td
<td> </td><th> com.jme3.scene.Geometry </th><th> com.jme3.scene.Node </th> class="col2"> The rootNode, the guiNode, an audio node, a custom grouping node, etc…</td></tr></table></div><p> <strong>Important:</strong> You never create a Spatial with <code>Spatial s = new Spatial();</code> – it&#039;s abstract. Instead you create (e.g. load) a Node or Geometry object, and cast it to Spatial. You use the Spatial type in methods that accept both Nodes and Geometries as arguments.</p></div><h3><a
</tr> name="mesh">Mesh</a></h3><div
<tr> class="level3"><p> The polygon <a
<th> Visibility: </th><td> A Geometry represents a visible 3-D object in the scene graph. </td><td> A Node is an invisible “handle” for a group of objects in the scene graph. </td> href="/com/jme3/gde/core/docs/jme3/advanced/mesh.html">Mesh</a> inside a Geometry can be one of three things:</p><ul><li
</tr> class="level1"><div
<tr> class="li"> <strong>Shapes:</strong> The simplest type of Meshes are jME&#039;s default <a
<th> Purpose: </th><td> Use Geometries to represent an object&#039;s looks: Every Geometry contains a polygon mesh and a material, specifying its shape, color, texture, and opacity/transparency. <br/> href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s such as cubes and spheres. You can use several Shapes to build complex Geometries. Shapes are built-in and can be created without using the AssetManager.</div></li><li
You can attach a Geometry to an Node. </td><td> Use nodes to structure and group Geometries and other Nodes. Every Node is attached to parent node, and the node can have children attached to itself. When you transform a parent node, all its children are transformed as well. </td> class="level1"><div
</tr> class="li"> <strong>3D Models:</strong> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D models and scenes</a> are also made up of meshes, but are more complex than Shapes. You create Models and Scenes in external 3D Mesh Editors and export them as Ogre <acronym
<th> Content: </th><td> Transformations, mesh, material. </td><td> Transformations. No mesh, no material.</td> title="Extensible Markup Language">XML</acronym> or Wavefront OBJ. Use the <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a> to load models into a your jME3 game.</div></li><li
<tr> class="level1"><div
<th> Examples: </th><td> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc… </td><td> The rootNode, the guiNode, an audio node, a custom grouping node, etc… </td> class="li"> <strong>Custom Meshes:</strong> Advanced users can create <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">Custom Meshes</a> programmatically.</div></li></ul></div><h2><a
</table> name="how_to_access_a_named_sub-mesh">How to Access a Named Sub-Mesh</a></h2><div
class="level2"><p> Often after you load a scene or model, you need to access a part of it as an individual Geometry in the scene graph. Maybe you want to swap a character&#039;s weapon, or you want to play a door-opening animation. First you need to know the unique name of the sub-mesh.</p><ol><li
<p> class="level1"><div
class="li"> Open the model in a 3D mesh editor, or in the jMonkeyPlatform&#039;s viewer.</div></li><li
<strong>Important:</strong> You never create a Spatial with <code>Spatial s = new Spatial();</code> – it&#039;s abstract. Instead you create (e.g. load) a Node or Geometry object, and cast it to Spatial. You use the Spatial type in methods that accept both Nodes and Geometries as arguments. class="level1"><div
</p> class="li"> Find out the existing names of sub-meshes in the model.</div></li><li
class="level1"><div
</div> class="li"> Assign unique names to sub-meshes in the model if neccessary.</div></li></ol><p> In the following example, the Node <code>house</code> is the loaded model. The sub-meshes in the Node are called its children. The String, here <code>door 12</code>, is the name of the mesh that you are searching.</p><pre>Geometry submesh = &#40;Geometry&#41; houseScene.getChild&#40;&quot;door 12&quot;&#41;;</pre></div>
<h3><a>Mesh</a></h3>
<div>
<p>
The polygon <a href="/com/jme3/gde/core/docs/jme3/advanced/mesh.html">Mesh</a> inside a Geometry can be one of three things:
</p>
<ul>
<li><div> <strong>Shapes:</strong> The simplest type of Meshes are jME&#039;s default <a href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s such as cubes and spheres. You can use several Shapes to build complex Geometries. Shapes are built-in and can be created without using the AssetManager.</div>
</li>
<li><div> <strong>3D Models:</strong> <a href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D models and scenes</a> are also made up of meshes, but are more complex than Shapes. You create Models and Scenes in external 3D Mesh Editors and export them as Ogre <acronym title="Extensible Markup Language">XML</acronym> or Wavefront OBJ. Use the <a href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a> to load models into a your jME3 game.</div>
</li>
<li><div> <strong>Custom Meshes:</strong> Advanced users can create <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">Custom Meshes</a> programmatically.</div>
</li>
</ul>
</div>
<h2><a>How to Access a Named Sub-Mesh</a></h2>
<div>
<p>
Often after you load a scene or model, you need to access a part of it as an individual Geometry in the scene graph. Maybe you want to swap a character&#039;s weapon, or you want to play a door-opening animation. First you need to know the unique name of the sub-mesh.
</p>
<ol>
<li><div> Open the model in a 3D mesh editor, or in the jMonkeyPlatform&#039;s viewer. </div>
</li>
<li><div> Find out the existing names of sub-meshes in the model.</div>
</li>
<li><div> Assign unique names to sub-meshes in the model if neccessary.</div>
</li>
</ol>
<p>
In the following example, the Node <code>house</code> is the loaded model. The sub-meshes in the Node are called its children. The String, here <code>door 12</code>, is the name of the mesh that you are searching.
</p>
<pre>Geometry submesh = &#40;Geometry&#41; houseScene.getChild&#40;&quot;door 12&quot;&#41;;</pre>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:spatial?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:spatial?do=export_xhtmlbody">view online version</a></em></p>

@ -1,164 +1,60 @@
<h1><a
<h1><a>JME3 Canvas in a Swing GUI</a></h1> name="jme3_canvas_in_a_swing_gui">JME3 Canvas in a Swing GUI</a></h1><div
<div> class="level1"><p> 3D games are typically played full-screen, or in a window that takes over the mouse and all inputs. However it is also possible to embed a jME 3 canvas in a standard Swing application. <br/> <br/> This can be useful when you create some sort of interactive 3D viewer with a user interface that is more complex than just a HUD: For instance an interactive scientific demo, a level editor, or a game character designer. <br/> <br/></p><ul><li
class="level1"><div
<p> class="li"> Advantages:</div><ul><li
class="level2"><div
3D games are typically played full-screen, or in a window that takes over the mouse and all inputs. However it is also possible to embed a jME 3 canvas in a standard Swing application. class="li"> You can use Swing components (frame, panels, menus, controls) next to your jME3 game.</div></li><li
</p> class="level2"><div
class="li"> The NetBeans <acronym
<p> title="Graphical User Interface">GUI</acronym> builder is compatible with the jMonkeyEngine; you can use it it to lay out the Swing <acronym
This can be useful when you create some sort of interactive 3D viewer with a user interface that is more complex than just a HUD: For instance an interactive scientific demo, a level editor, or a game character designer. title="Graphical User Interface">GUI</acronym> frame, and then add() the jME canvas into it. Install the <acronym
title="Graphical User Interface">GUI</acronym> builder via Tools → Plugins → Available Plugins.</div></li></ul></li><li
</p> class="level1"><div
<ul> class="li"> Disadvantages:</div><ul><li
<li><div> Advantages: </div> class="level2"><div
<ul> class="li"> You cannot use SimpleApplication&#039;s default mouse capturing for camera navigation, but have to come up with a custom solution.</div></li></ul></li></ul><p> Here is the full <a
<li><div> You can use Swing components (frame, panels, menus, controls) next to your jME3 game. </div> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/awt/TestCanvas.java">TestCanvas.java</a> code sample.</p></div><h2><a
</li> name="extending_simpleapplication">Extending SimpleApplication</a></h2><div
<li><div> The NetBeans <acronym title="Graphical User Interface">GUI</acronym> builder is compatible with the jMonkeyEngine; you can use it it to lay out the Swing <acronym title="Graphical User Interface">GUI</acronym> frame, and then add() the jME canvas into it. Install the <acronym title="Graphical User Interface">GUI</acronym> builder via Tools → Plugins → Available Plugins.</div> class="level2"><p> You start out just the same as for any jME3 game: The base application, here SwingCanvasTest, extends <code>com.jme3.app.SimpleApplication</code>. As usual, you use <code>simpleInitApp()</code> to initialize the scene, and <code>simpleUpdate()</code> as event loop. <br/> <br/> The camera&#039;s default behaviour in SimpleApplication is to capture the mouse, which doesn&#039;t make sense in a Swing window. You have to deactivate and replace this behaviour by <code>flyCam.setDragToRotate(true);</code> when you initialize the application:</p><pre>public void simpleInitApp&#40;&#41; &#123;
</li>
</ul>
</li>
<li><div> Disadvantages:</div>
<ul>
<li><div> You cannot use SimpleApplication&#039;s default mouse capturing for camera navigation, but have to come up with a custom solution.</div>
</li>
</ul>
</li>
</ul>
<p>
Here is the full <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/app/SwingCanvasTest.java?r=5796"><param name="text" value="<html><u>SwingCanvasTest.java</u></html>"><param name="textColor" value="blue"></object> code sample, contributed by pgi.
</p>
</div>
<h2><a>Extending SimpleApplication</a></h2>
<div>
<p>
You start out just the same as for any jME3 game: The base application, here SwingCanvasTest, extends <code>com.jme3.app.SimpleApplication</code>. As usual, you use <code>simpleInitApp()</code> to initialize the scene, and <code>simpleUpdate()</code> as event loop.
</p>
<p>
The camera&#039;s default behaviour in SimpleApplication is to capture the mouse, which doesn&#039;t make sense in a Swing window. You have to deactivate and replace this behaviour by <code>flyCam.setDragToRotate(true);</code> when you initialize the application:
</p>
<pre>public void simpleInitApp&#40;&#41; &#123;
// activate windowed input behaviour // activate windowed input behaviour
flyCam.setDragToRotate&#40;true&#41;; flyCam.setDragToRotate&#40;true&#41;;
&nbsp;
// Set up inputs and load your scene as usual // Set up inputs and load your scene as usual
... ...
&#125;</pre> &#125;</pre><p> In short: The first thing that is different is the <code>main()</code> method. We don&#039;t call start() on the SwingCanvasTest object as usual. Instead we create a Runnable() that creates and opens a standard Swing jFrame. In the runnable, we also create our SwingCanvasTest game with special settings, create a Canvas for it, and add that to the jFrame. Then we call startCanvas().</p></div><h2><a
<p> name="main_and_runnable">Main() and Runnable()</a></h2><div
In short: The first thing that is different is the <code>main()</code> method. We don&#039;t call start() on the SwingCanvasTest object as usual. Instead we create a Runnable() that creates and opens a standard Swing jFrame. In the runnable, we also create our SwingCanvasTest game with special settings, create a Canvas for it, and add that to the jFrame. Then we call startCanvas(). class="level2"><p> The Swing isn&#039;t thread-safe and doesn&#039;t allow us to keep the jME3 canvas up-to-date. This is why we create a runnable for the jME canvas and queue it in the AWT event thread, so it can be invoked &quot;later&quot; in the loop, when Swing is ready with updating its own stuff. <br/> <br/> In the SwingCanvasTest&#039;s main() method, create a queued runnable(). It will contain the jME canvas and the Swing frame.</p><pre> public static void main&#40;String&#91;&#93; args&#41; &#123;
</p>
</div>
<h2><a>Main() and Runnable()</a></h2>
<div>
<p>
The Swing isn&#039;t thread-save and doesn&#039;t allow us to keep the jME3 canvas up-to-date. This is why we create a runnable for the jME canvas and queue it in the AWT event thread, so it can be invoked “later” in the loop, when Swing is ready with updating its own stuff.
</p>
<p>
In the SwingCanvasTest&#039;s main() method, create a queued runnable(). It will contain the jME canvas and the Swing frame.
</p>
<pre> public static void main&#40;String&#91;&#93; args&#41; &#123;
java.awt.Runnable&#40;&#41; &#123; java.awt.Runnable&#40;&#41; &#123;
public void run&#40;&#41; &#123; public void run&#40;&#41; &#123;
// ... see below ... // ... see below ...
&#125; &#125;
&#125;&#41;; &#125;&#41;;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="creating_the_canvas">Creating the Canvas</a></h3><div
class="level3"><p> Here in the <code>run()</code> method, we start the jME application, create its canvas, create a Swing frame, and add everything together. <br/> <br/> Specify the com.jme3.system.AppSettings so jME knows the size of the Swing panel that we put it into. The application will not ask the user for display settings, you have to specify them in advance.</p><pre>AppSettings settings = new AppSettings&#40;true&#41;;
<h3><a>Creating the Canvas</a></h3>
<div>
<p>
Here in the <code>run()</code> method, we start the jME application, create its canvas, create a Swing frame, and add everything together.
</p>
<p>
Specify the com.jme3.system.AppSettings so jME knows the size of the Swing panel that we put it into. The application will not ask the user for display settings, you have to specify them in advance.
</p>
<pre>AppSettings settings = new AppSettings&#40;true&#41;;
settings.setWidth&#40;640&#41;; settings.setWidth&#40;640&#41;;
settings.setHeight&#40;480&#41;;</pre> settings.setHeight&#40;480&#41;;</pre><p> We create our canvas application SwingCanvasTest, and give it the settings. We manually create a canvas for this game and configure the com.jme3.system.JmeCanvasContext. The method setSystemListener() makes sure that the listener receives events relating to context creation, update, and destroy.</p><pre>SwingCanvasTest canvasApplication = new SwingCanvasTest&#40;&#41;;
<p>
We create our canvas application SwingCanvasTest, and give it the settings. We manually create a canvas for this game and configure the com.jme3.system.JmeCanvasContext. The method setSystemListener() makes sure that the listener receives events relating to context creation, update, and destroy.
</p>
<pre>SwingCanvasTest canvasApplication = new SwingCanvasTest&#40;&#41;;
canvasApplication.setSettings&#40;settings&#41;; canvasApplication.setSettings&#40;settings&#41;;
canvasApplication.createCanvas&#40;&#41;; // create canvas! canvasApplication.createCanvas&#40;&#41;; // create canvas!
JmeCanvasContext ctx = &#40;JmeCanvasContext&#41; canvasApplication.getContext&#40;&#41;; JmeCanvasContext ctx = &#40;JmeCanvasContext&#41; canvasApplication.getContext&#40;&#41;;
ctx.setSystemListener&#40;canvasApplication&#41;; ctx.setSystemListener&#40;canvasApplication&#41;;
Dimension&#40;640, 480&#41;; Dimension&#40;640, 480&#41;;
ctx.getCanvas&#40;&#41;.setPreferredSize&#40;dim&#41;;</pre> ctx.getCanvas&#40;&#41;.setPreferredSize&#40;dim&#41;;</pre><p> Note that we have not called start() on the application, as we would usually do in the main() method. We will call startCanvas() later instead.</p></div><h3><a
<p> name="creating_the_swing_frame">Creating the Swing Frame</a></h3><div
Note that we have not called start() on the application, as we would usually do in the main() method. We will call startCanvas() later instead. class="level3"><p> Inside the run() method, you create the Swing window as you would usually do. Create an empty jFrame and add() components to it, or create a custom jFrame object in another class file (for example, by using the NetBeans <acronym
</p> title="Graphical User Interface">GUI</acronym> builder) and create an instance of it here.
Which ever you do, let&#039;s call the jFrame <code>window</code>.</p><pre>JFrame&#40;&quot;Swing Application&quot;&#41;;
</div> window.setDefaultCloseOperation&#40;FlowLayout&#40;&#41;&#41;; // a panel
<h3><a>Creating the Swing Frame</a></h3>
<div>
<p>
Inside the run() method, you create the Swing window as you would usually do. Create an empty jFrame and add() components to it, or create a custom jFrame object in another class file (for example, by using the NetBeans <acronym title="Graphical User Interface">GUI</acronym> builder) and create an instance of it here.
Which ever you do, let&#039;s call the jFrame <code>window</code>.
</p>
<pre>JFrame&#40;&quot;Swing Application&quot;&#41;;
window.setDefaultCloseOperation&#40;JFrame.EXIT_ON_CLOSE&#41;;</pre>
<p>
We create a standard JPanel inside the JFrame. Give it any Layout you wish – here we use a simple Flow Layout. Where the code sample says “Some Swing Component”, this is where you add your buttons and controls.
</p>
<p>
The important step is to add() the canvas component into the panel, like all the other Swing components.
</p>
<pre>FlowLayout&#40;&#41;&#41;; // a panel
// add all your Swing components ... // add all your Swing components ...
panel.add&#40;new JButton&#40;&quot;Some Swing Component&quot;&#41;&#41;; panel.add&#40;new JButton&#40;&quot;Some Swing Component&quot;&#41;&#41;;
... ...
// add the JME canvas // add the JME canvas
panel.add&#40;ctx.getCanvas&#40;&#41;&#41;;</pre> panel.add&#40;ctx.getCanvas&#40;&#41;&#41;;</pre><p> OK, the jFrame and the panel are ready. We add the panel into the jFrame, and pack everything together. Set the window&#039;s visibility to true make it appear.</p><pre>window.add&#40;panel&#41;;
<p>
OK, the jFrame and the panel are ready. We add the panel into the jFrame, and pack everything together. Set the window&#039;s visibility to true make it appear.
</p>
<pre>window.add&#40;panel&#41;;
window.pack&#40;&#41;; window.pack&#40;&#41;;
window.setVisible&#40;true&#41;;</pre> window.setVisible&#40;true&#41;;</pre><p> Remember that we haven&#039;t called start() on the jME appliation yet? For the canvas, there is a special <code>startCanvas()</code> method that you must call now:</p><pre>canvasApplication.startCanvas&#40;&#41;;</pre><p> Clean, build, and run!</p></div><h2><a
<p> name="navigation">Navigation</a></h2><div
Remember that we haven&#039;t called start() on the jME appliation yet? For the canvas, there is a special <code>startCanvas()</code> method that you must call now: class="level2"><p> Remember, to navigate in the scene, click and drag (!) the mouse, or press the WASD keys. Depending on your game you may even want to define custom inputs to handle navigation in this untypical environment.</p><div
</p> class="tags"><span> <a
<pre>canvasApplication.startCanvas&#40;&#41;;</pre> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<p> href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a> </span></div></div>
Clean, build, and run!
</p>
</div>
<h2><a>Navigation</a></h2>
<div>
<p>
Remember, to navigate in the scene, click and drag (!) the mouse, or press the WASD keys. Depending on your game you may even want to define custom inputs to handle navigation in this untypical environment.
</p>
<div><span>
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:swing_canvas?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:swing_canvas?do=export_xhtmlbody">view online version</a></em></p>

@ -1,115 +1,54 @@
<h1><a
<h1><a>TerraMonkey - jME3&#039;s Terrain System</a></h1> name="terramonkey_-_jme3_s_terrain_system">TerraMonkey - jME3&#039;s Terrain System</a></h1><div
<div> class="level1"><p> The goal of TerraMonkey is to provide a base implementation that will be usable for 80% of people&#039;s goals, while providing tools and a good foundation for the other 20% to build off of.</p></div><h2><a
name="overview">Overview</a></h2><div
<p> class="level2"><p> TerraMonkey is a GeoMipMapping quad tree of terrain tiles that supports real time editing and texture splatting. That&#039;s a mouth full! Lets look at each part:</p><ul><li
class="level1"><div
The goal of TerraMonkey is to provide a base implementation that will be usable for 80% of people&#039;s goals, while providing tools and a good foundation for the other 20% to build off of. class="li"> <strong>GeoMipMapping:</strong> a method of changing the level of detail (LOD) of geometry tiles based on how far away they are from the camera. Between the edges of two tiles, it will seam those edges together so you don&#039;t get gaps or holes. For an in-depth read on how it works, here is a pdf <a
</p> href="http://www.flipcode.com/archives/article_geomipmaps.pdf">http://www.flipcode.com/archives/article_geomipmaps.pdf</a>.</div></li><li
class="level1"><div
</div> class="li"> <strong>Quad Tree:</strong> The entire terrain structure is made up of TerrainPatches (these hold the actual meshes) as leaves in a quad tree (TerrainQuad). TerrainQuads are subdivided by 4 until they reach minimum size, then a TerrainPatch is created, and that is where the actual geometry mesh lives. This allows for fast culling of the terrain that you can&#039;t see.</div></li><li
class="level1"><div
<h2><a>Overview</a></h2> class="li"> <strong>Splatting:</strong> The ability to paint multiple textures onto your terrain. What differs here from JME2 is that this is all done in a shader, no more render passes. So it performs much faster.</div></li><li
<div> class="level1"><div
class="li"> <strong>Real-time editing:</strong> TerraMonkey will be editable in JMonkeyPlatform, and you will be able to do it in real time: raising and lowering terrain.</div></li></ul></div><h2><a
<p> name="current_features">Current Features:</a></h2><div
class="level2"><ul><li
TerraMonkey is a GeoMipMapping quad tree of terrain tiles that supports real time editing and texture splatting. That&#039;s a mouth full! Lets look at each part: class="level1"><div
</p> class="li"> Support for up to 3 splat textures.</div></li><li
<ul> class="level1"><div
<li><div> <strong>GeoMipMapping:</strong> a method of changing the level of detail (LOD) of geometry tiles based on how far away they are from the camera. Between the edges of two tiles, it will seam those edges together so you don&#039;t get gaps or holes. For an in-depth read on how it works, here is a pdf <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.flipcode.com/archives/article_geomipmaps.pdf"><param name="text" value="<html><u>http://www.flipcode.com/archives/article_geomipmaps.pdf</u></html>"><param name="textColor" value="blue"></object>.</div> class="li"> GeoMipMapping</div></li><li
</li> class="level1"><div
<li><div> <strong>Quad Tree:</strong> The entire terrain structure is made up of TerrainPatches (these hold the actual meshes) as leaves in a quad tree (TerrainQuad). TerrainQuads are subdivided by 4 until they reach minimum size, then a TerrainPatch is created, and that is where the actual geometry mesh lives. This allows for fast culling of the terrain that you can&#039;t see.</div> class="li"> can be supplied a heightmap</div></li></ul></div><h2><a
</li> name="planned_features">Planned Features:</a></h2><div
<li><div> <strong>Splatting:</strong> The ability to paint multiple textures onto your terrain. What differs here from JME2 is that this is all done in a shader, no more render passes. So it performs much faster.</div> class="level2"><ul><li
</li> class="level1"><div
<li><div> <strong>Real-time editing:</strong> TerraMonkey will be editable in JMonkeyPlatform, and you will be able to do it in real time: raising and lowering terrain.</div> class="li"> jMonkeyPlatform terrain editor</div></li><li
</li> class="level1"><div
</ul> class="li"> Support for up to 16 splat textures.</div></li><li
class="level1"><div
</div> class="li"> Hydraulic erosion and procedural texture generation</div></li><li
class="level1"><div
<h2><a>Current Features:</a></h2> class="li"> Streaming terrain (ie. &quot;infinite&quot; terrain)</div></li><li
<div> class="level1"><div
<ul> class="li"> Holes: caves, cliffs</div></li></ul></div><h2><a
<li><div> Support for up to 3 splat textures.</div> name="geo_mip_mapping">Geo Mip Mapping</a></h2><div
</li> class="level2"><p> You have seen GeoMipMapping implemented in games before. This is where the farther away terrain has fewer polygons, and as you move closer, more polygons fill in. The whole terrain is divided into a grid of patches, and each one has its own LOD. The GeoMipMapping algorithm will look at each patch, and its neighbours, to determine how to render the geometry. It will seam the edges between two patches with different LOD.
<li><div> GeoMipMapping</div> This often leads to &quot;popping&quot; where you see the terrain switch from one LOD to another. TerraMonkey has been designed so you can swap out different LOD calculation algorithms based on what will look best for your game.
</li>
<li><div> can be supplied a heightmap</div>
</li>
</ul>
</div>
<h2><a>Planned Features:</a></h2>
<div>
<ul>
<li><div> jMonkeyPlatform terrain editor</div>
</li>
<li><div> Support for up to 16 splat textures.</div>
</li>
<li><div> Hydraulic erosion and procedural texture generation</div>
</li>
<li><div> Streaming terrain (ie. “infinite” terrain)</div>
</li>
<li><div> Holes: caves, cliffs</div>
</li>
</ul>
</div>
<h2><a>Geo Mip Mapping</a></h2>
<div>
<p>
You have seen GeoMipMapping implemented in games before. This is where the farther away terrain has fewer polygons, and as you move closer, more polygons fill in. The whole terrain is divided into a grid of patches, and each one has its own LOD. The GeoMipMapping algorithm will look at each patch, and its neighbours, to determine how to render the geometry. It will seam the edges between two patches with different LOD.
This often leads to “popping” where you see the terrain switch from one LOD to another. TerraMonkey has been designed so you can swap out different LOD calculation algorithms based on what will look best for your game.
You can do this with the LodCalculator interface. You can do this with the LodCalculator interface.
GeoMipMapping in TerraMonkey has been split into several parts: the terrain quad tree, and the LODGeomap. The geomap deals with the actual LOD and seaming algorithm. So if you want a different data structure for your terrain system, you can re-use this piece of code. GeoMipMapping in TerraMonkey has been split into several parts: the terrain quad tree, and the LODGeomap. The geomap deals with the actual LOD and seaming algorithm. So if you want a different data structure for your terrain system, you can re-use this piece of code.
The quad tree (TerrainQuad and TerrainPatch) provide a means to organize the LODGeomaps, notify them of their neighbour&#039;s LOD change, and to update the geometry when the LOD does change. The quad tree (TerrainQuad and TerrainPatch) provide a means to organize the LODGeomaps, notify them of their neighbour&#039;s LOD change, and to update the geometry when the LOD does change.
To change the LOD it does this by changing the index buffer of the triangle strip, so the whole geometry doesn&#039;t have to be re-loaded onto the video card. To change the LOD it does this by changing the index buffer of the triangle strip, so the whole geometry doesn&#039;t have to be re-loaded onto the video card.</p><p> If you are eager, you can read up more detail how GeoMipMapping works here: <a
</p> href="http://www.flipcode.com/archives/article_geomipmaps.pdf">www.flipcode.com/archives/article_geomipmaps.pdf</a></p></div><h2><a
name="terrain_quad_tree">Terrain Quad Tree</a></h2><div
<p> class="level2"><p> TerraMonkey is a quad tree. Each node is a TerrainQuad, and each leaf is a TerrainPatch. A TerrainQuad has either 4 child TerrainQuads, or 4 child TerrainPatches. The TerrainPatch holds the actual mesh geometry. This structure is almost exactly the same as JME2&#039;s TerrainPage system. Except now each leaf has a reference to its neighbours, so it doesn&#039;t ever have to traverse the tree to get them.</p></div><h2><a
If you are eager, you can read up more detail how GeoMipMapping works here: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.flipcode.com/archives/article_geomipmaps.pdf"><param name="text" value="<html><u>www.flipcode.com/archives/article_geomipmaps.pdf</u></html>"><param name="textColor" value="blue"></object> name="texture_splatting">Texture Splatting</a></h2><div
</p> class="level2"><p> The default material for TerraMonkey is Terrain.j3md. This material combines an alphamap with several textures to produce the final texture.
</div>
<h2><a>Terrain Quad Tree</a></h2>
<div>
<p>
TerraMonkey is a quad tree. Each node is a TerrainQuad, and each leaf is a TerrainPatch. A TerrainQuad has either 4 child TerrainQuads, or 4 child TerrainPatches. The TerrainPatch holds the actual mesh geometry. This structure is almost exactly the same as JME2&#039;s TerrainPage system. Except now each leaf has a reference to its neighbours, so it doesn&#039;t ever have to traverse the tree to get them.
</p>
</div>
<h2><a>Texture Splatting</a></h2>
<div>
<p>
The default material for TerraMonkey is Terrain.j3md. This material combines an alphamap with several textures to produce the final texture.
Right now there is support for only 3 textures and an alpha map. This is in place until we finish the terrain editor in JMP, and then the texture support will be 16 textures. Right now there is support for only 3 textures and an alpha map. This is in place until we finish the terrain editor in JMP, and then the texture support will be 16 textures.
It is only 3 right now so you can hand-paint them in a drawing program, like Photoshop, setting each splat texture in either Red, Green, or Blue. The test case has an example texture to show you how this works. It is only 3 right now so you can hand-paint them in a drawing program, like Photoshop, setting each splat texture in either Red, Green, or Blue. The test case has an example texture to show you how this works.</p><p> Along with getting more splat texture support, we will be adding in lighting and normal mapping support. The normal mapping isn&#039;t fully planned out yet. We need to decide how we are going to handle a normal map for each texture that is passed in. That could generate some very odd effects.
</p> Thoughts, ideas, and recommendations are appreciated!</p></div><h2><a
name="code_sample">Code Sample</a></h2><div
<p> class="level2"><p> First, we load our textures and the heightmap texture for the terrain</p><pre>// Create material from Terrain Material Definition
Along with getting more splat texture support, we will be adding in lighting and normal mapping support. The normal mapping isn&#039;t fully planned out yet. We need to decide how we are going to handle a normal map for each texture that is passed in. That could generate some very odd effects.
Thoughts, ideas, and recommendations are appreciated!
</p>
</div>
<h2><a>Code Sample</a></h2>
<div>
<p>
First, we load our textures and the heightmap texture for the terrain
</p>
<pre>// Create material from Terrain Material Definition
matRock = new Material&#40;assetManager, &quot;Common/MatDefs/Terrain/Terrain.j3md&quot;&#41;; matRock = new Material&#40;assetManager, &quot;Common/MatDefs/Terrain/Terrain.j3md&quot;&#41;;
// Load alpha map (for splat textures) // Load alpha map (for splat textures)
matRock.setTexture&#40;&quot;m_Alpha&quot;, assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/alphamap.png&quot;&#41;&#41;; matRock.setTexture&#40;&quot;m_Alpha&quot;, assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/alphamap.png&quot;&#41;&#41;;
@ -132,27 +71,16 @@ matRock.setFloat&#40;&quot;m_Tex2Scale&quot;, 32f&#41;;
Texture rock = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/road.jpg&quot;&#41;; Texture rock = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/road.jpg&quot;&#41;;
rock.setWrap&#40;WrapMode.Repeat&#41;; rock.setWrap&#40;WrapMode.Repeat&#41;;
matRock.setTexture&#40;&quot;m_Tex3&quot;, rock&#41;; matRock.setTexture&#40;&quot;m_Tex3&quot;, rock&#41;;
matRock.setFloat&#40;&quot;m_Tex3Scale&quot;, 128f&#41;;</pre> matRock.setFloat&#40;&quot;m_Tex3Scale&quot;, 128f&#41;;</pre><p> We create the heightmap from the <code>heightMapImage</code>.</p><pre>AbstractHeightMap heightmap = null;
<p>
We create the heightmap from the <code>heightMapImage</code>.
</p>
<pre>AbstractHeightMap heightmap = null;
heightmap = new ImageBasedHeightMap&#40; heightmap = new ImageBasedHeightMap&#40;
ImageToAwt.convert&#40;heightMapImage.getImage&#40;&#41;, false, true, 0&#41;, 1f&#41;; ImageToAwt.convert&#40;heightMapImage.getImage&#40;&#41;, false, true, 0&#41;, 1f&#41;;
heightmap.load&#40;&#41;;</pre> heightmap.load&#40;&#41;;</pre><p> Next we create the actual terrain.</p><ul><li
<p> class="level1"><div
class="li"> The terrain tiles are 65x65.</div></li><li
Next we create the actual terrain. class="level1"><div
</p> class="li"> The total size of the terrain is 513x513, but it can easily be up to 1025x1025.</div></li><li
<ul> class="level1"><div
<li><div> The terrain tiles are 65&times;65.</div> class="li"> It uses the heightmap to generate the height values.</div></li></ul><pre>terrain = new TerrainQuad&#40;&quot;terrain&quot;, 65, 513, heightmap.getHeightMap&#40;&#41;&#41;;
</li>
<li><div> The total size of the terrain is 513&times;513, but it can easily be up to 1025&times;1025.</div>
</li>
<li><div> It uses the heightmap to generate the height values.</div>
</li>
</ul>
<pre>terrain = new TerrainQuad&#40;&quot;terrain&quot;, 65, 513, heightmap.getHeightMap&#40;&#41;&#41;;
terrain.setMaterial&#40;matRock&#41;; terrain.setMaterial&#40;matRock&#41;;
terrain.setModelBound&#40;new BoundingBox&#40;&#41;&#41;; terrain.setModelBound&#40;new BoundingBox&#40;&#41;&#41;;
terrain.updateModelBound&#40;&#41;; terrain.updateModelBound&#40;&#41;;
@ -163,10 +91,5 @@ cameras.add&#40;getCamera&#40;&#41;&#41;;
TerrainLodControl control = new TerrainLodControl&#40;terrain, cameras&#41;; TerrainLodControl control = new TerrainLodControl&#40;terrain, cameras&#41;;
terrain.addControl&#40;control&#41;; terrain.addControl&#40;control&#41;;
&nbsp; &nbsp;
rootNode.attachChild&#40;terrain&#41;;</pre> rootNode.attachChild&#40;terrain&#41;;</pre><p> PS: As an alternative to an image-based height map, you can also generate a Hill hightmap:</p><pre>heightmap = new HillHeightMap&#40;1025, 1000, 50, 100, &#40;byte&#41; 3&#41;;</pre></div>
<p>
PS: As an alternative to an image-based height map, you can also generate a Hill hightmap:
</p>
<pre>heightmap = new HillHeightMap&#40;1025, 1000, 50, 100, &#40;byte&#41; 3&#41;;</pre>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:terrain?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:terrain?do=export_xhtmlbody">view online version</a></em></p>

@ -1,76 +1,52 @@
<h1><a
<h1><a>Update Loop</a></h1> name="update_loop">Update Loop</a></h1><div
<div> class="level1"><p> Extending your application from com.jme3.app.<a
href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> provides you with an update loop. This is where you implement your game logic (game mechanics).</p><p> Examples: Here you remote-control NPCs (computer controlled characters), generate game events, and respond to user input.</p><ol><li
<p> class="level1"><div
class="li"> Initialization (<code>simpleInit()</code>)</div></li><li
Extending your application from com.jme3.app.<a href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> provides you with an update loop. This is where you implement your game logic (game mechanics). class="level1"><div
</p> class="li"> If exit is requested, then cleanup and destroy</div></li><li
class="level1"><div
<p> class="li"> <a
Examples: Here you remote-control NPCs (computer controlled characters), generate game events, and respond to user input. href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input handling</a> (listeners)</div></li><li
class="level1"><div
</p> class="li"> Update game state</div><ol><li
<ol> class="level2"><div
<li><div> Initialization (<code>simpleInit()</code>)</div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> update</div></li><li
<li><div> If exit is requested, then cleanup and destroy</div> class="level2"><div
</li> class="li"> User update (<code>simpleUpdate()</code> method)</div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input handling</a> (listeners)</div> class="level2"><div
</li> class="li"> Entity logical update (<a
<li><div> Update game state</div> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a>)</div></li></ol></li><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> update</div> class="li"> render</div><ol><li
</li> class="level2"><div
<li><div> User update (<code>simpleUpdate()</code> method)</div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> rendering</div></li><li
<li><div> Entity logical update (<a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a>)</div> class="level2"><div
</li> class="li"> Scene rendering</div></li><li
</ol> class="level2"><div
</li> class="li"> User rendering (<code>simpleRender()</code> method)</div></li></ol></li><li
<li><div> render</div> class="level1"><div
<ol> class="li"> Repeat (goto 2)</div></li></ol></div><h2><a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> rendering</div> name="usage">Usage</a></h2><div
</li> class="level2"><p> Use…</p><ul><li
<li><div> Scene rendering</div> class="level1"><div
</li> class="li"> <a
<li><div> User rendering (<code>simpleRender()</code> method)</div> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> to implement global game mechanics <br/> Example: Physics, Global gameplay control</div></li><li
</li> class="level1"><div
</ol> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> to implement entity behavior <br/> Example: Enemy AI</div></li><li
<li><div> Repeat (goto 2)</div> class="level1"><div
</li> class="li"> <code>simpleUpdate()</code> to implement the rest, or for testing during development.</div></li></ul><div
</ol> class="tags"><span> <a
href="/wiki/doku.php/tag:basegame?do=showtag&amp;tag=tag%3Abasegame">basegame</a>, <a
</div> href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>, <a
href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<h2><a>Usage</a></h2> href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>, <a
<div> href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>, <a
<p> href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>, <a
href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a> </span></div></div>
Use…
</p>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> to implement global game mechanics <br/>
Example: Physics, Global gameplay control</div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> to implement entity behavior <br/>
Example: Enemy AI</div>
</li>
<li><div> <code>simpleUpdate()</code> to implement the rest, or for testing during development.</div>
</li>
</ul>
<div><span>
<a href="/wiki/doku.php/tag:basegame?do=showtag&amp;tag=tag%3Abasegame">basegame</a>,
<a href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>,
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>,
<a href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>,
<a href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:update_loop?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:update_loop?do=export_xhtmlbody">view online version</a></em></p>

@ -1,198 +1,89 @@
<h1><a
<h1><a>Controlling a Physical Vehicle</a></h1> name="controlling_a_physical_vehicle">Controlling a Physical Vehicle</a></h1><div
<div> class="level1"><p> For physical vehicles, jME&#039;s uses the jBullet ray-cast vehicle. In this vehicle implementation, the physical chassis &#039;floats&#039; along on four non-physical vertical rays.</p><p> Internally, each wheel casts a ray down, and using the ray&#039;s intersection point, jBullet calculates the suspension length, and the suspension force. The suspension force is applied to the chassis, keeping it from hitting the ground. The friction force is calculated for each wheel where the ray intersects with the ground. Friction is applied as a sideways and forwards force. <sup><a
href="#fn__1">1)</a></sup></p><p> This article shows how you use this vehicle implementation in a jME3 application.</p><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:physics-vehicle.png?id=jme3%3Aadvanced%3Avehicles"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/physics-vehicle.png" class="mediacenter" alt="" /></a></p></div><h2><a
For physical vehicles, jME&#039;s uses the jBullet ray-cast vehicle. In this vehicle implementation, the physical chassis &#039;floats&#039; along on four non-physical vertical rays. name="sample_code">Sample Code</a></h2><div
</p> class="level2"><p> Full code samples are here:</p><ul><li
class="level1"><div
<p> class="li"> <a
Internally, each wheel casts a ray down, and using the ray&#039;s intersection point, jBullet calculates the suspension length, and the suspension force. The suspension force is applied to the chassis, keeping it from hitting the ground. The friction force is calculated for each wheel where the ray intersects with the ground. Friction is applied as a sideways and forwards force. <sup><a href="#fn__1">1)</a></sup> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCar.java">TestPhysicsCar.java</a></div></li><li
</p> class="level1"><div
class="li"> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java">TestFancyCar.java</a></div></li></ul></div><h2><a
This article shows how you use this vehicle implementation in a jME3 application. name="overview_of_this_physics_application">Overview of this Physics Application</a></h2><div
</p> class="level2"><p> The goal is to create a physical vehicle with wheels that can be steered and that interacts (collides with) with the floor and obstacles.</p><ol><li
class="level1"><div
<p> class="li"> Create a SimpleApplication with a <a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/physics-vehicle.png"> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a></div><ul><li
</p> class="level2"><div
class="li"> This gives us a PhysicsSpace for PhysicsNodes</div></li></ul></li><li
</div> class="level1"><div
class="li"> Create a VehicleControl + CompoundCollisionShape for the physical vehicle behaviour</div><ol><li
<h2><a>Sample Code</a></h2> class="level2"><div
<div> class="li"> Set physical properties of the vehicle, such as suspension.</div></li></ol></li><li
class="level1"><div
<p> class="li"> Create a VehicleNode for the car model</div><ol><li
class="level2"><div
Full code samples are here: class="li"> Create a box plus 4 cylinders as wheels (using <code>vehicle.addWheel()</code>).</div></li><li
class="level2"><div
</p> class="li"> Add the VehicleControl behaviour to the VehicleNode geometry.</div></li></ol></li><li
<ul> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCar.java"><param name="text" value="<html><u>TestPhysicsCar.java</u></html>"><param name="textColor" value="blue"></object></div> class="li"> Create a RigidBodyControl and CollisionShape for the floor</div></li><li
</li> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java"><param name="text" value="<html><u>TestFancyCar.java</u></html>"><param name="textColor" value="blue"></object></div> class="li"> Map key triggers and add input listeners</div><ul><li
</li> class="level2"><div
</ul> class="li"> Navigational commands Left, Right, Foward, Brake.</div></li></ul></li><li
class="level1"><div
</div> class="li"> Define the steering actions to be triggered by the key events.</div><ul><li
class="level2"><div
<h2><a>Overview of this Physics Application</a></h2> class="li"> <code>vehicle.steer()</code></div></li><li
<div> class="level2"><div
class="li"> <code>vehicle.accelerate()</code></div></li><li
<p> class="level2"><div
class="li"> <code>vehicle.brake()</code></div></li></ul></li></ol></div><h2><a
The goal is to create a physical vehicle with wheels that can be steered and that interacts (collides with) with the floor and obstacles. name="creating_the_vehicle_chassis">Creating the Vehicle Chassis</a></h2><div
class="level2"><p> The vehicle that we create here in the <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCar.java">TestPhysicsCar.java</a> example is just a &quot;box on wheels&quot;, a basic vehicle shape that you can replace with a fancy car model, as demonstrated in <a
<ol> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java">TestFancyCar.java</a>.</p><p> Every physical object must have a collision shape, that we prepare first. For the vehicle, we choose a compound collision shape that is made up of a box-shaped body of the right size for the vehicle. We will add the wheels later.</p><pre>CompoundCollisionShape compoundShape = new CompoundCollisionShape&#40;&#41;;
<li><div> Create a SimpleApplication with a <a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a> </div> BoxCollisionShape box = new BoxCollisionShape&#40;new Vector3f&#40;1.2f, 0.5f, 2.4f&#41;&#41;;</pre><p> <strong>Best Practice:</strong> We attach the BoxCollisionShape (the vehicle body) to the CompoundCollisionShape at a Vector of (0,1,0): This shifts the effective center of mass of the BoxCollisionShape downwards to 0,-1,0 and makes a moving vehicle more stable!</p><pre>compoundShape.addChildShape&#40;box, new Vector3f&#40;0, 1, 0&#41;&#41;;</pre><p> Any kind of geometry can make up the visible part of the vehicle, here we use a wireframe box. We create a node that we use to group the geometry.</p><pre> Node vehicleNode=new Node&#40;&quot;vehicleNode&quot;&#41;;
<ul>
<li><div> This gives us a PhysicsSpace for PhysicsNodes</div>
</li>
</ul>
</li>
<li><div> Create a VehicleControl + CompoundCollisionShape for the physical vehicle behaviour</div>
<ol>
<li><div> Set physical properties of the vehicle, such as suspension.</div>
</li>
</ol>
</li>
<li><div> Create a VehicleNode for the car model</div>
<ol>
<li><div> Create a box plus 4 cylinders as wheels (using <code>vehicle.addWheel()</code>).</div>
</li>
<li><div> Add the VehicleControl behaviour to the VehicleNode geometry.</div>
</li>
</ol>
</li>
<li><div> Create a RigidBodyControl and CollisionShape for the floor</div>
</li>
<li><div> Map key triggers and add input listeners</div>
<ul>
<li><div> Navigational commands Left, Right, Foward, Brake.</div>
</li>
</ul>
</li>
<li><div> Define the steering actions to be triggered by the key events.</div>
<ul>
<li><div> <code>vehicle.steer()</code></div>
</li>
<li><div> <code>vehicle.accelerate()</code></div>
</li>
<li><div> <code>vehicle.brake()</code></div>
</li>
</ul>
</li>
</ol>
</div>
<h2><a>Creating the Vehicle Chassis</a></h2>
<div>
<p>
The vehicle that we create here in the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCar.java"><param name="text" value="<html><u>TestPhysicsCar.java</u></html>"><param name="textColor" value="blue"></object> example is just a “box on wheels”, a basic vehicle shape that you can replace with a fancy car model, as demonstrated in <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java"><param name="text" value="<html><u>TestFancyCar.java</u></html>"><param name="textColor" value="blue"></object>.
</p>
<p>
Every physical object must have a collision shape, that we prepare first. For the vehicle, we choose a compound collision shape that is made up of a box-shaped body of the right size for the vehicle. We will add the wheels later.
</p>
<pre>CompoundCollisionShape compoundShape = new CompoundCollisionShape&#40;&#41;;
BoxCollisionShape box = new BoxCollisionShape&#40;new Vector3f&#40;1.2f, 0.5f, 2.4f&#41;&#41;;</pre>
<p>
<strong>Best Practice:</strong> We attach the BoxCollisionShape (the vehicle body) to the CompoundCollisionShape at a Vector of (0,1,0): This shifts the effective center of mass of the BoxCollisionShape downwards to 0,-1,0 and makes a moving vehicle more stable!
</p>
<pre>compoundShape.addChildShape&#40;box, new Vector3f&#40;0, 1, 0&#41;&#41;;</pre>
<p>
Any kind of geometry can make up the visible part of the vehicle, here we use a wireframe box. We create a node that we use to group the geometry.
</p>
<pre> Node vehicleNode=new Node&#40;&quot;vehicleNode&quot;&#41;;
vehicle = new VehicleControl&#40;compoundShape, 400&#41;; vehicle = new VehicleControl&#40;compoundShape, 400&#41;;
vehicleNode.addControl&#40;vehicle&#41;;</pre> vehicleNode.addControl&#40;vehicle&#41;;</pre><p> We initialize the Vehicle Control with the compound shape, and set its mass to a heavy value, 400f. The Vehicle Control represents the car&#039;s physical behaviour.</p><pre>vehicle = new VehicleControl&#40;compoundShape, 400&#41;;</pre><p> Finally we add the behaviour (VehicleControl) to the visible Geometry (node).</p><pre>vehicleNode.addControl&#40;vehicle&#41;;</pre><p> We configure the physical properties of the vehicle&#039;s suspension: Compresion, Damping, Stiffness, and MaxSuspenionForce. Picking workable values for the wheel suspension can be tricky – for background info have a look at these <a
<p> href="https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en">Suspension Settings Tips</a>. For now, let&#039;s work with the following values:</p><pre> float stiffness = 60.0f;//200=f1 car
We initialize the Vehicle Control with the compound shape, and set its mass to a heavy value, 400f. The Vehicle Control represents the car&#039;s physical behaviour.
</p>
<pre>vehicle = new VehicleControl&#40;compoundShape, 400&#41;;</pre>
<p>
Finally we add the behaviour (VehicleControl) to the visible Geometry (node).
</p>
<pre>vehicleNode.addControl&#40;vehicle&#41;;</pre>
<p>
We configure the physical properties of the vehicle&#039;s suspension: Compresion, Damping, Stiffness, and MaxSuspenionForce. Picking workable values for the wheel suspension can be tricky – for background info have a look at these <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en"><param name="text" value="<html><u>Suspension Settings Tips</u></html>"><param name="textColor" value="blue"></object>. For now, let&#039;s work with the following values:
</p>
<pre> float stiffness = 60.0f;//200=f1 car
float compValue = .3f; //(should be lower than damp) float compValue = .3f; //(should be lower than damp)
float dampValue = .4f; float dampValue = .4f;
vehicle.setSuspensionCompression&#40;compValue * 2.0f * FastMath.sqrt&#40;stiffness&#41;&#41;; vehicle.setSuspensionCompression&#40;compValue * 2.0f * FastMath.sqrt&#40;stiffness&#41;&#41;;
vehicle.setSuspensionDamping&#40;dampValue * 2.0f * FastMath.sqrt&#40;stiffness&#41;&#41;; vehicle.setSuspensionDamping&#40;dampValue * 2.0f * FastMath.sqrt&#40;stiffness&#41;&#41;;
vehicle.setSuspensionStiffness&#40;stiffness&#41;; vehicle.setSuspensionStiffness&#40;stiffness&#41;;
vehicle.setMaxSuspensionForce&#40;10000.0f&#41;;</pre> vehicle.setMaxSuspensionForce&#40;10000.0f&#41;;</pre><p> We now have a node <code>vehicleNode</code> with a visible &quot;car&quot; geometry, which acts like a vehicle. One thing that&#039;s missing are wheels.</p></div><h2><a
<p> name="adding_the_wheels">Adding the Wheels</a></h2><div
We now have a node <code>vehicleNode</code> with a visible “car” geometry, which acts like a vehicle. One thing that&#039;s missing are wheels. class="level2"><p> We create four wheel Geometries and add them to the vehicle. Our wheel geometries are simple, non-physical discs (flat Cylinders), they are just visual decorations. Note that the physical wheel behaviour (the com.jme3.bullet.objects.VehicleWheel objects) is created internally by the <code>vehicle.addWheel()</code> method.</p><p> The <code>addWheel()</code> method sets following properties:</p><ul><li
</p> class="level1"><div
class="li"> Vector3f connectionPoint – Coordinate where the suspension connects to the chassis (internally, this is where the Ray is casted downwards).</div></li><li
</div> class="level1"><div
class="li"> Vector3f direction – Wheel direction is typically a (0,-1,0) vector.</div></li><li
<h2><a>Adding the Wheels</a></h2> class="level1"><div
<div> class="li"> Vector3f axle – Axle direction is typically a (-1,0,0) vector.</div></li><li
class="level1"><div
<p> class="li"> float suspensionRestLength – Suspension rest length in world units</div></li><li
class="level1"><div
We create four wheel Geometries and add them to the vehicle. Our wheel geometries are simple, non-physical discs (flat Cylinders), they are just visual decorations. Note that the physical wheel behaviour (the com.jme3.bullet.objects.VehicleWheel objects) is created internally by the <code>vehicle.addWheel()</code> method. class="li"> float wheelRadius – Wheel radius in world units</div></li><li
</p> class="level1"><div
class="li"> boolean isFrontWheel – Whether this wheel is one of the steering wheels. <br/> Front wheels are the ones that rotate visibly when the vehicle turns.</div></li></ul><p> We initialize a few variables that we will reuse when we add the four wheels. yOff, etc, are the particular wheel offsets for our small vehicle model.</p><pre>Vector3f wheelDirection = new Vector3f&#40;0, -1, 0&#41;;
<p>
The <code>addWheel()</code> method sets following properties:
</p>
<ul>
<li><div> Vector3f connectionPoint – Coordinate where the suspension connects to the chassis (internally, this is where the Ray is casted downwards).</div>
</li>
<li><div> Vector3f direction – Wheel direction is typically a (0,-1,0) vector.</div>
</li>
<li><div> Vector3f axle – Axle direction is typically a (-1,0,0) vector.</div>
</li>
<li><div> float suspensionRestLength – Suspension rest length in world units</div>
</li>
<li><div> float wheelRadius – Wheel radius in world units</div>
</li>
<li><div> boolean isFrontWheel – Whether this wheel is one of the steering wheels. <br/>
Front wheels are the ones that rotate visibly when the vehicle turns.</div>
</li>
</ul>
<p>
We initialize a few variables that we will reuse when we add the four wheels. yOff, etc, are the particular wheel offsets for our small vehicle model.
</p>
<pre>Vector3f wheelDirection = new Vector3f&#40;0, -1, 0&#41;;
Vector3f wheelAxle = new Vector3f&#40;-1, 0, 0&#41;; Vector3f wheelAxle = new Vector3f&#40;-1, 0, 0&#41;;
float radius = 0.5f; float radius = 0.5f;
float restLength = 0.3f; float restLength = 0.3f;
float yOff = 0.5f; float yOff = 0.5f;
float xOff = 1f; float xOff = 1f;
float zOff = 2f;</pre> float zOff = 2f;</pre><p> We create a Cylinder mesh shape that we use to create the four visible wheel geometries.</p><pre>Cylinder wheelMesh = new Cylinder&#40;16, 16, radius, radius * 0.6f, true&#41;;</pre><p> For each wheel, we create a Node and a Geometry. We attach the Cylinder Geometry to the Node. We rotate the wheel by 90° around the Y axis. We set a material to make it visible. Finally we add the wheel (plus its properties) to the vehicle.</p><pre>Node node1 = new Node&#40;&quot;wheel 1 node&quot;&#41;;
<p>
We create a Cylinder mesh shape that we use to create the four visible wheel geometries.
</p>
<pre>Cylinder wheelMesh = new Cylinder&#40;16, 16, radius, radius * 0.6f, true&#41;;</pre>
<p>
For each wheel, we create a Node and a Geometry. We attach the Cylinder Geometry to the Node. We rotate the wheel by 90° around the Y axis. We set a material to make it visible. Finally we add the wheel (plus its properties) to the vehicle.
</p>
<pre>Node node1 = new Node&#40;&quot;wheel 1 node&quot;&#41;;
Geometry wheels1 = new Geometry&#40;&quot;wheel 1&quot;, wheelMesh&#41;; Geometry wheels1 = new Geometry&#40;&quot;wheel 1&quot;, wheelMesh&#41;;
node1.attachChild&#40;wheels1&#41;; node1.attachChild&#40;wheels1&#41;;
wheels1.rotate&#40;0, FastMath.HALF_PI, 0&#41;; wheels1.rotate&#40;0, FastMath.HALF_PI, 0&#41;;
wheels1.setMaterial&#40;mat&#41;; wheels1.setMaterial&#40;mat&#41;;
&nbsp; &nbsp;
vehicle.addWheel&#40;node1, new Vector3f&#40;-xOff, yOff, zOff&#41;, vehicle.addWheel&#40;node1, new Vector3f&#40;-xOff, yOff, zOff&#41;,
wheelDirection, wheelAxle, restLength, radius, true&#41;;</pre> wheelDirection, wheelAxle, restLength, radius, true&#41;;</pre><p> The three next wheels are created in the same fashion, only the offsets are different. Remember to set the Boolean parameter correctly to indicate whether it&#039;s a front wheel.</p><pre>...
<p>
The three next wheels are created in the same fashion, only the offsets are different. Remember to set the Boolean parameter correctly to indicate whether it&#039;s a front wheel.
</p>
<pre>...
vehicle.addWheel&#40;node2, new Vector3f&#40;xOff, yOff, zOff&#41;, vehicle.addWheel&#40;node2, new Vector3f&#40;xOff, yOff, zOff&#41;,
wheelDirection, wheelAxle, restLength, radius, true&#41;; wheelDirection, wheelAxle, restLength, radius, true&#41;;
... ...
@ -200,52 +91,22 @@ vehicle.addWheel&#40;node3, new Vector3f&#40;-xOff, yOff, -zOff&#41;,
wheelDirection, wheelAxle, restLength, radius, false&#41;; wheelDirection, wheelAxle, restLength, radius, false&#41;;
... ...
vehicle.addWheel&#40;node4, new Vector3f&#40;xOff, yOff, -zOff&#41;, vehicle.addWheel&#40;node4, new Vector3f&#40;xOff, yOff, -zOff&#41;,
wheelDirection, wheelAxle, restLength, radius, false&#41;;</pre> wheelDirection, wheelAxle, restLength, radius, false&#41;;</pre><p> Attach the wheel Nodes to the vehicle Node to group them, so they move together.</p><pre>vehicleNode.attachChild&#40;node1&#41;;
<p>
Attach the wheel Nodes to the vehicle Node to group them, so they move together.
</p>
<pre>vehicleNode.attachChild&#40;node1&#41;;
vehicleNode.attachChild&#40;node2&#41;; vehicleNode.attachChild&#40;node2&#41;;
vehicleNode.attachChild&#40;node3&#41;; vehicleNode.attachChild&#40;node3&#41;;
vehicleNode.attachChild&#40;node4&#41;;</pre> vehicleNode.attachChild&#40;node4&#41;;</pre><p> As always, attach the vehicle Node to the rootNode to make it visible, and add the Vehicle Control to the PhysicsSpace to make the car physical.</p><pre>rootNode.attachChild&#40;vehicleNode&#41;;
<p> getPhysicsSpace&#40;&#41;.add&#40;vehicle&#41;;</pre><p> Not shown here is that we also created a Material <code>mat</code>.</p></div><h2><a
As always, attach the vehicle Node to the rootNode to make it visible, and add the Vehicle Control to the PhysicsSpace to make the car physical. name="steering_the_vehicle">Steering the Vehicle</a></h2><div
</p> class="level2"><p> Not shown here is the standard way how we map the input keys to actions (see full code sample). Also refer to <a
<pre>rootNode.attachChild&#40;vehicleNode&#41;; href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input Handling</a>).</p><p> In the ActionListener, we implement the actions that control the vehicle&#039;s direction and speed. For the four directions (accelerate=up, brake=down, left, right), we specify how we want the vehicle to move.</p><ul><li
getPhysicsSpace&#40;&#41;.add&#40;vehicle&#41;;</pre> class="level1"><div
<p> class="li"> The braking action is pretty straightforward: <br/> <code>vehicle.brake(brakeForce)</code></div></li><li
Not shown here is that we also created a Material <code>mat</code>. class="level1"><div
</p> class="li"> For left and right turns, we add a constant to <code>steeringValue</code> when the key is pressed, and subtract it when the key is released. <br/> <code>vehicle.steer(steeringValue);</code></div></li><li
class="level1"><div
</div> class="li"> For acceleration we add a constant to <code>accelerationValue</code> when the key is pressed, and substract it when the key is released. <br/> <code>vehicle.accelerate(accelerationValue);</code></div></li><li
class="level1"><div
<h2><a>Steering the Vehicle</a></h2> class="li"> Because we can and it&#039;s fun, we also add a turbo booster that makes the vehicle jump when you press the assigned key (spacebar). <br/> <code>vehicle.applyImpulse(jumpForce, Vector3f.ZERO);</code></div></li></ul><pre>public void onAction&#40;String binding, boolean value, float tpf&#41; &#123;
<div>
<p>
Not shown here is the standard way how we map the input keys to actions (see full code sample). Also refer to <a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input Handling</a>).
</p>
<p>
In the ActionListener, we implement the actions that control the vehicle&#039;s direction and speed. For the four directions (accelerate=up, brake=down, left, right), we specify how we want the vehicle to move.
</p>
<ul>
<li><div> The braking action is pretty straightforward: <br/>
<code>vehicle.brake(brakeForce)</code></div>
</li>
<li><div> For left and right turns, we add a constant to <code>steeringValue</code> when the key is pressed, and subtract it when the key is released. <br/>
<code>vehicle.steer(steeringValue);</code></div>
</li>
<li><div> For acceleration we add a constant to <code>accelerationValue</code> when the key is pressed, and substract it when the key is released. <br/>
<code>vehicle.accelerate(accelerationValue);</code></div>
</li>
<li><div> Because we can and it&#039;s fun, we also add a turbo booster that makes the vehicle jump when you press the assigned key (spacebar). <br/>
<code>vehicle.applyImpulse(jumpForce, Vector3f.ZERO);</code></div>
</li>
</ul>
<pre>public void onAction&#40;String binding, boolean value, float tpf&#41; &#123;
if &#40;binding.equals&#40;&quot;Lefts&quot;&#41;&#41; &#123; if &#40;binding.equals&#40;&quot;Lefts&quot;&#41;&#41; &#123;
if &#40;value&#41; &#123; if &#40;value&#41; &#123;
steeringValue += .5f; steeringValue += .5f;
@ -288,46 +149,20 @@ In the ActionListener, we implement the actions that control the vehicle&#039;s
&#125; else &#123; &#125; else &#123;
&#125; &#125;
&#125; &#125;
&#125;</pre> &#125;</pre><p> For your reference, this is how we initialized the constants for this example:</p><pre>private final float accelerationForce = 1000.0f;
<p>
For your reference, this is how we initialized the constants for this example:
</p>
<pre>private final float accelerationForce = 1000.0f;
private final float brakeForce = 100.0f; private final float brakeForce = 100.0f;
private float steeringValue = 0; private float steeringValue = 0;
private float accelerationValue = 0; private float accelerationValue = 0;
private Vector3f jumpForce = new Vector3f&#40;0, 3000, 0&#41;;</pre> private Vector3f jumpForce = new Vector3f&#40;0, 3000, 0&#41;;</pre><p> Remember, the standard input listener code that maps the actions to keys can be found in the code samples.</p></div><h2><a
<p> name="detecting_collisions">Detecting Collisions</a></h2><div
Remember, the standard input listener code that maps the actions to keys can be found in the code samples. class="level2"><p> Read the <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/physics#responding_to_a_physicscollisionevent.html">Responding to a PhysicsCollisionEvent</a> chapter in the general physics documentation on how to detect collisions. You would do this if you want to react to collisions with custom events, such as adding points or substracting health.</p></div><h2><a
name="best_practices">Best Practices</a></h2><div
</div> class="level2"><p> This example shows a very simple but functional vehicle. For a game you would implement steering behaviour and acceleration with values that are typical for the type of vehicle that you want to simulate. Instead of a box, you load a chassis model. You can consider using an <a
href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">AnalogListener</a> to respond to key events in a more sophisticated way.</p><p> For a more advanced example, look at <a
<h2><a>Detecting Collisions</a></h2> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java">TestFancyCar.java</a>.</p></div><div
<div> class="footnotes"><div
class="fn"><sup><a
<p> href="#fnt__1">1)</a></sup> <a
href="https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en">https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en</a></div></div>
Read the <a href="/com/jme3/gde/core/docs/jme3/advanced/physics#responding_to_a_physicscollisionevent.html">Responding to a PhysicsCollisionEvent</a> chapter in the general physics documentation on how to detect collisions. You would do this if you want to react to collisions with custom events, such as adding points or substracting health.
</p>
</div>
<h2><a>Best Practices</a></h2>
<div>
<p>
This example shows a very simple but functional vehicle. For a game you would implement steering behaviour and acceleration with values that are typical for the type of vehicle that you want to simulate. Instead of a box, you load a chassis model. You can consider using an <a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">AnalogListener</a> to respond to key events in a more sophisticated way.
</p>
<p>
For a more advanced example, look at <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java"><param name="text" value="<html><u>TestFancyCar.java</u></html>"><param name="textColor" value="blue"></object>.
</p>
</div>
<div>
<div><sup><a href="#fnt__1">1)</a></sup>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en"><param name="text" value="<html><u>https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&amp;hl=en</u></html>"><param name="textColor" value="blue"></object> </div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:vehicles?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:vehicles?do=export_xhtmlbody">view online version</a></em></p>

@ -1,98 +1,54 @@
<h1><a
<h1><a>Walking Character</a></h1> name="walking_character">Walking Character</a></h1><div
<div> class="level1"><p> <strong>Work in progress.</strong></p><p> In other code samples we have seen how to create collidable landscapes and walk around in a first-person perspective, by enclosing the camera with a collision shape.</p><p> Many games however require a third-person perspective of the character. If you load a character model, create a PhysicsControl for it, and use forces to push it around, you may not get the desired effect: Phyical objects often fall over when pushed, and that is not what you expect of a walking character.</p><p> This is why jME3 offers a special CharacterControl to implement walking characters.</p></div><h2><a
name="sample_code">Sample Code</a></h2><div
<p> class="level2"><p> The full code sample can be found here:</p><ul><li
class="level1"><div
<strong>Work in progress.</strong> class="li"> <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java">TestPhysicsCharacter.java</a> (third-person view)</div></li><li
class="level1"><div
<p> class="li"> <a
In other code samples we have seen how to create collidable landscapes and walk around in a first-person perspective, by enclosing the camera with a collision shape. href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java">TestWalkingChar.java</a> (third-person view)</div></li><li
</p> class="level1"><div
class="li"> <a
<p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestQ3.java">TestQ3.java</a> (first-person view)</div></li></ul></div><h2><a
Many games however require a third-person perspective of the character. If you load a character model, create a PhysicsControl for it, and use forces to push it around, you may not get the desired effect: Phyical objects often fall over when pushed, and that is not what you expect of a walking character. name="overview_of_this_physics_application">Overview of this Physics Application</a></h2><div
</p> class="level2"><ol><li
class="level1"><div
<p> class="li"> Create a SimpleApplication with a <a
This is why jME3 offers a special CharacterControl to implement walking characters. href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a></div><ul><li
</p> class="level2"><div
class="li"> This gives us a Physics Space</div></li></ul></li><li
</div> class="level1"><div
class="li"> Load any physical game level model, terrain, or floor</div></li><li
<h2><a>Sample Code</a></h2> class="level1"><div
<div> class="li"> Load an animated character model</div></li><li
class="level1"><div
<p> class="li"> Set up animation channel and controller</div></li><li
class="level1"><div
The full code sample can be found here: class="li"> Add a CharacterControl to the model</div></li></ol></div><h2><a
</p> name="creating_the_character">Creating the Character</a></h2><div
<ul> class="level2"><ol><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java"><param name="text" value="<html><u>TestPhysicsCharacter.java</u></html>"><param name="textColor" value="blue"></object> (third-person view)</div> class="level1"><div
</li> class="li"> Initialze physical character behaviour, including collision shape</div><ol><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestWalkingChar.java"><param name="text" value="<html><u>TestWalkingChar.java</u></html>"><param name="textColor" value="blue"></object> (third-person view)</div> class="level2"><div
</li> class="li"> Create CapsuleCollisionShape of the right size for the model.</div><ul><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestQ3.java"><param name="text" value="<html><u>TestQ3.java</u></html>"><param name="textColor" value="blue"></object> (first-person view)</div> class="level3"><div
</li> class="li"> A Capsule is a cylinder with rounded top and bottom: A good collision shape for a character since it reduces the risk of getting stuck on obstacles.</div></li></ul></li><li
</ul> class="level2"><div
class="li"> Create a CharacterControl from the collision shape</div></li></ol></li><li
</div> class="level1"><div
class="li"> Load the visible character model, and add the physical behaviour to it</div><ol><li
<h2><a>Overview of this Physics Application</a></h2> class="level2"><div
<div> class="li"> Load an animated model (e.g. &quot;Models/Oto/Oto.mesh.xml&quot;).</div></li><li
<ol> class="level2"><div
<li><div> Create a SimpleApplication with a <a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">BulletAppState</a> </div> class="li"> Add the CharacterControl to the character model.</div></li></ol></li><li
<ul> class="level1"><div
<li><div> This gives us a Physics Space</div> class="li"> Make character visible and physical</div><ol><li
</li> class="level2"><div
</ul> class="li"> Attach the model to the rootNode to make it appear in the scene.</div></li><li
</li> class="level2"><div
<li><div> Load any physical game level model, terrain, or floor</div> class="li"> Add the CharacterControl to the PhysicsSpace to make it physical.</div></li></ol></li></ol><pre>// initialze physical character behaviour, including collision shape
</li>
<li><div> Load an animated character model</div>
</li>
<li><div> Set up animation channel and controller</div>
</li>
<li><div> Add a CharacterControl to the model</div>
</li>
</ol>
</div>
<h2><a>Creating the Character</a></h2>
<div>
<ol>
<li><div> Initialze physical character behaviour, including collision shape </div>
<ol>
<li><div> Create CapsuleCollisionShape of the right size for the model.</div>
<ul>
<li><div> A Capsule is a cylinder with rounded top and bottom: A good collision shape for a character since it reduces the risk of getting stuck on obstacles.</div>
</li>
</ul>
</li>
<li><div> Create a CharacterControl from the collision shape</div>
</li>
</ol>
</li>
<li><div> Load the visible character model, and add the physical behaviour to it</div>
<ol>
<li><div> Load an animated model (e.g. “Models/Oto/Oto.mesh.xml”).</div>
</li>
<li><div> Add the CharacterControl to the character model.</div>
</li>
</ol>
</li>
<li><div> Make character visible and physical</div>
<ol>
<li><div> Attach the model to the rootNode to make it appear in the scene.</div>
</li>
<li><div> Add the CharacterControl to the PhysicsSpace to make it physical.</div>
</li>
</ol>
</li>
</ol>
<pre>// initialze physical character behaviour, including collision shape
CapsuleCollisionShape capsule = new CapsuleCollisionShape&#40;3f, 4f&#41;; CapsuleCollisionShape capsule = new CapsuleCollisionShape&#40;3f, 4f&#41;;
CharacterControl character = new CharacterControl&#40;capsule, 0.01f&#41;; CharacterControl character = new CharacterControl&#40;capsule, 0.01f&#41;;
// load the visible character model and add the physical behaviour to it // load the visible character model and add the physical behaviour to it
@ -100,17 +56,9 @@ Node model = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh
model.addControl&#40;character&#41;; model.addControl&#40;character&#41;;
// Make character visible and physical // Make character visible and physical
rootNode.attachChild&#40;model&#41;; // make it visible rootNode.attachChild&#40;model&#41;; // make it visible
getPhysicsSpace&#40;&#41;.add&#40;character&#41;; // make it physical</pre> getPhysicsSpace&#40;&#41;.add&#40;character&#41;; // make it physical</pre></div><h2><a
</div> name="setting_up_the_animation_controller">Setting Up the Animation Controller</a></h2><div
class="level2"><p> We create two AninChannels, for example one for walking, one for shooting. The shootingChannel only controls one arm, while the walking channels controls the whole animation.</p><pre>AnimControl animationControl = model.getControl&#40;AnimControl.class&#41;;
<h2><a>Setting Up the Animation Controller</a></h2>
<div>
<p>
We create two AninChannels, for example one for walking, one for shooting. The shootingChannel only controls one arm, while the walking channels controls the whole animation.
</p>
<pre>AnimControl animationControl = model.getControl&#40;AnimControl.class&#41;;
animationControl.addListener&#40;this&#41;; animationControl.addListener&#40;this&#41;;
&nbsp; &nbsp;
AnimChannel animationChannel = animationControl.createChannel&#40;&#41;; AnimChannel animationChannel = animationControl.createChannel&#40;&#41;;
@ -118,20 +66,7 @@ AnimChannel shootingChannel = animationControl.createChannel&#40;&#41;;
&nbsp; &nbsp;
shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;uparm.right&quot;&#41;&#41;; shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;uparm.right&quot;&#41;&#41;;
shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;arm.right&quot;&#41;&#41;; shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;arm.right&quot;&#41;&#41;;
shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;hand.right&quot;&#41;&#41;;</pre> shootingChannel.addBone&#40;animationControl.getSkeleton&#40;&#41;.getBone&#40;&quot;hand.right&quot;&#41;&#41;;</pre><p> The extra shooting channel exists so the character can lift an arm to shoot and walk at the same time.</p></div><h2><a
<p> name="walking">Walking</a></h2><div
The extra shooting channel exists so the character can lift an arm to shoot and walk at the same time. class="level2"><p> Work in progress (this is being updated for the new physics and chase cam.)</p></div>
</p>
</div>
<h2><a>Walking</a></h2>
<div>
<p>
Work in progress (this is being updated for the new physics and chase cam.)
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:walking_character?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:walking_character?do=export_xhtmlbody">view online version</a></em></p>

@ -1,143 +1,80 @@
<h1><a
<h1><a>SeaMonkey - jME3 Water System</a></h1> name="seamonkey_-_jme3_water_system">SeaMonkey - jME3 Water System</a></h1><div
<div> class="level1"><p> <strong>DRAFT</strong></p><p> Here is some background info for JME3&#039;s frist water implementation, nicknamed SeaMonkey:</p><ul><li
class="level1"><div
<p> class="li"> <a
href="http://www.jmonkeyengine.com/forum/index.php?topic=14740.0">http://www.jmonkeyengine.com/forum/index.php?topic=14740.0</a></div></li><li
<strong>DRAFT</strong> class="level1"><div
</p> class="li"> <a
href="http://www.bonzaisoftware.com/water_tut.html">http://www.bonzaisoftware.com/water_tut.html</a></div></li><li
<p> class="level1"><div
Here is some background info for JME3&#039;s frist water implementation, nicknamed SeaMonkey: class="li"> <a
</p> href="http://www.gametutorials.com/Articles/RealisticWater.pdf">http://www.gametutorials.com/Articles/RealisticWater.pdf</a></div></li></ul><p> <a
<ul> href="/wiki/lib/exe/fetch.php?hash=af543c&amp;media=http%3A%2F%2Fwww.jmonkeyengine.com%2Fwp-content%2Fuploads%2F2010%2F10%2Fsimplewaterdemo.jpg"><img
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/forum/index.php?topic=14740.0"><param name="text" value="<html><u>http://www.jmonkeyengine.com/forum/index.php?topic=14740.0</u></html>"><param name="textColor" value="blue"></object></div> src="/wiki/lib/exe/fetch.php?hash=af543c&amp;w=277&amp;h=180&amp;media=http%3A%2F%2Fwww.jmonkeyengine.com%2Fwp-content%2Fuploads%2F2010%2F10%2Fsimplewaterdemo.jpg" class="mediacenter" title="www.jmonkeyengine.com_wp-content_uploads_2010_10_simplewaterdemo.jpg" alt="www.jmonkeyengine.com_wp-content_uploads_2010_10_simplewaterdemo.jpg" width="277" height="180" /></a></p></div><h2><a
</li> name="simplewaterprocessor">SimpleWaterProcessor</a></h2><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.bonzaisoftware.com/water_tut.html"><param name="text" value="<html><u>http://www.bonzaisoftware.com/water_tut.html</u></html>"><param name="textColor" value="blue"></object></div> class="level2"><p> A JME3 scene with water uses a <code>com.jme3.water.SimpleWaterProcessor</code> (which implements the SceneProcessor interface).</p><p> To achieve a water effect, JME3 uses shaders and a special material, <code>Common/MatDefs/Water/SimpleWater.j3md</code>. The water surface is a quad, and we use normal map and dU/dV map texturing to simulate the waves.</p><ol><li
</li> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.gametutorials.com/Articles/RealisticWater.pdf"><param name="text" value="<html><u>http://www.gametutorials.com/Articles/RealisticWater.pdf</u></html>"><param name="textColor" value="blue"></object></div> class="li"> Every frame, we render to three texture maps:</div><ul><li
</li> class="level2"><div
</ul> class="li"> For the water surface (reflection), we take a snapshot of the environment, flip it upside down, and clip it to the visible water surface. Note that we do not actually use a &quot;water texture&quot; color map: The &quot;texture&quot; of the water is solely a distorted reflection.</div></li><li
class="level2"><div
<p> class="li"> For the &quot;wavy&quot; distortion (refraction), we use the derivative of a normal map, a dU/dV map.</div></li><li
class="level2"><div
<img src="/wiki/lib/exe/fetch.php"> class="li"> For the fogginess of water (depth) we use a depth map from the terrains z-buffer.</div></li></ul></li><li
</p> class="level1"><div
class="li"> In the shaders, we add all of the texture maps together.</div><ul><li
</div> class="level2"><div
class="li"> For the &quot;bumpy&quot; displacement of the waves, we use a normal map and a du/dv map that are shifted against each other over time to create the wave effect.</div></li><li
<h2><a>SimpleWaterProcessor</a></h2> class="level2"><div
<div> class="li"> For the light reflection vectors on the water surface, we use the Fresnel formula, together with normal vectors.</div></li><li
class="level2"><div
<p> class="li"> We add specular lighting.</div></li></ul></li><li
class="level1"><div
A JME3 scene with water uses a <code>com.jme3.water.SimpleWaterProcessor</code> (which implements the SceneProcessor interface). class="li"> (For the underwater caustics effect, we use splatted textures. – TODO)</div></li></ol></div><h2><a
</p> name="usage">Usage</a></h2><div
class="level2"><p> <a
<p> href="/wiki/lib/exe/detail.php/jme3:advanced:simplewater.png?id=jme3%3Aadvanced%3Awater"><img
To achieve a water effect, JME3 uses shaders and a special material, <code>Common/MatDefs/Water/SimpleWater.j3md</code>. The water surface is a quad, and we use normal map and dU/dV map texturing to simulate the waves. src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/simplewater.png?w=384&amp;h=288" class="mediaright" align="right" alt="" width="384" height="288" /></a></p><ol><li
class="level1"><div
</p> class="li"> Create a <code>mainScene</code> Node</div><ol><li
<ol> class="level2"><div
<li><div> Every frame, we render to three texture maps:</div> class="li"> Attach the <code>mainScene</code> Node to the <code>rootNode</code></div></li></ol></li><li
<ul> class="level1"><div
<li><div> For the water surface (reflection), we take a snapshot of the environment, flip it upside down, and clip it to the visible water surface. Note that we do not actually use a “water texture” color map: The “texture” of the water is solely a distorted reflection.</div> class="li"> Load your <code>scene</code> Spatial</div><ol><li
</li> class="level2"><div
<li><div> For the “wavy” distortion (refraction), we use the derivative of a normal map, a dU/dV map.</div> class="li"> Add a light source to the <code>scene</code> Spatial</div></li><li
</li> class="level2"><div
<li><div> For the fogginess of water (depth) we use a depth map from the terrains z-buffer.</div> class="li"> Attach the <code>scene</code> Spatial to the <code>mainScene</code> Node</div></li></ol></li><li
</li> class="level1"><div
</ul> class="li"> Load your <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">sky</a> Geometry</div><ol><li
<li><div> In the shaders, we add all of the texture maps together. </div> class="level2"><div
<ul> class="li"> Attach the sky Geometry to the <code>mainScene</code> Node</div></li></ol></li><li
<li><div> For the “bumpy” displacement of the waves, we use a normal map and a du/dv map that are shifted against each other over time to create the wave effect.</div> class="level1"><div
</li> class="li"> Create the SimpleWaterProcessor <code>waterProcessor</code></div><ol><li
<li><div> For the light reflection vectors on the water surface, we use the Fresnel formula, together with normal vectors.</div> class="level2"><div
</li> class="li"> Set the processor&#039;s ReflectionScene to the <code>mainScene</code> Spatial (!)</div></li><li
<li><div> We add specular lighting.</div> class="level2"><div
</li> class="li"> Set the processor&#039;s Plane to where you want your water surface to be</div></li><li
</ul> class="level2"><div
</li> class="li"> Set the processor&#039;s WaterDepth, DistortionScale, and WaveSpeed</div></li><li
<li><div> (For the underwater caustics effect, we use splatted textures. – TODO)</div> class="level2"><div
</li> class="li"> Attach the processor to the <code>viewPort</code></div></li></ol></li><li
</ol> class="level1"><div
class="li"> Create a Quad <code>quad</code></div><ol><li
</div> class="level2"><div
class="li"> Set the quad&#039;s TextureCoordinates to specify the size of the waves</div></li></ol></li><li
<h2><a>Usage</a></h2> class="level1"><div
<div> class="li"> Create a <code>water</code> Geometry from the Quad</div><ol><li
class="level2"><div
<p> class="li"> Set the water&#039;s translation and rotation (same Y value as Plane above!)</div></li><li
class="level2"><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/advanced/simplewater.png"> class="li"> Set the water&#039;s material to the processor&#039;s output material</div></li><li
class="level2"><div
</p> class="li"> Attach the <code>water</code> Geometry to the <code>rootNode</code>. (Not to the mainScene!)</div></li></ol></li></ol></div><h2><a
<ol> name="sample_code">Sample Code</a></h2><div
<li><div> Create a <code>mainScene</code> Node</div> class="level2"><p> The sample code can be found in <code>jme3/src/jme3test/water/TestSimpleWater.java</code> and <code>jme3/src/jme3test/water/TestSceneWater.java</code>.</p><p> Here is the most important part of the code:</p><pre>// we create a water processor
<ol>
<li><div> Attach the <code>mainScene</code> Node to the <code>rootNode</code></div>
</li>
</ol>
</li>
<li><div> Load your <code>scene</code> Spatial</div>
<ol>
<li><div> Add a light source to the <code>scene</code> Spatial</div>
</li>
<li><div> Attach the <code>scene</code> Spatial to the <code>mainScene</code> Node</div>
</li>
</ol>
</li>
<li><div> Load your <a href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">sky</a> Geometry</div>
<ol>
<li><div> Attach the sky Geometry to the <code>mainScene</code> Node</div>
</li>
</ol>
</li>
<li><div> Create the SimpleWaterProcessor <code>waterProcessor</code></div>
<ol>
<li><div> Set the processor&#039;s ReflectionScene to the <code>mainScene</code> Spatial (!)</div>
</li>
<li><div> Set the processor&#039;s Plane to where you want your water surface to be</div>
</li>
<li><div> Set the processor&#039;s WaterDepth, DistortionScale, and WaveSpeed</div>
</li>
<li><div> Attach the processor to the <code>viewPort</code></div>
</li>
</ol>
</li>
<li><div> Create a Quad <code>quad</code></div>
<ol>
<li><div> Set the quad&#039;s TextureCoordinates to specify the size of the waves</div>
</li>
</ol>
</li>
<li><div> Create a <code>water</code> Geometry from the Quad</div>
<ol>
<li><div> Set the water&#039;s translation and rotation (same Y value as Plane above!)</div>
</li>
<li><div> Set the water&#039;s material to the processor&#039;s output material</div>
</li>
<li><div> Attach the <code>water</code> Geometry to the <code>rootNode</code>. (Not to the mainScene!)</div>
</li>
</ol>
</li>
</ol>
</div>
<h2><a>Sample Code</a></h2>
<div>
<p>
The sample code can be found in <code>jme3/src/jme3test/water/TestSimpleWater.java</code> and <code>jme3/src/jme3test/water/TestSceneWater.java</code>.
</p>
<p>
Here is the most important part of the code:
</p>
<pre>// we create a water processor
SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor&#40;assetManager&#41;; SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor&#40;assetManager&#41;;
waterProcessor.setReflectionScene&#40;mainScene&#41;; waterProcessor.setReflectionScene&#40;mainScene&#41;;
&nbsp; &nbsp;
@ -161,49 +98,9 @@ water.setLocalRotation&#40;new Quaternion&#40;&#41;.fromAngleAxis&#40;-FastMath.
water.setLocalTranslation&#40;-200, -6, 250&#41;; water.setLocalTranslation&#40;-200, -6, 250&#41;;
water.setShadowMode&#40;ShadowMode.Receive&#41;; water.setShadowMode&#40;ShadowMode.Receive&#41;;
water.setMaterial&#40;waterProcessor.getMaterial&#40;&#41;&#41;; water.setMaterial&#40;waterProcessor.getMaterial&#40;&#41;&#41;;
rootNode.attachChild&#40;water&#41;;</pre> rootNode.attachChild&#40;water&#41;;</pre></div><h2><a
</div> name="settings">Settings</a></h2><div
class="level2"><p> You can lower the render size to gain higher performance:</p><pre>waterProcessor.setRenderSize&#40;128,128&#41;;</pre><p> The deeper the water, the more transparent. (?)</p><pre>waterProcessor.setWaterDepth&#40;40&#41;;</pre><p> A higher distortion scale makes bigger waves.</p><pre>waterProcessor.setDistortionScale&#40;0.05f&#41;;</pre><p> A lower wave speed makes calmer water.</p><pre>waterProcessor.setWaveSpeed&#40;0.05f&#41;;</pre><p> If your scene does not have a lightsource, you can set the light direction for the water:</p><pre>waterProcessor.setLightDirection&#40; new Vector3f&#40;0.55f, -0.82f, 0.15f&#41;&#41;;</pre><p> Instead of creating a quad and specifying a plane, you can get a default waterplane from the processor:</p><pre>Geometry waterPlane = waterProcessor.createWaterGeometry&#40;10, 10&#41;;
<h2><a>Settings</a></h2>
<div>
<p>
You can lower the render size to gain higher performance:
</p>
<pre>waterProcessor.setRenderSize&#40;128,128&#41;;</pre>
<p>
The deeper the water, the more transparent. (?)
</p>
<pre>waterProcessor.setWaterDepth&#40;40&#41;;</pre>
<p>
A higher distortion scale makes bigger waves.
</p>
<pre>waterProcessor.setDistortionScale&#40;0.05f&#41;;</pre>
<p>
A lower wave speed makes calmer water.
</p>
<pre>waterProcessor.setWaveSpeed&#40;0.05f&#41;;</pre>
<p>
If your scene does not have a lightsource, you can set the light direction for the water:
</p>
<pre>waterProcessor.setLightDirection&#40; new Vector3f&#40;0.55f, -0.82f, 0.15f&#41;&#41;;</pre>
<p>
Instead of creating a quad and specifying a plane, you can get a default waterplane from the processor:
</p>
<pre>Geometry waterPlane = waterProcessor.createWaterGeometry&#40;10, 10&#41;;
waterPlane.setLocalTranslation&#40;-5, 0, 5&#41;; waterPlane.setLocalTranslation&#40;-5, 0, 5&#41;;
waterPlane.setMaterial&#40;waterProcessor.getMaterial&#40;&#41;&#41;;</pre> waterPlane.setMaterial&#40;waterProcessor.getMaterial&#40;&#41;&#41;;</pre><p> You can offer a switch to set the water Material to a static texture – for users with slow PCs.</p></div>
<p>
You can offer a switch to set the water Material to a static texture – for users with slow PCs.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:water?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:water?do=export_xhtmlbody">view online version</a></em></p>

@ -1,27 +1,13 @@
<h1><a
<h1><a>JME 3 Tutorial (7) - Hello Animation</a></h1> name="jme_3_tutorial_7_-_hello_animation">JME 3 Tutorial (7) - Hello Animation</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a> This tutorial shows how to add an animation controller and channels, and how to respond to user input by triggering an animation in a loaded model. <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a>, href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-animation.png?id=jme3%3Abeginner%3Ahello_animation"><img
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-animation.png" class="mediacenter" alt="" /></a></p></div><h2><a
</p> name="sample_code">Sample Code</a></h2><div
class="level2"><pre>package jme3test.helloworld;
<p>
This tutorial shows how to add an animation controller and channels, and how to respond to user input by triggering an animation in a loaded model.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-animation.png">
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl; import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener; import com.jme3.animation.AnimEventListener;
@ -34,40 +20,32 @@ import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Node; import com.jme3.scene.Node;
&nbsp;
<span>/** Sample 7 - how to load an OgreXML model and play an animation, <span>/** Sample 7 - how to load an OgreXML model and play an animation,
* using channels, a controller, and an AnimEventListener. */</span> * using channels, a controller, and an AnimEventListener. */</span>
public class HelloAnimation extends SimpleApplication public class HelloAnimation extends SimpleApplication
implements AnimEventListener &#123; implements AnimEventListener &#123;
&nbsp;
private AnimChannel channel; private AnimChannel channel;
private AnimControl control; private AnimControl control;
Node player; Node player;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
HelloAnimation app = new HelloAnimation&#40;&#41;; HelloAnimation app = new HelloAnimation&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
viewPort.setBackgroundColor&#40;ColorRGBA.LightGray&#41;; viewPort.setBackgroundColor&#40;ColorRGBA.LightGray&#41;;
initKeys&#40;&#41;; initKeys&#40;&#41;;
&nbsp;
DirectionalLight dl = new DirectionalLight&#40;&#41;; DirectionalLight dl = new DirectionalLight&#40;&#41;;
dl.setDirection&#40;new Vector3f&#40;-0.1f, -1f, -1&#41;.normalizeLocal&#40;&#41;&#41;; dl.setDirection&#40;new Vector3f&#40;-0.1f, -1f, -1&#41;.normalizeLocal&#40;&#41;&#41;;
rootNode.addLight&#40;dl&#41;; rootNode.addLight&#40;dl&#41;;
&nbsp;
player = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;; player = &#40;Node&#41; assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;;
player.setLocalScale&#40;0.5f&#41;; player.setLocalScale&#40;0.5f&#41;;
rootNode.attachChild&#40;player&#41;; rootNode.attachChild&#40;player&#41;;
&nbsp;
control = player.getControl&#40;AnimControl.class&#41;; control = player.getControl&#40;AnimControl.class&#41;;
control.addListener&#40;this&#41;; control.addListener&#40;this&#41;;
channel = control.createChannel&#40;&#41;; channel = control.createChannel&#40;&#41;;
channel.setAnim&#40;&quot;stand&quot;&#41;; channel.setAnim&#40;&quot;stand&quot;&#41;;
&#125; &#125;
&nbsp;
public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123; public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123; if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123;
channel.setAnim&#40;&quot;stand&quot;, 0.50f&#41;; channel.setAnim&#40;&quot;stand&quot;, 0.50f&#41;;
@ -75,17 +53,14 @@ public class HelloAnimation extends SimpleApplication
channel.setSpeed&#40;1f&#41;; channel.setSpeed&#40;1f&#41;;
&#125; &#125;
&#125; &#125;
&nbsp;
public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123; public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
// unused // unused
&#125; &#125;
&nbsp;
/** Custom Keybinding: Map named actions to inputs. */ /** Custom Keybinding: Map named actions to inputs. */
private void initKeys&#40;&#41; &#123; private void initKeys&#40;&#41; &#123;
inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;; inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;;
&#125; &#125;
&nbsp;
private ActionListener&#40;&#41; &#123; private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
if &#40;name.equals&#40;&quot;Walk&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; if &#40;name.equals&#40;&quot;Walk&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
@ -96,126 +71,67 @@ public class HelloAnimation extends SimpleApplication
&#125; &#125;
&#125; &#125;
&#125;; &#125;;
&nbsp; &#125;</pre></div><h2><a
&#125;</pre> name="creating_and_loading_animated_models">Creating and Loading Animated Models</a></h2><div
</div> class="level2"><p> You create animated models with a tool such as Blender. Take some time and learn how to create your own models in these <a
href="http://www.blender.org/education-help/tutorials/animation/">Blender Animation Tutorials</a>. For now, download and use a free model, such as the one included here as an example (<a
<h2><a>Creating and Loading Animated Models</a></h2> href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test-data/Models/Oto/">Oto Golem</a>, <a
<div> href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test-data/Models/Ninja/">Ninja</a>). <br/> Loading an animated model is pretty straight-forward, just as you have learned in the previous chapters. Animated Ogre models come as a set of files: The model is in <code>Oto.mesh.xml</code>, and the animation details are in <code>Oto.skeleton.xml</code> (plus materials and textures). Check that all files of the model are indeed in the right <code>Model</code> subdirectory.</p><pre> /* Displaying the model requires a light source */
<p>
You create animated models with a tool such as Blender. Take some time and learn how to create your own models in these <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.blender.org/education-help/tutorials/animation/"><param name="text" value="<html><u>Blender Animation Tutorials</u></html>"><param name="textColor" value="blue"></object>. For now, download and use a free model, such as the one included here as an example (<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test-data/Models/Oto/"><param name="text" value="<html><u>Oto Golem</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test-data/Models/Ninja/"><param name="text" value="<html><u>Ninja</u></html>"><param name="textColor" value="blue"></object>).
</p>
<p>
<br/>
</p>
<p>
Loading an animated model is pretty straight-forward, just as you have learned in the previous chapters. Animated Ogre models come as a set of files: The model is in <code>Oto.mesh.xml</code>, and the animation details are in <code>Oto.skeleton.xml</code> (plus materials and textures). Check that all files of the model are indeed in the right <code>Model</code> subdirectory.
</p>
<pre> /* Displaying the model requires a light source */
DirectionalLight dl = new DirectionalLight&#40;&#41;; DirectionalLight dl = new DirectionalLight&#40;&#41;;
dl.setDirection&#40;new Vector3f&#40;-0.1f, -1f, -1&#41;.normalizeLocal&#40;&#41;&#41;; dl.setDirection&#40;new Vector3f&#40;-0.1f, -1f, -1&#41;.normalizeLocal&#40;&#41;&#41;;
rootNode.addLight&#40;dl&#41;; rootNode.addLight&#40;dl&#41;;
&nbsp;
/* load and attach the model as usual */ /* load and attach the model as usual */
player = assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;; player = assetManager.loadModel&#40;&quot;Models/Oto/Oto.mesh.xml&quot;&#41;;
player.setLocalScale&#40;0.5f&#41;; // resize player.setLocalScale&#40;0.5f&#41;; // resize
rootNode.attachChild&#40;player&#41;;</pre> rootNode.attachChild&#40;player&#41;;</pre><p> Don&#039;t forget to add a light source to make the material visible.</p></div><h2><a
<p> name="animation_controler_and_channel">Animation Controler and Channel</a></h2><div
Don&#039;t forget to add a light source to make the material visible. class="level2"><p> After you load the animated model, you register it to the Animation Controller.</p><ul><li
</p> class="level1"><div
class="li"> The controller object gives you access to the available animation sequences.</div></li><li
</div> class="level1"><div
class="li"> The controller can have several channels, each channel can run one animation sequence at a time.</div></li><li
<h2><a>Animation Controler and Channel</a></h2> class="level1"><div
<div> class="li"> To run several sequences, you create several channels, and set them each to their animation.</div></li></ul><pre> <span>/* Load the animation controls, listen to animation events,
<p>
After you load the animated model, you register it to the Animation Controller.
</p>
<ul>
<li><div> The controller object gives you access to the available animation sequences. </div>
</li>
<li><div> The controller can have several channels, each channel can run one animation sequence at a time. </div>
</li>
<li><div> To run several sequences, you create several channels, and set them each to their animation.</div>
</li>
</ul>
<pre> <span>/* Load the animation controls, listen to animation events,
* create an animation channel, and bring the model in its default position. */</span> * create an animation channel, and bring the model in its default position. */</span>
control = player.getControl&#40;AnimControl.class&#41;; control = player.getControl&#40;AnimControl.class&#41;;
control.addListener&#40;this&#41;; control.addListener&#40;this&#41;;
channel = control.createChannel&#40;&#41;; channel = control.createChannel&#40;&#41;;
channel.setAnim&#40;&quot;stand&quot;&#41;;</pre> channel.setAnim&#40;&quot;stand&quot;&#41;;</pre></div><h2><a
</div> name="responding_to_animation_events">Responding to Animation Events</a></h2><div
class="level2"><p> Add <code>implements AnimEventListener</code> to the class declaration. This interface gives you access to events that notify you when a sequence is done, or when you change from one sequence to another, so you can respond to it. In this example, you reset the character to a standing position after a <code>Walk</code> cycle is done.</p><pre> public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
<h2><a>Responding to Animation Events</a></h2>
<div>
<p>
Add <code>implements AnimEventListener</code> to the class declaration. This interface gives you access to events that notify you when a sequence is done, or when you change from one sequence to another, so you can respond to it. In this example, you reset the character to a standing position after a <code>Walk</code> cycle is done.
</p>
<pre> public void onAnimCycleDone&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123; if &#40;animName.equals&#40;&quot;Walk&quot;&#41;&#41; &#123;
channel.setAnim&#40;&quot;stand&quot;, 0.50f&#41;; channel.setAnim&#40;&quot;stand&quot;, 0.50f&#41;;
channel.setLoopMode&#40;LoopMode.DontLoop&#41;; channel.setLoopMode&#40;LoopMode.DontLoop&#41;;
channel.setSpeed&#40;1f&#41;; channel.setSpeed&#40;1f&#41;;
&#125; &#125;
&#125; &#125;
&nbsp;
public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123; public void onAnimChange&#40;AnimControl control, AnimChannel channel, String animName&#41; &#123;
// unused // unused
&#125;</pre> &#125;</pre></div><h2><a
</div> name="trigger_animations_after_user_input">Trigger Animations After User Input</a></h2><div
class="level2"><p> There are ambient animations like animals or trees that you may want to trigger in the main event loop. In other cases, animations are triggered by user interaction, such as key input. You want to play the Walk animation when the player presses a certain key (here the spacebar), at the same time as the avatar performs the walk action and changes its location.</p><ol><li
<h2><a>Trigger Animations After User Input</a></h2> class="level1"><div
<div> class="li"> Initialize a new input controller (in <code>simpleInitApp()</code>).</div><ul><li
class="level2"><div
<p> class="li"> Don&#039;t forget to call the <code>initKey()</code> convenience method from <code>simpleInitApp()</code>.</div></li></ul></li><li
class="level1"><div
There are ambient animations like animals or trees that you may want to trigger in the main event loop. In other cases, animations are triggered by user interaction, such as key input. You want to play the Walk animation when the player presses a certain key (here the spacebar), at the same time as the avatar performs the walk action and changes its location. class="li"> Add a key mapping with the name the action you want to trigger.</div><ul><li
class="level2"><div
</p> class="li"> Here for example, you map <code>Walk</code> to the Spacebar key.</div></li></ul></li><li
<ol> class="level1"><div
<li><div> Initialize a new input controller (in <code>simpleInitApp()</code>). </div> class="li"> Add an input listener for the <code>Walk</code> action.</div></li></ol><pre> private void initKeys&#40;&#41; &#123;
<ul>
<li><div> Don&#039;t forget to call the <code>initKey()</code> convenience method from <code>simpleInitApp()</code>.</div>
</li>
</ul>
</li>
<li><div> Add a key mapping with the name the action you want to trigger. </div>
<ul>
<li><div> Here for example, you map <code>Walk</code> to the Spacebar key.</div>
</li>
</ul>
</li>
<li><div> Add an input listener for the <code>Walk</code> action.</div>
</li>
</ol>
<pre> private void initKeys&#40;&#41; &#123;
inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;; inputManager.addMapping&#40;&quot;Walk&quot;, new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Walk&quot;&#41;;
&#125;</pre> &#125;</pre><p> To use the input controller, you need to implement the actionLister:
<p> Test for each action by name, and set the channel to the corresponding animation to run.</p><ul><li
To use the input controller, you need to implement the actionLister: class="level1"><div
Test for each action by name, and set the channel to the corresponding animation to run. class="li"> The second parameter of setAnim() is the blendTime (how long the animation should overlap the last one).</div></li><li
class="level1"><div
</p> class="li"> LoopMode can be Loop (repeat), Cycle (forward then backward), and DontLoop (only once).</div></li><li
<ul> class="level1"><div
<li><div> The second parameter of setAnim() is the blendTime (?). </div> class="li"> If needed, use channel.setSpeed() to set the speed of this animation.</div></li><li
</li> class="level1"><div
<li><div> LoopMode can be Loop (repeat), Cycle (?), and DontLoop (only once). </div> class="li"> Optionally, use channel.setTime() to Fast-forward or rewind to a certain moment in time of this animation.</div></li></ul><pre> private ActionListener&#40;&#41; &#123;
</li>
<li><div> If needed, use channel.setTime() to set the speed of this animation.</div>
</li>
</ul>
<pre> private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
if &#40;name.equals&#40;&quot;Walk&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; if &#40;name.equals&#40;&quot;Walk&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
if &#40;!channel.getAnimationName&#40;&#41;.equals&#40;&quot;Walk&quot;&#41;&#41;&#123; if &#40;!channel.getAnimationName&#40;&#41;.equals&#40;&quot;Walk&quot;&#41;&#41;&#123;
@ -224,103 +140,48 @@ Test for each action by name, and set the channel to the corresponding animation
&#125; &#125;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre></div><h2><a
</div> name="exercises">Exercises</a></h2><div
class="level2"></div><h4><a
<h2><a>Exercises</a></h2> name="two_animations">Two Animations</a></h4><div
<div> class="level4"><p> Make the a mouse click trigger another animation sequence!</p><ol><li
class="level1"><div
</div> class="li"> Create a second channel in the controller</div></li><li
class="level2"><div
<h4><a>Two Animations</a></h4> class="li"> Create a new key trigger mapping and action (see: <a
<div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a>)</div></li><li
class="level2"><div
<p> class="li"> Tip: Do you want to find out what animation sequences are available in the model? Use:<pre>for &#40;System.out.println&#40;anim&#41;; &#125;</pre></div></li></ol></div><h4><a
name="revealing_the_skeleton_1">Revealing the Skeleton (1)</a></h4><div
Make the a mouse click trigger another animation sequence! class="level4"><p> Open the <code>skeleton.xml</code> file in a text editor of your choice.
You don&#039;t have to be able to read or write these xml files (Blender does that for you) – but it is good to know what the xml files are there for and how skeletons work. &quot;There&#039;s no magic to it!&quot;</p><ul><li
</p> class="level1"><div
<ol> class="li"> Note how the bones are numbered and named. All names of animated models follow a naming scheme.</div></li><li
<li><div> Create a second channel in the controller</div> class="level1"><div
</li> class="li"> Note the bone hierarchy that specifies how the bones are connected.</div></li><li
<li><div> Create a new key trigger mapping and action (see: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a>)</div> class="level1"><div
</li> class="li"> Note the list of animations: Each animation has a name, and several tracks. Each track tells individual bones how and when to transform. These animation steps are called keyframes.</div></li></ul></div><h4><a
<li><div> Tip: Do you want to find out what animation sequences are available in the model? Use: <pre>for &#40;System.out.println&#40;anim&#41;; &#125;</pre></div> name="revealing_the_skeleton_2">Revealing the Skeleton (2)</a></h4><div
</li> class="level4"><p> Add the following code snippet to <code>simpleInitApp()</code> to make the bones (that you just read about) visible!</p><pre> SkeletonDebugger skeletonDebug = new SkeletonDebugger&#40;&quot;skeleton&quot;, control.getSkeleton&#40;&#41;&#41;;
</ol>
</div>
<h4><a>Revealing the Skeleton (1)</a></h4>
<div>
<p>
Open the <code>skeleton.xml</code> file in a text editor of your choice.
</p>
<p>
You don&#039;t have to be able to read or write these xml files (Blender does that for you) – but it is good to know what the xml files are there for and how skeletons work. “There&#039;s no magic to it!”
</p>
<ul>
<li><div> Note how the bones are numbered and named. All names of animated models follow a naming scheme.</div>
</li>
<li><div> Note the bone hierarchy that specifies how the bones are connected.</div>
</li>
<li><div> Note the list of animations: Each animation has a name, and several tracks. Each track tells individual bones how and when to transform. These animation steps are called keyframes. </div>
</li>
</ul>
</div>
<h4><a>Revealing the Skeleton (2)</a></h4>
<div>
<p>
Add the following code snippet to <code>simpleInitApp()</code> to make the bones (that you just read about) visible!
</p>
<pre> SkeletonDebugger skeletonDebug = new SkeletonDebugger&#40;&quot;skeleton&quot;, control.getSkeleton&#40;&#41;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Green&#41;; mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Green&#41;;
mat.getAdditionalRenderState&#40;&#41;.setDepthTest&#40;false&#41;; mat.getAdditionalRenderState&#40;&#41;.setDepthTest&#40;false&#41;;
skeletonDebug.setMaterial&#40;mat&#41;; skeletonDebug.setMaterial&#40;mat&#41;;
player.attachChild&#40;skeletonDebug&#41;;</pre> player.attachChild&#40;skeletonDebug&#41;;</pre><p> Can you identify individual bones in the skeleton?</p></div><h2><a
<p> name="conclusion">Conclusion</a></h2><div
Can you identify individual bones in the skeleton? class="level2"><p> Now you can load animated models, identify stored animations, and trigger by using onAnimCycleDone() and onAnimChange(). You also learned that you can play several animations simultaneously, by starting each in a channel of its own. This could be useful if you ever want to animate the lower and upper part of the characters body independently, for example the legs run, while the arms use a weapon.
</p> Now that your character can walk, wouldn&#039;t it be cool if it could also pick up things, or aim a weapon at things, or open doors? Time to learn more about the secrets of <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">picking</a>!</p><hr
</div> /><p> See also: <a
href="https://docs.google.com/leaf?id=0B9hhZie2D-fEYmRkMTYwN2YtMzQ0My00NTM4LThhOTYtZTk1MTRlYTNjYTc3&amp;hl=en">Creating Animated OgreXML Models in Blender</a></p><div
<h2><a>Conclusion</a></h2> class="tags"><span> <a
<div> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
<p> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
href="/wiki/doku.php/tag:animation?do=showtag&amp;tag=tag%3Aanimation">animation</a>, <a
Now you can load animated models, identify stored animations, and trigger by using onAnimCycleDone() and onAnimChange(). You also learned that you can play several animations simultaneously, by starting each in a channel of its own. This could be useful if you ever want to animate the lower and upper part of the characters body independently, for example the legs run, while the arms use a weapon. href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
</p> href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<p> href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>, <a
Now that your character can walk, wouldn&#039;t it be cool if it could also pick up things, or aim a weapon at things, or open doors? Time to learn more about the secrets of <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">picking</a>! href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a> </span></div></div>
</p>
<hr />
<p>
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://docs.google.com/leaf?id=0B9hhZie2D-fEYmRkMTYwN2YtMzQ0My00NTM4LThhOTYtZTk1MTRlYTNjYTc3&amp;hl=en"><param name="text" value="<html><u>Creating Animated OgreXML Models in Blender</u></html>"><param name="textColor" value="blue"></object>
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:animation?do=showtag&amp;tag=tag%3Aanimation">animation</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>,
<a href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_animation?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_animation?do=export_xhtmlbody">view online version</a></em></p>

@ -1,31 +1,14 @@
<h1><a
<h1><a>JME 3 Tutorial (3) - Hello Assets</a></h1> name="jme_3_tutorial_3_-_hello_assets">JME 3 Tutorial (3) - Hello Assets</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Update Loop</a></p><p> In this tutorial we will learn to load 3-D models and text into the scene graph, using the jME asset manager. You also learn how to arrive at the correct paths, and which file formats to use.</p><p> <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>, href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-assets-models.png?id=jme3%3Abeginner%3Ahello_asset"><img
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Update Loop</a> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-assets-models.png?w=320&amp;h=250" class="mediacenter" alt="" width="320" height="250" /></a></p><p><p><div
</p> class="notetip">To use the example assets in a new jMonkeyPlatform project, right-click your project, select &quot;Properties&quot;, go to &quot;Libraries&quot;, press &quot;Add Library&quot; and add the &quot;jme3-test-data&quot; library.</div></p></p></div><h2><a
name="code_sample">Code Sample</a></h2><div
<p> class="level2"><pre>package jme3test.helloworld;
In this tutorial we will learn to load 3-D models and text into the scene graph, using the jME asset manager. You also learn how to arrive at the correct paths, and which file formats to use.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-assets-models.png">
</p>
<p>
<p><div>To use the example assets in a new jMonkeyPlatform project, right-click your project, select “Properties”, go to “Libraries”, press “Add Library” and add the “jme3-test-data” library.
</div></p>
</p>
</div>
<h2><a>Code Sample</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText; import com.jme3.font.BitmapText;
@ -86,26 +69,9 @@ public class HelloAssets extends SimpleApplication &#123;
rootNode.addLight&#40;sun&#41;; rootNode.addLight&#40;sun&#41;;
&nbsp; &nbsp;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Build and run the code sample. You should see a green Ninja with a colorful teapot standing behind a wall. The text on the screen should say &quot;Hello World&quot;.</p></div><h2><a
<p> name="the_asset_manager">The Asset Manager</a></h2><div
Build and run the code sample. You should see a green Ninja with a colorful teapot standing behind a wall. The text on the screen should say “Hello World”. class="level2"><p> JME3 comes with a handy asset manager that helps you keep your assets structured. Project assets are media files such as models, materials, textures, scenes, shaders, sounds, and fonts. The asset manager maintains a root that contains the classpath, so it can load any file from the current classpath (the top level of your project directory).</p><p> Additionally, the assetManager can be configured to add any path to the assets root, so assets can be loaded from directories you specify. <strong>In a jMonkeyPlatform project, jME3 seaches for models in the <code>assets</code> directory of your project.</strong> This is our recommended directory structure for storing assets:</p><pre>assets/Interface/
</p>
</div>
<h2><a>The Asset Manager</a></h2>
<div>
<p>
JME3 comes with a handy asset manager that helps you keep your assets structured. Project assets are media files such as models, materials, textures, scenes, shaders, sounds, and fonts. The asset manager maintains a root that contains the classpath, so it can load any file from the current classpath (the top level of your project directory).
</p>
<p>
Additionally, the assetManager can be configured to add any path to the assets root, so assets can be loaded from directories you specify. <strong>In a jMonkeyPlatform project, jME3 seaches for models in the <code>assets</code> directory of your project.</strong> This is our recommended directory structure for storing assets:
</p>
<pre>
assets/Interface/
assets/MatDefs/ assets/MatDefs/
assets/Materials/ assets/Materials/
assets/Models/ assets/Models/
@ -115,23 +81,9 @@ assets/Sounds/
assets/Textures/ assets/Textures/
build.xml build.xml
src/... src/...
dist/... dist/...</pre><p> These are just the most common examples, you can name the directories inside the assets directory how you like.</p></div><h3><a
</pre> name="loading_textures">Loading Textures</a></h3><div
class="level3"><p> Place the textures in a subdirectory of <code>assets/Textures/</code>. Load the texture into the material before you set the Material. The following code sample is from the <code>simpleInitApp()</code> method:</p><pre> // Create a wall with a simple texture from test_data
<p>
These are just the most common examples, you can name the directories inside the assets directory how you like.
</p>
</div>
<h3><a>Loading Textures</a></h3>
<div>
<p>
Place the textures in a subdirectory of <code>assets/Textures/</code>. Load the texture into the material before you set the Material. The following code sample is from the <code>simpleInitApp()</code> method:
</p>
<pre> // Create a wall with a simple texture from test_data
Box&#40;Vector3f.ZERO, 2.5f,2.5f,1.0f&#41;; Box&#40;Vector3f.ZERO, 2.5f,2.5f,1.0f&#41;;
Spatial wall = new Geometry&#40;&quot;Box&quot;, box &#41;; Spatial wall = new Geometry&#40;&quot;Box&quot;, box &#41;;
Material mat_brick = new Material&#40; Material mat_brick = new Material&#40;
@ -140,39 +92,20 @@ Place the textures in a subdirectory of <code>assets/Textures/</code>. Load the
assetManager.loadTexture&#40;&quot;Textures/Terrain/BrickWall/BrickWall.jpg&quot;&#41;&#41;; assetManager.loadTexture&#40;&quot;Textures/Terrain/BrickWall/BrickWall.jpg&quot;&#41;&#41;;
wall.setMaterial&#40;mat_brick&#41;; wall.setMaterial&#40;mat_brick&#41;;
wall.setLocalTranslation&#40;2.0f,-2.5f,0.0f&#41;; wall.setLocalTranslation&#40;2.0f,-2.5f,0.0f&#41;;
rootNode.attachChild&#40;wall&#41;;</pre> rootNode.attachChild&#40;wall&#41;;</pre><p> In most cases, you use default material descriptions such as &quot;SimpleTextured.j3md&quot;, as we do in this example. Advanced users can create <a
<p> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">custom Materials</a>.</p></div><h3><a
In most cases, you use default material descriptions such as “SimpleTextured.j3md”, as we do in this example. Advanced users can create <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">custom Materials</a>. name="loading_text_and_fonts">Loading Text and Fonts</a></h3><div
</p> class="level3"><p> This example displays &quot;Hello Text&quot; in the default font at the bottom edge of the window. You attach text to the <code>guiNode</code>, a special node for flat (orthogonal) display elements. You can clear existing text in the guiNode by detaching all its children.
The following code sample goes into the <code>simpleInitApp()</code> method.</p><pre> // Display a line of text with a default font
</div>
<h3><a>Loading Text and Fonts</a></h3>
<div>
<p>
This example displays “Hello Text” in the default font at the bottom edge of the window. You attach text to the <code>guiNode</code>, a special node for flat (orthogonal) display elements. You can clear existing text in the guiNode by detaching all its children.
The following code sample goes into the <code>simpleInitApp()</code> method.
</p>
<pre> // Display a line of text with a default font
guiNode.detachAllChildren&#40;&#41;; guiNode.detachAllChildren&#40;&#41;;
guiFont = assetManager.loadFont&#40;&quot;Interface/Fonts/Default.fnt&quot;&#41;; guiFont = assetManager.loadFont&#40;&quot;Interface/Fonts/Default.fnt&quot;&#41;;
BitmapText helloText = new BitmapText&#40;guiFont, false&#41;; BitmapText helloText = new BitmapText&#40;guiFont, false&#41;;
helloText.setSize&#40;guiFont.getCharSet&#40;&#41;.getRenderedSize&#40;&#41;&#41;; helloText.setSize&#40;guiFont.getCharSet&#40;&#41;.getRenderedSize&#40;&#41;&#41;;
helloText.setText&#40;&quot;Hello World&quot;&#41;; helloText.setText&#40;&quot;Hello World&quot;&#41;;
helloText.setLocalTranslation&#40;300, helloText.getLineHeight&#40;&#41;, 0&#41;; helloText.setLocalTranslation&#40;300, helloText.getLineHeight&#40;&#41;, 0&#41;;
guiNode.attachChild&#40;helloText&#41;;</pre> guiNode.attachChild&#40;helloText&#41;;</pre></div><h3><a
</div> name="loading_an_ogre_xml_model">Loading an Ogre XML Model</a></h3><div
class="level3"><p> Export your model in OgreXML format (.mesh.xml, .scene, .material, .skeleton.xml) and place it in a subdirectory of <code>assets/Models/</code>. The following code sample goes into the <code>simpleInitApp()</code> method.</p><pre> // Load a model from test_data (OgreXML + material + texture)
<h3><a>Loading an Ogre XML Model</a></h3>
<div>
<p>
Export your model in OgreXML format (.mesh.xml, .scene, .material, .skeleton.xml) and place it in a subdirectory of <code>assets/Models/</code>. The following code sample goes into the <code>simpleInitApp()</code> method.
</p>
<pre> // Load a model from test_data (OgreXML + material + texture)
Spatial ninja = assetManager.loadModel&#40;&quot;Models/Ninja/Ninja.mesh.xml&quot;&#41;; Spatial ninja = assetManager.loadModel&#40;&quot;Models/Ninja/Ninja.mesh.xml&quot;&#41;;
ninja.scale&#40;0.05f, 0.05f, 0.05f&#41;; ninja.scale&#40;0.05f, 0.05f, 0.05f&#41;;
ninja.rotate&#40;0.0f, -3.0f, 0.0f&#41;; ninja.rotate&#40;0.0f, -3.0f, 0.0f&#41;;
@ -181,276 +114,166 @@ Export your model in OgreXML format (.mesh.xml, .scene, .material, .skeleton.xml
// You must add a light to make the model visible // You must add a light to make the model visible
DirectionalLight sun = new DirectionalLight&#40;&#41;; DirectionalLight sun = new DirectionalLight&#40;&#41;;
sun.setDirection&#40;new Vector3f&#40;-0.1f, -0.7f, -1.0f&#41;&#41;; sun.setDirection&#40;new Vector3f&#40;-0.1f, -0.7f, -1.0f&#41;&#41;;
rootNode.addLight&#40;sun&#41;;</pre> rootNode.addLight&#40;sun&#41;;</pre><p> If you use the build script created by the jMonkeyPlatform then, by default, <strong>the original OgreXML files will not be included in your distributed game.</strong> You will get an error message when trying to load them.</p><pre>com.jme3.asset.DesktopAssetManager loadAsset
<p>
If you use the build script created by the jMonkeyPlatform then, by default, <strong>the original OgreXML files will not be included in your distributed game.</strong> You will get an error message when trying to load them.
</p>
<pre>com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Scenes/town/main.scene WARNING: Cannot locate resource: Scenes/town/main.scene
com.jme3.app.Application handleError com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main] SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException java.lang.NullPointerException</pre><p> For the release build, you should work with .j3o files only. Use the jMonkeyPlatform&#039;s context menu action to <a
</pre> href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">convert OgreXML models to .j3o format</a>.</p></div><h3><a
name="loading_assets_from_custom_paths">Loading Assets From Custom Paths</a></h3><div
<p> class="level3"><p> What if your game relies on user supplied model files, that will not be included in your distribution? If a file is not located in the default location, you can register a custom Locator and load it from any path.</p><p> Here is a usage example of a ZipLocator that is registered to a file <code>town.zip</code> in the top level of your project directory:</p><pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
For the release build, you should work with .j3o files only. Use the jMonkeyPlatform&#039;s context menu action to <a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">convert OgreXML models to .j3o format</a>.
</p>
</div>
<h3><a>Loading Assets From Custom Paths</a></h3>
<div>
<p>
What if your game relies on user supplied model files, that will not be included in your distribution? If a file is not located in the default location, you can register a custom Locator and load it from any path.
</p>
<p>
Here is a usage example of a ZipLocator that is registered to a file <code>town.zip</code> in the top level of your project directory:
</p>
<pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre> rootNode.attachChild&#40;scene&#41;;</pre><p> Here is a HttpZipLocator that can download zipped models:</p><pre> assetManager.registerLocator&#40;&quot;http://jmonkeyengine.googlecode.com/files/wildhouse.zip&quot;,
<p>
Here is a HttpZipLocator that can download zipped models:
</p>
<pre> assetManager.registerLocator&#40;&quot;http://jmonkeyengine.googlecode.com/files/wildhouse.zip&quot;,
HttpZipLocator.class.getName&#40;&#41;&#41;; HttpZipLocator.class.getName&#40;&#41;&#41;;
Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; Spatial scene = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre> rootNode.attachChild&#40;scene&#41;;</pre><p> JME3 offers ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see <code>com.jme3.asset.plugins</code>).</p></div><h2><a
<p> name="creating_models_and_scenes">Creating Models and Scenes</a></h2><div
JME3 offers ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, and UrlLocator (see <code>com.jme3.asset.plugins</code>). class="level2"><p> To create 3D models and scenes, you need a 3D Mesh Editor such as Blender, with an OgreXML Exporter plugin. Create your models with <a
</p> href="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics">UV textures</a>.
You can use the <a
</div> href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to <a
href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">load models</a> and <a
<h2><a>Creating Models and Scenes</a></h2> href="/com/jme3/gde/core/docs/sdk/scene_composer.html">create scenes</a> from them.</p><p> Export your models as Ogre <acronym
<div> title="Extensible Markup Language">XML</acronym> meshes with materials.</p><ol><li
class="level1"><div
<p> class="li"> Open the menu File &gt; Export &gt; OgreXML Exporter to open the exporter dialog.</div></li><li
class="level1"><div
To create 3D models and scenes, you need a 3D Mesh Editor such as Blender, with an OgreXML Exporter plugin. Create your models with <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics"><param name="text" value="<html><u>UV textures</u></html>"><param name="textColor" value="blue"></object>. class="li"> In the Export Materials field: Give the material the same name as the model. For example, the model <code>something.mesh.xml</code> goes with <code>something.material</code>, plus (optionally) <code>something.skeleton.xml</code> and some <acronym
You can use the <a href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> to <a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">load models</a> and <a href="/com/jme3/gde/core/docs/sdk/scene_composer.html">create scenes</a> from them. title="Joint Photographics Experts Group">JPG</acronym> files.</div></li><li
</p> class="level1"><div
class="li"> In the Export Meshes field: Select a subdirectory of your <code>assets/Models/</code> directory. E.g. <code>assets/Models/something/</code>.</div></li><li
<p> class="level1"><div
Export your models as Ogre <acronym title="Extensible Markup Language">XML</acronym> meshes with materials. class="li"> Activate the following exporter settings:</div><ul><li
</p> class="level2"><div
<ol> class="li"> Copy Textures: YES</div></li><li
<li><div> Open the menu File &gt; Export &gt; OgreXML Exporter to open the exporter dialog.</div> class="level2"><div
</li> class="li"> Rendering Materials: YES</div></li><li
<li><div> In the Export Materials field: Give the material the same name as the model. For example, the model <code>something.mesh.xml</code> goes with <code>something.material</code>, plus (optionally) <code>something.skeleton.xml</code> and some <acronym title="Joint Photographics Experts Group">JPG</acronym> files.</div> class="level2"><div
</li> class="li"> Flip Axis: YES</div></li><li
<li><div> In the Export Meshes field: Select a subdirectory of your <code>assets/Models/</code> directory. E.g. <code>assets/Models/something/</code>.</div> class="level2"><div
</li> class="li"> Require Materials: YES</div></li><li
<li><div> Activate the following exporter settings: </div> class="level2"><div
<ul> class="li"> Skeleton name follows mesh: YES</div></li></ul></li><li
<li><div> Copy Textures: YES</div> class="level1"><div
</li> class="li"> Click export.</div></li></ol><p> <strong>File Format:</strong> JME 3 can load Ogre <acronym
<li><div> Rendering Materials: YES</div> title="Extensible Markup Language">XML</acronym> models, materials, and scenes, as well as Wavefront OBJ+MTL models. For the game release, you should optimize model loading by converting all models to JME3&#039;s .j3o format. We recommend creating your project in the <a
</li> href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a>, it contains an integrated .j3o converter.</p><ol><li
<li><div> Flip Axis: YES</div> class="level1"><div
</li> class="li"> Open your JME3 Project in the jMonkeyplatform.</div></li><li
<li><div> Require Materials: YES</div> class="level1"><div
</li> class="li"> Right-click a .mesh.xml file in the Projects (or Favorites) window, and choose &quot;convert to JME3 binary&quot;.</div></li><li
<li><div> Skeleton name follows mesh: YES</div> class="level1"><div
</li> class="li"> The .j3o file appears next to the .mesh.xml file with the same name.</div></li><li
</ul> class="level1"><div
</li> class="li"> If you use the build script generated by the jMonkeyPlatform, mesh.xml files and obj files will be excluded from the executable JAR. If you get a runtime exception, make sure you have converted all models to .j3o.</div></li></ol></div><h3><a
<li><div> Click export.</div> name="loading_models_and_scenes">Loading Models and Scenes</a></h3><div
</li> class="level3"><div
</ol> class="table sectionedit1"><table
class="inline"><tr
<p> class="row0"><th
class="col0"> Task?</th><th
<strong>File Format:</strong> JME 3 can load Ogre <acronym title="Extensible Markup Language">XML</acronym> models, materials, and scenes, as well as Wavefront OBJ+MTL models. For the game release, you should optimize model loading by converting all models to JME3&#039;s .j3o format. We recommend creating your project in the <a href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a>, it contains an integrated .j3o converter. class="col1"> Solution!</th></tr><tr
class="row1"><td
</p> class="col0"> Load a model with materials</td><td
<ol> class="col1"> Use the asset managers <code>loadModel()</code> method and attach the Spatial to the rootNode.<pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.mesh.xml&quot;&#41;;
<li><div> Open your JME3 Project in the jMonkeyplatform.</div>
</li>
<li><div> Right-click a .mesh.xml file in the Projects (or Favorites) window, and choose “convert to JME3 binary”. </div>
</li>
<li><div> The .j3o file appears next to the .mesh.xml file with the same name. </div>
</li>
<li><div> If you use the build script generated by the jMonkeyPlatform, mesh.xml files and obj files will be excluded from the executable JAR. If you get a runtime exception, make sure you have converted all models to .j3o.</div>
</li>
</ol>
</div>
<h3><a>Loading Models and Scenes</a></h3>
<div>
<table>
<tr>
<th> Task? </th><th> Solution! </th>
</tr>
<tr>
<td> Load a model with materials </td><td> Use the asset managers <code>loadModel()</code> method and attach the Spatial to the rootNode. <pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.mesh.xml&quot;&#41;;
rootNode.attachChild&#40;elephant&#41;;</pre><pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.j3o&quot;&#41;; rootNode.attachChild&#40;elephant&#41;;</pre><pre>Spatial elephant = assetManager.loadModel&#40;&quot;Models/Elephant/Elephant.j3o&quot;&#41;;
rootNode.attachChild&#40;elephant&#41;;</pre></td> rootNode.attachChild&#40;elephant&#41;;</pre></td></tr><tr
</tr> class="row2"><td
<tr> class="col0"> Load a model without materials</td><td
<td> Load a model without materials </td><td> If you have a model without materials, you have to add a default material to make it visible. <pre>Spatial teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;; class="col1"> If you have a model without materials, you have to add a default material to make it visible.<pre>Spatial teapot = assetManager.loadModel&#40;&quot;Models/Teapot/Teapot.obj&quot;&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;;
teapot.setMaterial&#40;mat&#41;; teapot.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;teapot&#41;;</pre></td> rootNode.attachChild&#40;teapot&#41;;</pre></td></tr><tr
</tr> class="row3"><td
<tr> class="col0"> Load a scene</td><td
<td> Load a scene </td><td> You load scenes just like you load models: <pre>Spatial scene = assetManager.loadModel&#40;&quot;Scenes/house/main.scene&quot;&#41;; class="col1"> You load scenes just like you load models:<pre>Spatial scene = assetManager.loadModel&#40;&quot;Scenes/house/main.scene&quot;&#41;;
rootNode.attachChild&#40;scene&#41;;</pre></td> rootNode.attachChild&#40;scene&#41;;</pre></td></tr></table></div></div><h3><a
</tr> name="excercise_-_how_to_load_assets">Excercise - How to Load Assets</a></h3><div
</table> class="level3"><p> As an exercise, let&#039;s try different ways of loading a scene. You can load a scene directly, or from a zip file:</p><ol><li
class="level1"><div
</div> class="li"> <a
href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip">Download the town.zip</a> sample scene.</div></li><li
<h3><a>Excercise - How to Load Assets</a></h3> class="level1"><div
<div> class="li"> (Optional:) Unzip the town.zip to see the structure of the contained Ogre dotScene: You&#039;ll get a directory named <code>town</code>. It contains <acronym
title="Extensible Markup Language">XML</acronym> and texture files, and file called main.scene. (This is just for your information, you do not need to do anything with it.)</div></li><li
<p> class="level1"><div
class="li"> Place the town.zip file in the top level directory of your JME3 project, like so:<pre>jMonkeyProjects/MyGameProject/assets/
As an exercise, let&#039;s try different ways of loading a scene. You can load a scene directly, or from a zip file:
</p>
<ol>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip"><param name="text" value="<html><u>Download the town.zip</u></html>"><param name="textColor" value="blue"></object> sample scene. </div>
</li>
<li><div> (Optional:) Unzip the town.zip to see the structure of the contained Ogre dotScene: You&#039;ll get a directory named <code>town</code>. It contains <acronym title="Extensible Markup Language">XML</acronym> and texture files, and file called main.scene. (This is just for your information, you do not need to do anything with it.)</div>
</li>
<li><div> Place the town.zip file in the top level directory of your JME3 project, like so: <pre>jMonkeyProjects/MyGameProject/assets/
jMonkeyProjects/MyGameProject/build.xml jMonkeyProjects/MyGameProject/build.xml
jMonkeyProjects/MyGameProject/src/ jMonkeyProjects/MyGameProject/src/
jMonkeyProjects/MyGameProject/town.zip jMonkeyProjects/MyGameProject/town.zip
... ...</pre></div></li></ol><p> Use the following method to load models from a zip file:</p><ol><li
</pre> class="level1"><div
</div> class="li"> Make sure <code>town.zip</code> is in the project directory.</div></li><li
</li> class="level1"><div
</ol> class="li"> We register a zip file locator to the project directory. The loadModel() method now searches this zip directly for the files to load. <br/> (That is, <em>do not</em> write <code>town.zip/main.scene</code> or similar.)</div></li><li
class="level1"><div
<p> class="li"> Add the following code under <code>simpleInitApp() {</code><pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
Use the following method to load models from a zip file:
</p>
<ol>
<li><div> Make sure <code>town.zip</code> is in the project directory.</div>
</li>
<li><div> We register a zip file locator to the project directory. The loadModel() method now searches this zip directly for the files to load. <br/>
(That is, <em>do not</em> write <code>town.zip/main.scene</code> or similar.) </div>
</li>
<li><div> Add the following code under <code>simpleInitApp() {</code><pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
Spatial gameLevel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; Spatial gameLevel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;; gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;;
gameLevel.setLocalScale&#40;2&#41;; gameLevel.setLocalScale&#40;2&#41;;
rootNode.attachChild&#40;gameLevel&#41;;</pre></div> rootNode.attachChild&#40;gameLevel&#41;;</pre></div></li><li
</li> class="level1"><div
<li><div> Clean, build and run the project. You should see the Ninja+wall+teapot standing in a town. </div> class="li"> Clean, build and run the project. You should see the Ninja+wall+teapot standing in a town.</div></li></ol><p> If you register new locators, make sure you do not get any file name conflicts: Give each scene a unique name.</p><p> Earlier in this tutorial, you loaded scenes and models from the asset directory. This is the most common way you will be loading scenes and models. Here is the typical procedure:</p><ol><li
</li> class="level1"><div
</ol> class="li"> Remove the code from the previous exercise.</div></li><li
class="level1"><div
<p> class="li"> Move the unzipped <code>town/</code> directory into the <code>assets/Scenes/</code> directory of your project.</div></li><li
class="level1"><div
If you register new locators, make sure you do not get any file name conflicts: Give each scene a unique name. class="li"> Add the following code under <code>simpleInitApp() {</code><pre> Spatial gameLevel = assetManager.loadModel&#40;&quot;Scenes/town/main.scene&quot;&#41;;
</p>
<p>
Earlier in this tutorial, you loaded scenes and models from the asset directory. This is the most common way you will be loading scenes and models. Here is the typical procedure:
</p>
<ol>
<li><div> Remove the code from the previous exercise.</div>
</li>
<li><div> Move the unzipped <code>town/</code> directory into the <code>assets/Scenes/</code> directory of your project.</div>
</li>
<li><div> Add the following code under <code>simpleInitApp() {</code> <pre> Spatial gameLevel = assetManager.loadModel&#40;&quot;Scenes/town/main.scene&quot;&#41;;
gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;; gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;;
gameLevel.setLocalScale&#40;2&#41;; gameLevel.setLocalScale&#40;2&#41;;
rootNode.attachChild&#40;gameLevel&#41;;</pre></div> rootNode.attachChild&#40;gameLevel&#41;;</pre></div></li><li
</li> class="level1"><div
<li><div> Note that the path starts relative to the <code>assets/…</code> directory.</div> class="li"> Note that the path starts relative to the <code>assets/…</code> directory.</div></li><li
</li> class="level1"><div
<li><div> Clean, build and run the project. Again, you should see the Ninja+wall+teapot standing in a town. </div> class="li"> Clean, build and run the project. Again, you should see the Ninja+wall+teapot standing in a town.</div></li></ol><p> Here is a third method you must know. Loading a scene/model from a .j3o file:</p><ol><li
</li> class="level1"><div
</ol> class="li"> Remove the code from the previous exercise.</div></li><li
class="level1"><div
<p> class="li"> If you haven&#039;t already, open the <a
href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> and open the project that contains the Hello Asset class.</div></li><li
Here is a third method you must know. Loading a scene/model from a .j3o file: class="level1"><div
class="li"> In the projects window, browse to the <code>assets/Scenes/town</code> directory.</div></li><li
</p> class="level1"><div
<ol> class="li"> Right-click the <code>main.scene</code> and convert the scene to binary: The jMoneyPlatform generates a main.j3o file.</div></li><li
<li><div> Remove the code from the previous exercise.</div> class="level1"><div
</li> class="li"> Add the following code under <code>simpleInitApp() {</code><pre> Spatial gameLevel = assetManager.loadModel&#40;&quot;Scenes/town/main.j3o&quot;&#41;;
<li><div> If you haven&#039;t already, open the <a href="/com/jme3/gde/core/docs/sdk.html">jMonkeyPlatform</a> and open the project that contains the Hello Asset class.</div>
</li>
<li><div> In the projects window, browse to the <code>assets/Scenes/town</code> directory. </div>
</li>
<li><div> Right-click the <code>main.scene</code> and convert the scene to binary: The jMoneyPlatform generates a main.j3o file.</div>
</li>
<li><div> Add the following code under <code>simpleInitApp() {</code><pre> Spatial gameLevel = assetManager.loadModel&#40;&quot;Scenes/town/main.j3o&quot;&#41;;
gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;; gameLevel.setLocalTranslation&#40;0, -5.2f, 0&#41;;
gameLevel.setLocalScale&#40;2&#41;; gameLevel.setLocalScale&#40;2&#41;;
rootNode.attachChild&#40;gameLevel&#41;;</pre></div> rootNode.attachChild&#40;gameLevel&#41;;</pre></div></li><li
</li> class="level1"><div
<li><div> Again, note that the path starts relative to the <code>assets/…</code> directory.</div> class="li"> Again, note that the path starts relative to the <code>assets/…</code> directory.</div></li><li
</li> class="level1"><div
<li><div> Clean, Build and run the project. Again, you should see the Ninja+wall+teapot standing in a town. </div> class="li"> Clean, Build and run the project. Again, you should see the Ninja+wall+teapot standing in a town.</div></li></ol><p> What is the difference between loading <code>Scenes/town/main.j3o</code> and <code>Scenes/town/main.scene</code>?</p><ul><li
</li> class="level1"><div
</ol> class="li"> <strong>You can work with *.scene and .xml files during the development phase:</strong> When your designer pushes updated files to the asset directory, you can quickly review the latest version in your development environment.</div></li><li
class="level1"><div
<p> class="li"> <strong>Create and load *.j3o files for QA and release builds:</strong> .j3o is a binary format for jME3 applications, and .j3o files will be automatically included in the distributable JAR file. When you do QA test builds or are ready to release, use the jMonkeyPlatform to convert all .scene and .xml files to .j3o files, and load these.</div></li></ul></div><h2><a
name="conclusion">Conclusion</a></h2><div
What is the difference between loading <code>Scenes/town/main.j3o</code> and <code>Scenes/town/main.scene</code>? class="level2"><p> Now you know how to populate the scenegraph with static shapes and models, and how to build scenes. You have learned how to load assets using the <code>assetManager</code> and you have seen that the paths start relative to your project directory. Another important thing you have learned is to convert models to .j3o format for the JAR builds.</p><p> Let&#039;s add some action to the scene and continue with the <a
</p> href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Update Loop</a>.</p><hr
<ul> /><p> <strong>See also:</strong></p><ul><li
<li><div> <strong>You can work with *.scene and .xml files during the development phase:</strong> When your designer pushes updated files to the asset directory, you can quickly review the latest version in your development environment. </div> class="level1"><div
</li> class="li"> <a
<li><div> <strong>Create and load *.j3o files for QA and release builds:</strong> .j3o is a binary format for jME3 applications, and .j3o files will be automatically included in the distributable JAR file. When you do QA test builds or are ready to release, use the jMonkeyPlatform to convert all .scene and .xml files to .j3o files, and load these.</div> href="https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&amp;hl=en">Exporting OgreXML scenes from Blender to jME</a></div></li><li
</li> class="level1"><div
</ul> class="li"> <a
href="http://www.jmonkeyengine.com/forum/index.php?topic=14418.0">Screenshots of a great loaded model</a></div></li><li
</div> class="level1"><div
class="li"> If you want to learn how to load sounds, see <a
<h2><a>Conclusion</a></h2> href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a></div></li><li
<div> class="level1"><div
class="li"> If you want to learn more about loading textures and materials, see <a
<p> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></div></li></ul><div
class="tags"><span> <a
Now you know how to populate the scenegraph with static shapes and models, and how to build scenes. You have learned how to load assets using the <code>assetManager</code> and you have seen that the paths start relative to your project directory. Another important thing you have learned is to convert models to .j3o format for the JAR builds. href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</p> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
Let&#039;s add some action to the scene and continue with the <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Update Loop</a>. href="/wiki/doku.php/tag:lightnode?do=showtag&amp;tag=tag%3Alightnode">lightnode</a>, <a
href="/wiki/doku.php/tag:material?do=showtag&amp;tag=tag%3Amaterial">material</a>, <a
</p> href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>, <a
<hr /> href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>, <a
href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>, <a
<p> href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a> </span></div></div>
<strong>See also:</strong>
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&amp;hl=en"><param name="text" value="<html><u>Exporting OgreXML scenes from Blender to jME</u></html>"><param name="textColor" value="blue"></object> </div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/forum/index.php?topic=14418.0"><param name="text" value="<html><u>Screenshots of a great loaded model</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> If you want to learn how to load sounds, see <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a></div>
</li>
<li><div> If you want to learn more about loading textures and materials, see <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></div>
</li>
</ul>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:lightnode?do=showtag&amp;tag=tag%3Alightnode">lightnode</a>,
<a href="/wiki/doku.php/tag:material?do=showtag&amp;tag=tag%3Amaterial">material</a>,
<a href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>,
<a href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>,
<a href="/wiki/doku.php/tag:gui?do=showtag&amp;tag=tag%3Agui">gui</a>,
<a href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_asset?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_asset?do=export_xhtmlbody">view online version</a></em></p>

@ -1,23 +1,12 @@
<h1><a
<h1><a>JME 3 Tutorial (11) - Hello Audio</a></h1> name="jme_3_tutorial_11_-_hello_audio">JME 3 Tutorial (11) - Hello Audio</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a> <br/> This tutorial explains how to add 3D sound to a game, and how make sounds play together with other game events. We learn how to use the Audio Renderer, an Audio Listener, and Audio Nodes. We also make use of an Action Listener and a MouseButtonTrigger from the previous <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a>, href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> tutorial to make a mouse click trigger a gun shot sound.</p></div><h2><a
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a> name="sample_code">Sample Code</a></h2><div
</p> class="level2"><pre>package jme3test.helloworld;
<p>
This tutorial explains how to add 3D sound to a game, and how to trigger when sounds are to be played. We will use an Audio Listener, an Audio Renderer, two Audio Nodes, and an Action Listener.
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioNode; import com.jme3.audio.AudioNode;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.ActionListener;
@ -27,23 +16,18 @@ import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
&nbsp;
/** Sample 11 - playing 3D audio. */ /** Sample 11 - playing 3D audio. */
public class HelloAudio extends SimpleApplication &#123; public class HelloAudio extends SimpleApplication &#123;
&nbsp;
private AudioNode audio_gun; private AudioNode audio_gun;
private AudioNode audio_nature; private AudioNode audio_nature;
private Geometry player; private Geometry player;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
HelloAudio app = new HelloAudio&#40;&#41;; HelloAudio app = new HelloAudio&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
flyCam.setMoveSpeed&#40;40&#41;; flyCam.setMoveSpeed&#40;40&#41;;
&nbsp;
/** just a blue box floating in space */ /** just a blue box floating in space */
Box&#40;Vector3f.ZERO, 1, 1, 1&#41;; Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
player = new Geometry&#40;&quot;Player&quot;, box1&#41;; player = new Geometry&#40;&quot;Player&quot;, box1&#41;;
@ -51,37 +35,30 @@ public class HelloAudio extends SimpleApplication &#123;
mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;
player.setMaterial&#40;mat1&#41;; player.setMaterial&#40;mat1&#41;;
rootNode.attachChild&#40;player&#41;; rootNode.attachChild&#40;player&#41;;
&nbsp;
/** custom init methods, see below */ /** custom init methods, see below */
initKeys&#40;&#41;; initKeys&#40;&#41;;
initAudio&#40;&#41;; initAudio&#40;&#41;;
&#125; &#125;
&nbsp;
/** We create two audio nodes. */ /** We create two audio nodes. */
private void initAudio&#40;&#41; &#123; private void initAudio&#40;&#41; &#123;
/* gun shot sound is to be triggered by a mouse click. */ /* gun shot sound is to be triggered by a mouse click. */
audio_gun = new AudioNode&#40;assetManager, &quot;Sound/Effects/Gun.wav&quot;, false&#41;; audio_gun = new AudioNode&#40;audioRenderer, assetManager, &quot;Sound/Effects/Gun.wav&quot;&#41;;
audio_gun.setLooping&#40;false&#41;; audio_gun.setLooping&#40;false&#41;;
// Volume goes from 0.1f to 1.0f. At 0 it's muted. audio_gun.setVolume&#40;2&#41;;
audio_gun.setVolume&#40;0.2f&#41;;
&nbsp;
/* nature sound - keeps playing in a loop. */ /* nature sound - keeps playing in a loop. */
audio_nature = new AudioNode&#40;assetManager, &quot;Sound/Environment/Nature.ogg&quot;, false&#41;; audio_nature = new AudioNode&#40;audioRenderer, assetManager, &quot;Sound/Environment/Nature.ogg&quot;&#41;;
audio_nature.setLooping&#40;true&#41;; audio_nature.setLooping&#40;true&#41;;
audio_nature.setPositional&#40;true&#41;; audio_nature.setPositional&#40;true&#41;;
audio_nature.setLocalTranslation&#40;Vector3f.ZERO.clone&#40;&#41;&#41;; audio_nature.setLocalTranslation&#40;Vector3f.ZERO.clone&#40;&#41;&#41;;
// Volume goes from 0.1f to 1.0f. At 0 it's muted. audio_nature.setVolume&#40;3&#41;;
audio_nature.setVolume&#40;0.3f&#41;;
audioRenderer.playSource&#40;audio_nature&#41;; // play continuously! audioRenderer.playSource&#40;audio_nature&#41;; // play continuously!
&#125; &#125;
&nbsp;
<span>/** Declaring the &quot;Shoot&quot; action, and <span>/** Declaring the &quot;Shoot&quot; action, and
* mapping it to a trigger (mouse click). */</span> * mapping it to a trigger (mouse click). */</span>
private void initKeys&#40;&#41; &#123; private void initKeys&#40;&#41; &#123;
inputManager.addMapping&#40;&quot;Shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;; inputManager.addMapping&#40;&quot;Shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;;
&#125; &#125;
&nbsp;
/** Defining the &quot;Shoot&quot; action: Play a gun sound. */ /** Defining the &quot;Shoot&quot; action: Play a gun sound. */
private ActionListener&#40;&#41; &#123; private ActionListener&#40;&#41; &#123;
@Override @Override
@ -91,46 +68,22 @@ public class HelloAudio extends SimpleApplication &#123;
&#125; &#125;
&#125; &#125;
&#125;; &#125;;
&nbsp;
/** Move the listener with the a camera - for 3D audio. */ /** Move the listener with the a camera - for 3D audio. */
@Override @Override
public void simpleUpdate&#40;float tpf&#41; &#123; public void simpleUpdate&#40;float tpf&#41; &#123;
listener.setLocation&#40;cam.getLocation&#40;&#41;&#41;; listener.setLocation&#40;cam.getLocation&#40;&#41;&#41;;
listener.setRotation&#40;cam.getRotation&#40;&#41;&#41;; listener.setRotation&#40;cam.getRotation&#40;&#41;&#41;;
&#125; &#125;
&nbsp; &#125;</pre><p> When you run the sample, you should see a blue cube, and hear nature ambient sounds. When you click you hear a loud shot.</p></div><h2><a
&#125;</pre> name="understanding_the_code_sample">Understanding the Code Sample</a></h2><div
<p> class="level2"><p> In the game&#039;s <code>initSampleApp()</code> method, we create a simple blue cube geometry called <code>player</code> and attach it to the scene – it&#039;s just sample content so you see something when running the audio sample.
When you run the sample, you should see a blue cube, and hear nature ambient sounds. When you click you hear a loud shot.
</p>
</div>
<h2><a>Understanding the Code Sample</a></h2>
<div>
<p>
In the game&#039;s <code>initSampleApp()</code> method, we create a simple blue cube geometry called <code>player</code> and attach it to the scene – it&#039;s just sample content so you see something when running the audio sample.
</p>
<p>
From <code>initSampleApp()</code>, we initialize the game by calling the two custom methods <code>initKeys()</code> and <code>initAudio()</code>. You could call the lines of code in these two methods directly from <code>initSampleApp()</code>; we simply moved them into extra methods to keep the code more readable. From <code>initSampleApp()</code>, we initialize the game by calling the two custom methods <code>initKeys()</code> and <code>initAudio()</code>. You could call the lines of code in these two methods directly from <code>initSampleApp()</code>; we simply moved them into extra methods to keep the code more readable.
</p> Let&#039;s look at <code>initKeys()</code>: As we learned in previous tutorials, we use jme&#039;s <code>inputManager</code> to respond to user input. We add a mapping for a left mouse button click, and we name this new action <code>Shoot</code>.</p><pre>/** Declaring the &quot;Shoot&quot; action and mapping to a trigger. */
<p>
Let&#039;s look at <code>initKeys()</code>: As we learned in previous tutorials, we use jme&#039;s <code>inputManager</code> to respond to user input. We add a mapping for a left mouse button click, and we name this new action <code>Shoot</code>.
</p>
<pre>/** Declaring the &quot;Shoot&quot; action and mapping to a trigger. */
private void initKeys&#40;&#41; &#123; private void initKeys&#40;&#41; &#123;
// click to shoot // click to shoot
inputManager.addMapping&#40;&quot;Shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;; inputManager.addMapping&#40;&quot;Shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;;
&#125;</pre> &#125;</pre><p> Setting up the ActionListener should also be familiar from previous tutorials. We declare that, when the trigger (the mouse button) is pressed and released, we want to play a gun sound.</p><pre> /** Defining the &quot;Shoot&quot; action: play a sound. */
<p>
Setting up the ActionListener should also be familiar from previous tutorials. We declare that, when the trigger (the mouse button) is pressed and released, we want to play a gun sound.
</p>
<pre> /** Defining the &quot;Shoot&quot; action: play a sound. */
private ActionListener&#40;&#41; &#123; private ActionListener&#40;&#41; &#123;
@Override @Override
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
@ -138,154 +91,69 @@ Setting up the ActionListener should also be familiar from previous tutorials. W
audioRenderer.playSource&#40;audio_gun&#41;; audioRenderer.playSource&#40;audio_gun&#41;;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre><p> Next we have a closer look at <code>initAudio()</code> to learn how to use the <code>AudioRenderer</code> and <code>AudioNode</code>s.</p></div><h2><a
<p> name="audionodes">AudioNodes</a></h2><div
Next we have a closer look at <code>initAudio()</code> to learn how to use the <code>AudioRenderer</code> and <code>AudioNode</code>s. class="level2"><p> Using audio is quite simple. Save your audio files into your <code>assets/Sound</code> directory. jME3 supports both Ogg Vorbis (.ogg) and Wave (.wav) files.
</p> For each sound you create an audio node. A sound node can be used like any node in the jME scene graph. We create one node for a gunshot sound, and one for a nature sound.</p><pre> private AudioNode audio_gun;
private AudioNode audio_nature;</pre><p> Look at our custom <code>initAudio()</code> method: Here we initialize the sound objects and set their parameters.</p><pre> audio_gun = new AudioNode&#40; audioRenderer, assetManager, &quot;Sound/Effects/Gun.wav&quot;&#41;;
</div> ...
audio_nature = new AudioNode&#40; audioRenderer, assetManager, &quot;Sound/Environment/Nature.ogg&quot;&#41;;</pre><p> These two lines create new sound nodes from the given audio files in the assetManager.
<h2><a>AudioNodes</a></h2> In the next lines we specify that we want the gunshot sound to play only <em>once</em> – we don&#039;t want it to loop. We specify its volume as gain factor (at 0, sound is muted, at 2, it is twice as loud, etc.).</p><pre> audio_gun.setLooping&#40;false&#41;;
<div> audio_gun.setVolume&#40;2&#41;;</pre><p> The nature sound is different: We want it to loop <em>continuously</em> as background sound. This is why we set looping to true, and we already call the play() method on the node. We also choose to set its volume to 3.</p><pre> audio_nature.setLooping&#40;true&#41;;
audio_nature.setVolume&#40;3&#41;;
<p> ...
audioRenderer.playSource&#40;audio_nature&#41;; // play continuously!
Using audio is quite simple. Save your audio files into your <code>assets/Sound</code> directory. jME3 supports both Ogg Vorbis (.ogg) and Wave (.wav) files. &#125;</pre><p> We can choose to make the audio_nature a positional sound that comes from a certain place. We have to give the node an explicit translation, in this example we choose Vector3f.ZERO (which stands for the coordinates <code>0.0f,0.0f,0.0f</code>, the center of the scene.) Since jME supports 3D audio, you will be able to hear this sound coming from this particular location. Making the sound positional is optional.</p><pre> audio_nature.setPositional&#40;true&#41;;
</p> audio_nature.setLocalTranslation&#40;Vector3f.ZERO.clone&#40;&#41;&#41;;</pre></div><h2><a
name="triggering_audio">Triggering Audio</a></h2><div
<p> class="level2"><p> The two sounds are used differently:</p><ul><li
For each sound you create an audio node. A sound node can be used like any node in the jME scene graph. We create one node for a gunshot sound, and one for a nature sound. class="level1"><div
</p> class="li"> The gunshot is situational. We want to play it only once, right when it is triggered.</div><ul><li
<pre> private AudioNode audio_gun; class="level2"><div
private AudioNode audio_nature;</pre> class="li"> This is why we made it <code>setLooping(false)</code></div></li></ul></li><li
<p> class="level1"><div
Look at <code>initAudio()</code>: Here we initialize the sound objects and set some parameters. class="li"> The nature sound is a background noise. We want it to start playing and loop on as long as the game runs.</div><ul><li
</p> class="level2"><div
<pre> audio_gun = new AudioNode(assetManager, &quot;Sound/Effects/Gun.wav&quot;, false); class="li"> This is why we made it <code>setLooping(true)</code></div></li></ul></li></ul><p> Now every sound knows whether it loops or not. The actual <code>play</code> command is the same for both files:</p><pre> audioRenderer.playSource&#40;audio_nature&#41;;
audio_nature = new AudioNode(assetManager, &quot;Sound/Environment/Nature.ogg&quot;, true);</pre>
<p>
These two lines create new sound nodes from the given audio files in the assetManager. The Boolean parameter specifies whether you want to stream the sound or not. The nature sound is quite long, so we set this to true because we want to stream it.
</p>
<p>
In the next lines we specify that we want the gunshot sound to play only <em>once</em> (do not loop) and we specify its volume on a scale of 0.1 to 1.0. At 0, it is muted.
</p>
<pre> audio_gun.setLooping&#40;false&#41;;
audio_gun.setVolume&#40;0.4f&#41;;</pre>
<p>
The nature sound is different: We want it to loop <em>continuously</em> as background sound. We also make it a positional sound and give the node an explicit translation (Vector3f.ZERO stands for <code>0.0f,0.0f,0.0f</code>). Since jME supports 3D audio, you will be able to hear this sound coming from a particular direction.
</p>
<pre> audio_nature.setLooping&#40;true&#41;;
audio_nature.setPositional&#40;true&#41;;
audio_nature.setLocalTranslation&#40;new Vector3f.ZERO.clone&#40;&#41;&#41;;
audio_nature.setVolume&#40;0.3f&#41;;
&#125;</pre>
</div>
<h2><a>Triggering Audio</a></h2>
<div>
<p>
The two sounds are used differently:
</p>
<ul>
<li><div> The gunshot is situational. We want to play it only once, right when it is triggered.</div>
<ul>
<li><div> This is why we made it <code>setLooping(false)</code></div>
</li>
</ul>
</li>
<li><div> The nature sound is a background noise. We want it to start playing and loop on as long as the game runs.</div>
<ul>
<li><div> This is why we made it <code>setLooping(true)</code></div>
</li>
</ul>
</li>
</ul>
<p>
So every sound knows whether it loops or not. The actual <code>play</code> command is the same for both files:
</p>
<pre> audioRenderer.playSource&#40;audio_nature&#41;;
... ...
audioRenderer.playSource&#40;audio_gun&#41;;</pre> audioRenderer.playSource&#40;audio_gun&#41;;</pre><p> Appart from the looping Boolean, the only difference is <em>where</em> play() is called:</p><ul><li
<p> class="level1"><div
The only difference is where they are called: class="li"> We start playing the background nature sound right after we have created it, in the initAudio() method.</div></li><li
</p> class="level1"><div
<ul> class="li"> The gunshot sound, however, is triggered situationally, only as part of the <code>Shoot</code> input action that we defined in the ActionListener.</div></li></ul><pre> /** Defining the &quot;Shoot&quot; action: Play a gun sound. */
<li><div> We start playing the background nature sound right after we have created it, in the initAudio() method. </div> private ActionListener&#40;&#41; &#123;
</li> @Override
<li><div> The gunshot sound, however, is triggered situationally, as part of the <code>Shoot</code> input action that we defined.</div> public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
</li> if &#40;name.equals&#40;&quot;Shoot&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
</ul> audioRenderer.playSource&#40;audio_gun&#41;; // play once!
&#125;
</div> &#125;
&#125;;</pre></div><h2><a
<h2><a>3D Audio Listener</a></h2> name="your_ear_in_the_scene_-_3d_audio_listener">Your Ear in the Scene - 3D Audio Listener</a></h2><div
<div> class="level2"><p> To keep up the 3D audio effect, jME needs to know the position of the sound source, and the position of the ears of the player. The ear is represented by an 3D Audio Listener object. The <code>listener</code> is a built-in object in a SimpleApplication (it is not related to any other Java Listeners, such as the input manager&#039;s ActionListener).
In order to make the most of the 3D audio effect, we use the <code>simpleUpdate()</code> method to move and rotate the listener (the player&#039;s ears) together with the camera (the player&#039;s eyes).</p><pre>public void simpleUpdate&#40;float tpf&#41; &#123;
<p>
To keep up the 3D audio effect, jME needs to know the position of the sound source, and the position of the audio listener. The <code>listener</code> is a built-in object in a SimpleApplication and it is not related to an ActonListener.
</p>
<p>
I order to make the most of 3D audio, we use the <code>simpleUpdate()</code> method to move the listener with the camera.
</p>
<pre> public void simpleUpdate&#40;float tpf&#41; &#123;
listener.setLocation&#40;cam.getLocation&#40;&#41;&#41;; listener.setLocation&#40;cam.getLocation&#40;&#41;&#41;;
listener.setRotation&#40;cam.getRotation&#40;&#41;&#41;; listener.setRotation&#40;cam.getRotation&#40;&#41;&#41;;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="global_directional_positional">Global, Directional, Positional?</a></h2><div
class="level2"><p> In this example, we defined the nature sound as coming from a certain position, but not the gunshot sound. This means our gunshot is global and can be heard everywhere with the same volume. JME3 also supports directional sounds, that can only be heard from a certain direction (More about <a
<h2><a>Global or Positional?</a></h2> href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">Audio</a> here). How do you make this decision?</p><ul><li
<div> class="level1"><div
class="li"> In a game with moving enemies you may want to make the gun shot or footsteps positional sounds. In these cases you must move the audio nodes to the location of the enemy before playing it. This way a player with stereo speakers could hear from which direction the steps or gun shots are coming.</div></li><li
<p> class="level1"><div
class="li"> Similarly, you may have game levels where you want one background sound to play globally. In this case, you would make the audio_nature neither positional nor directional (set both to false).</div></li><li
In this example, we defined the nature sound as coming from a certain position, but not the gunshot sound. This means the gunshot can be heard everywhere with the same volume. class="level1"><div
class="li"> If you want sound to be &quot;absorbed by the walls&quot; and only broadcast in one direction, you would make it directional. (More about <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">Audio</a> here.)</div></li></ul><p> In short, you must choose in every situation whether you want a sound to be global, directional, or positional.</p></div><h2><a
<ul> name="conclusion">Conclusion</a></h2><div
<li><div> In a game with moving enemies you maight want to make the audio_gun node positional, and move it to the location of the shooting enemy before playing it – this way a player with stereo speakers could hear from which direction the gunshot is coming. </div> class="level2"><p> You now know how to add the two most common types of sound to your game: Global sounds and positional sounds. You can play sounds in two ways: Either continuously in a loop, or situationally just once. You also learned to use sound files that are in either .ogg or .wav format. <strong>Tip:</strong> jME&#039;s Audio implementation also supports more advanced effects such as reverberation and the Doppler effect. You can also create directional sounds, and stream long sound files instead of buffering first. Find out more about these features from the sample code included in the jme3test directory and from the advanced <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">Audio</a> docs.
<li><div> Similarly, you may have game levels where you want one background sound to play globally, in this case, you would not make the audio_nature a positional sound.</div> Want some fire and explosions to go with your sounds? Read on to learn more about <a
</li> href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">effects</a>.</p><div
</ul> class="tags"><span> <a
href="/wiki/doku.php/tag:sound?do=showtag&amp;tag=tag%3Asound">sound</a>, <a
<p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
In short, you must choose in every situation whether you want a sound to be global or positional. href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</p> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a> </span></div></div>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You now know how to add two types of sound to your game: global sounds and positional sounds. You can play sounds in two ways: Either as loop or just once. You also learned to use sound files that are in either .ogg or .wav format.
</p>
<p>
Tip: jME&#039;s Audio implementation also supports more advanced effects such as reverberation and the Doppler effect. Find out more about these from the sample code included in the jme3test directory.
</p>
<p>
Want some fire and explosions to go with your sounds? Read on to learn more about <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">effects</a>.
</p>
<div><span>
<a href="/wiki/doku.php/tag:sound?do=showtag&amp;tag=tag%3Asound">sound</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_audio?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_audio?do=export_xhtmlbody">view online version</a></em></p>

@ -1,49 +1,20 @@
<h1><a
<h1><a>JME 3 Tutorial (9) - Hello Collision</a></h1> name="jme_3_tutorial_9_-_hello_collision">JME 3 Tutorial (9) - Hello Collision</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a> <br/> This tutorial demonstrates how you load a scene model and give it solid walls and floors for a character to walk around.
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a>,
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a>
</p>
<p>
This tutorial demonstrates how you load a scene model and give it solid walls and floors for a character to walk around.
</p>
<p>
We will use a <code>PhysicsNode</code> for the static collidable scene, and a <code>PhysicsCharacterNode</code> for the mobile first-person character. We will also adapt the default first-person camera to work with physics-controlled navigation. We will use a <code>PhysicsNode</code> for the static collidable scene, and a <code>PhysicsCharacterNode</code> for the mobile first-person character. We will also adapt the default first-person camera to work with physics-controlled navigation.
</p> The solution shown here can be used for first-person shooters, mazes, and similar games. <a
href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-scene.png?id=jme3%3Abeginner%3Ahello_collision"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-scene.png?w=360&amp;h=281" class="mediacenter" alt="" width="360" height="281" /></a></p></div><h2><a
The solution shown here can be used for first-person shooters, mazes, and similar games. name="sample_code">Sample Code</a></h2><div
</p> class="level2"><p> If you don&#039;t have it yet, <a
href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip">download the town.zip</a> sample scene.</p><pre>jMonkeyProjects$ ls -1 BasicGame
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-scene.png">
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<p>
If you don&#039;t have it yet, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip"><param name="text" value="<html><u>download the town.zip</u></html>"><param name="textColor" value="blue"></object> sample scene.
</p>
<pre>jMonkeyProjects$ ls -1 BasicGame
assets/ assets/
build.xml build.xml
town.zip town.zip
src/</pre> src/</pre><p> Place town.zip in the root directory of your JME3 project.</p><pre>package jme3test.helloworld;
<p>
Place town.zip in the root directory of your JME3 project.
</p>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ZipLocator; import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState; import com.jme3.bullet.BulletAppState;
@ -61,7 +32,6 @@ import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
&nbsp;
<span>/** <span>/**
* Example 9 - How to make walls and floors solid. * Example 9 - How to make walls and floors solid.
* This version uses Physics and a custom Action Listener. * This version uses Physics and a custom Action Listener.
@ -69,42 +39,35 @@ import com.jme3.scene.Spatial;
*/</span> */</span>
public class HelloCollision extends SimpleApplication public class HelloCollision extends SimpleApplication
implements ActionListener &#123; implements ActionListener &#123;
&nbsp;
private Spatial sceneModel; private Spatial sceneModel;
private BulletAppState bulletAppState; private BulletAppState bulletAppState;
private RigidBodyControl landscape; private RigidBodyControl landscape;
private CharacterControl player; private CharacterControl player;
private Vector3f walkDirection = new Vector3f&#40;&#41;; private Vector3f walkDirection = new Vector3f&#40;&#41;;
private boolean left = false, right = false, up = false, down = false; private boolean left = false, right = false, up = false, down = false;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
HelloCollision app = new HelloCollision&#40;&#41;; HelloCollision app = new HelloCollision&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
/** Set up Physics */ /** Set up Physics */
bulletAppState = new BulletAppState&#40;&#41;; bulletAppState = new BulletAppState&#40;&#41;;
stateManager.attach&#40;bulletAppState&#41;; stateManager.attach&#40;bulletAppState&#41;;
&nbsp; // We re-use the flyby camera control for rotation, while positioning is handled by physics
// We re-use the flyby camera for rotation, while positioning is handled by physics
viewPort.setBackgroundColor&#40;new ColorRGBA&#40;0.7f,0.8f,1f,1f&#41;&#41;; viewPort.setBackgroundColor&#40;new ColorRGBA&#40;0.7f,0.8f,1f,1f&#41;&#41;;
flyCam.setMoveSpeed&#40;100&#41;; flyCam.setMoveSpeed&#40;100&#41;;
setUpKeys&#40;&#41;; setUpKeys&#40;&#41;;
setUpLight&#40;&#41;; setUpLight&#40;&#41;;
&nbsp;
// We load the scene from the zip file and adjust its size. // We load the scene from the zip file and adjust its size.
assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;; assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
sceneModel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; sceneModel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
sceneModel.setLocalScale&#40;2f&#41;; sceneModel.setLocalScale&#40;2f&#41;;
&nbsp;
// We set up collision detection for the scene by creating a // We set up collision detection for the scene by creating a
// compound collision shape and a static physics node with mass zero. // compound collision shape and a static physics node with mass zero.
CollisionShape sceneShape = CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; sceneModel&#41;; CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; sceneModel&#41;;
landscape = new RigidBodyControl&#40;sceneShape, 0&#41;; landscape = new RigidBodyControl&#40;sceneShape, 0&#41;;
sceneModel.addControl&#40;landscape&#41;; sceneModel.addControl&#40;landscape&#41;;
&nbsp;
// We set up collision detection for the player by creating // We set up collision detection for the player by creating
// a capsule collision shape and a physics character node. // a capsule collision shape and a physics character node.
// The physics character node offers extra settings for // The physics character node offers extra settings for
@ -116,26 +79,22 @@ public class HelloCollision extends SimpleApplication
player.setFallSpeed&#40;30&#41;; player.setFallSpeed&#40;30&#41;;
player.setGravity&#40;30&#41;; player.setGravity&#40;30&#41;;
player.setPhysicsLocation&#40;new Vector3f&#40;0, 10, 0&#41;&#41;; player.setPhysicsLocation&#40;new Vector3f&#40;0, 10, 0&#41;&#41;;
&nbsp;
// We attach the scene and the player to the rootnode and the physics space, // We attach the scene and the player to the rootnode and the physics space,
// to make them appear in the game world. // to make them appear in the game world.
rootNode.attachChild&#40;sceneModel&#41;; rootNode.attachChild&#40;sceneModel&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;landscape&#41;; bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;landscape&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;player&#41;; bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;player&#41;;
&#125; &#125;
&nbsp;
private void setUpLight&#40;&#41; &#123; private void setUpLight&#40;&#41; &#123;
// We add light so we see the scene // We add light so we see the scene
AmbientLight al = new AmbientLight&#40;&#41;; AmbientLight al = new AmbientLight&#40;&#41;;
al.setColor&#40;ColorRGBA.White.mult&#40;1.3f&#41;&#41;; al.setColor&#40;ColorRGBA.White.mult&#40;1.3f&#41;&#41;;
rootNode.addLight&#40;al&#41;; rootNode.addLight&#40;al&#41;;
&nbsp;
DirectionalLight dl = new DirectionalLight&#40;&#41;; DirectionalLight dl = new DirectionalLight&#40;&#41;;
dl.setColor&#40;ColorRGBA.White&#41;; dl.setColor&#40;ColorRGBA.White&#41;;
dl.setDirection&#40;new Vector3f&#40;2.8f, -2.8f, -2.8f&#41;.normalizeLocal&#40;&#41;&#41;; dl.setDirection&#40;new Vector3f&#40;2.8f, -2.8f, -2.8f&#41;.normalizeLocal&#40;&#41;&#41;;
rootNode.addLight&#40;dl&#41;; rootNode.addLight&#40;dl&#41;;
&#125; &#125;
&nbsp;
<span>/** We over-write some navigational key mappings here, so we can <span>/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */</span> * add physics-controlled walking and jumping: */</span>
private void setUpKeys&#40;&#41; &#123; private void setUpKeys&#40;&#41; &#123;
@ -150,7 +109,6 @@ public class HelloCollision extends SimpleApplication
inputManager.addListener&#40;this, &quot;Downs&quot;&#41;; inputManager.addListener&#40;this, &quot;Downs&quot;&#41;;
inputManager.addListener&#40;this, &quot;Jumps&quot;&#41;; inputManager.addListener&#40;this, &quot;Jumps&quot;&#41;;
&#125; &#125;
&nbsp;
<span>/** These are our custom actions triggered by key presses. <span>/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */</span> * We do not walk yet, we just keep track of the direction the user pressed. */</span>
public void onAction&#40;String binding, boolean value, float tpf&#41; &#123; public void onAction&#40;String binding, boolean value, float tpf&#41; &#123;
@ -166,7 +124,6 @@ public class HelloCollision extends SimpleApplication
player.jump&#40;&#41;; player.jump&#40;&#41;;
&#125; &#125;
&#125; &#125;
&nbsp;
<span>/** <span>/**
* This is the main event loop--walking happens here. * This is the main event loop--walking happens here.
* We check in which direction the player is walking by interpreting * We check in which direction the player is walking by interpreting
@ -186,193 +143,64 @@ public class HelloCollision extends SimpleApplication
player.setWalkDirection&#40;walkDirection&#41;; player.setWalkDirection&#40;walkDirection&#41;;
cam.setLocation&#40;player.getPhysicsLocation&#40;&#41;&#41;; cam.setLocation&#40;player.getPhysicsLocation&#40;&#41;&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Run the sample. You should see a town square with houses and a monument. Use the WASD keys and the mouse to navigate around in first person view. Run forward and jump by pressing W and Space. Note how you step over the sidewalk, and up the steps to the monument. You can walk in the alleys between the houses, but the walls are solid. Don&#039;t walk over the edge of the world! <img
<p> src="/wiki/lib/images/smileys/icon_smile.gif" class="middle" alt=":-)" /></p></div><h2><a
Run the sample. You should see a town square with houses and a monument. Use the WASD keys and the mouse to navigate around in first person view. Run forward and jump by pressing W and Space. Note how you step over the sidewalk, and up the steps to the monument. You can walk in the alleys between the houses, but the walls are solid. Don&#039;t walk over the edge of the world! <img src="/wiki/lib/images/smileys/icon_smile.gif" class="middle" alt=":-)" /> name="understanding_the_code">Understanding the Code</a></h2><div
</p> class="level2"><p> Let&#039;s start with the class declaration:</p><pre>extends SimpleApplication implements ActionListener</pre><p> SimpleApplication is the base class for all jME3 games. We also have this class implement the <code>ActionListener</code> interface because we want to customize the navigational inputs later.</p><pre> private Spatial sceneModel;
</div>
<h2><a>Understanding the Code</a></h2>
<div>
<p>
Let&#039;s start with the class declaration:
</p>
<pre>extends SimpleApplication implements ActionListener</pre>
<p>
SimpleApplication is the base class for all jME3 games. We also have this class implement the <code>ActionListener</code> interface because we want to customize the navigational inputs later.
</p>
<pre> private Spatial sceneModel;
private BulletAppState bulletAppState; private BulletAppState bulletAppState;
private RigidBodyControl landscape; private RigidBodyControl landscape;
private CharacterControl player; private CharacterControl player;
private Vector3f walkDirection = new Vector3f&#40;&#41;; private Vector3f walkDirection = new Vector3f&#40;&#41;;
private boolean left = false, right = false, up = false, down = false;</pre> private boolean left = false, right = false, up = false, down = false;</pre><p> We initialize a few private fields:</p><ul><li
<p> class="level1"><div
We initialize a few private fields: class="li"> The BulletAppState gives this SimpleApplication access to physics features (such as collision detection) supplied by jME3&#039;s jBullet integration</div></li><li
</p> class="level1"><div
<ul> class="li"> The Spatial sceneModel is a normal OgreXML model loaded as a Spatial.</div></li><li
<li><div> The BulletAppState gives this SimpleApplication access to physics features (such as collision detection) supplied by jME3&#039;s jBullet integration</div> class="level1"><div
</li> class="li"> You use the model as the game&#039;s landscape by adding a RigidBodyControl to it.</div></li><li
<li><div> The Spatial sceneModel is a normal OgreXML model loaded as a Spatial. </div> class="level1"><div
</li> class="li"> The (invisible) first-person player is represented by a CharacterControl object.</div></li><li
<li><div> You use the model as the game&#039;s landscape by adding a RigidBodyControl to it. </div> class="level1"><div
</li> class="li"> The fields <code>walkDirection</code> and the four Booleans are used for physics-controlled navigation.</div></li></ul><p> Let&#039;s have a look at all the details:</p></div><h2><a
<li><div> The (invisible) first-person player is represented by a CharacterControl object.</div> name="initializing_the_game">Initializing the Game</a></h2><div
</li> class="level2"><p> As usual, you initialize the game in the <code>simpleInitApp()</code> method.</p><pre> viewPort.setBackgroundColor&#40;new ColorRGBA&#40;0.7f,0.8f,1f,1f&#41;&#41;;
<li><div> The fields <code>walkDirection</code> and the four Booleans are used for physics-controlled navigation. </div>
</li>
</ul>
<p>
Let&#039;s have a look at all the details:
</p>
</div>
<h2><a>Initializing the Game</a></h2>
<div>
<p>
As usual, you initialize the game in the <code>simpleInitApp()</code> method.
</p>
<pre> viewPort.setBackgroundColor&#40;new ColorRGBA&#40;0.7f,0.8f,1f,1f&#41;&#41;;
flyCam.setMoveSpeed&#40;100&#41;; flyCam.setMoveSpeed&#40;100&#41;;
setUpKeys&#40;&#41;; setUpKeys&#40;&#41;;
setUpLight&#40;&#41;;</pre> setUpLight&#40;&#41;;</pre><p> We switch the background color from balck to light blue, since this is a scene with a sky.
<p> You repurpose the default camera control &quot;flyCam&quot; as first-person camera and set its speed.
We switch the background color from balck to light blue, since this is a scene with a sky.
You repurpose the default flyCam camera as first-person camera and set its speed.
The auxiliary method <code>setUpLights()</code> adds light sources. The auxiliary method <code>setUpLights()</code> adds light sources.
The auxiliary method <code>setUpKeys()</code> configures input mappings–we will look at it later. The auxiliary method <code>setUpKeys()</code> configures input mappings–we will look at it later.</p></div><h3><a
</p> name="the_physics-controlled_scene">The Physics-Controlled Scene</a></h3><div
class="level3"><p> The first thing you do in every physics game is create a BulletAppState object. It gives you access to jME3&#039;s jBullet integration which handles physical forces and collisions.</p><pre> bulletAppState = new BulletAppState&#40;&#41;;
</div> stateManager.attach&#40;bulletAppState&#41;;</pre><p> For the scene, you load the <code>sceneModel</code> from a zip file, and adjust the size.</p><pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
<h3><a>The Physics-Controlled Scene</a></h3>
<div>
<p>
The first thing you do in every physics game is create a BulletAppState object. It gives you access to jME3&#039;s jBullet integration which handles physical forces and collisions.
</p>
<pre> bulletAppState = new BulletAppState&#40;&#41;;
stateManager.attach&#40;bulletAppState&#41;;</pre>
<p>
For the scene, you load the <code>sceneModel</code> from a zip file, and adjust the size.
</p>
<pre> assetManager.registerLocator&#40;&quot;town.zip&quot;, ZipLocator.class.getName&#40;&#41;&#41;;
sceneModel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;; sceneModel = assetManager.loadModel&#40;&quot;main.scene&quot;&#41;;
sceneModel.setLocalScale&#40;2f&#41;;</pre> sceneModel.setLocalScale&#40;2f&#41;;</pre><p> The file <code>town.zip</code> is included as a sample model in the JME3 sources – you can <a
<p> href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip">download it here</a>. (Optionally, use any OgreXML scene of your own.) For this sample, place the zip file in the application&#039;s top level directory (that is, next to src/, assets/, build.xml).</p><pre> CollisionShape sceneShape =
The file <code>town.zip</code> is included as a sample model in the JME3 sources – you can <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/town.zip"><param name="text" value="<html><u>download it here</u></html>"><param name="textColor" value="blue"></object>. (Optionally, use any OgreXML scene of your own.) For this sample, place the zip file in the application&#039;s top level directory (that is, next to src/, assets/, build.xml).
</p>
<pre> CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; sceneModel&#41;; CollisionShapeFactory.createMeshShape&#40;&#40;Node&#41; sceneModel&#41;;
landscape = new RigidBodyControl&#40;sceneShape, 0&#41;; landscape = new RigidBodyControl&#40;sceneShape, 0&#41;;
sceneModel.addControl&#40;landscape&#41;;</pre> sceneModel.addControl&#40;landscape&#41;;</pre><p> To use collision detection, you want to add a RigidBodyControl to the <code>sceneModel</code> Spatial. The RigidBodyControl for a complex model takes two arguments: A Collision Shape, and the object&#039;s mass.</p><ul><li
<p> class="level1"><div
To use collision detection, you want to add a RigidBodyControl to the <code>sceneModel</code> Spatial. The RigidBodyControl for a complex model takes two arguments: A Collision Shape, and the object&#039;s mass. class="li"> JME3 offers a <code>CollisionShapeFactory</code> that precalculates a mesh-accurate collision shape for a Spatial. We choose to generate a <code>CompoundCollisionShape</code>, which has MeshCollisionShapes as its children. <strong>Note:</strong> This type of collision shape is optimal for immobile objects, such as terrain, houses, and whole shooter levels.</div></li><li
class="level1"><div
</p> class="li"> You set the mass to zero since a scene is static and its mass irrevelant.</div></li></ul><p> Add the control to the Spatial to give it physical properties. Attach the sceneModel to the rootNode to make it visible.</p><pre> rootNode.attachChild&#40;sceneModel&#41;;</pre><p> <strong>Tip:</strong> Remember to always add a light source so you can see the scene.</p></div><h3><a
<ul> name="the_physics-controlled_player">The Physics-Controlled Player</a></h3><div
<li><div> JME3 offers a <code>CollisionShapeFactory</code> that precalculates a mesh-accurate collision shape for a Spatial. We choose to generate a <code>CompoundCollisionShape</code>, which has MeshCollisionShapes as its children. <strong>Note:</strong> This type of collision shape is optimal for immobile objects, such as terrain, houses, and whole shooter levels. </div> class="level3"><p> Next you set up collision detection for the first-person player.</p><pre> CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape&#40;1.5f, 6f, 1&#41;;</pre><p> Again, you create a CollisionShape: This time we choose a CapsuleCollisionShape, a cylinder with a rounded top and bottom. <strong>Note:</strong> This shape is optimal for a person: It&#039;s tall and the roundness helps to get stuck less often on obstacles.</p><ul><li
</li> class="level1"><div
<li><div> You set the mass to zero since a scene is static and its mass irrevelant. </div> class="li"> Supply the CapsuleCollisionShape constructor with the desired size of the bounding capsule to fit the shape of your character. In this example the character is 2*1.5f units wide, and 6f units tall.</div></li><li
</li> class="level1"><div
</ul> class="li"> The final integer argument specifies the orientation of the cylinder: 1 is the Y-axis, which fits an upright person. For many animals and vehicles you would use 0 or 2.</div></li></ul><pre> player = new CharacterControl&#40;capsuleShape, 0.05f&#41;;</pre><p> Now you use the CollisionShape to create a <code>CharacterControl</code> that represents the player. The last argument of the CharacterControl constructor (here <code>.05f</code>) is the size of a step that the character should be able to surmount.</p><pre> player.setJumpSpeed&#40;20&#41;;
<p>
Add the control to the Spatial to make give it physical properties. Attach the sceneModel to the rootNode to make it visible.
</p>
<pre> rootNode.attachChild&#40;sceneModel&#41;;</pre>
<p>
<strong>Tip:</strong> Remember to always add a light source so you can see the scene.
</p>
</div>
<h3><a>The Physics-Controlled Player</a></h3>
<div>
<p>
Next you set up collision detection for the first-person player.
</p>
<pre> CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape&#40;1.5f, 6f, 1&#41;;</pre>
<p>
Again, you create a CollisionShape: This time we choose a CapsuleCollisionShape, a cylinder with a rounded top and bottom. <strong>Note:</strong> This shape is optimal for a person: It&#039;s tall and the roundness helps to get stuck less often on obstacles.
</p>
<ul>
<li><div> Supply the CapsuleCollisionShape constructor with the desired size of the bounding capsule to fit the shape of your character. In this example the character is 2*1.5f units wide, and 6f units tall. </div>
</li>
<li><div> The final integer argument specifies the orientation of the cylinder: 1 is the Y-axis, which fits an upright person. For many animals and vehicles you would use 0 or 2.</div>
</li>
</ul>
<pre> player = new CharacterControl&#40;capsuleShape, 0.05f&#41;;</pre>
<p>
Now you use the CollisionShape to create a <code>CharacterControl</code> that represents the player. The last argument of the CharacterControl constructor (here <code>.05f</code>) is the size of a step that the character should be able to surmount.
</p>
<pre> player.setJumpSpeed&#40;20&#41;;
player.setFallSpeed&#40;30&#41;; player.setFallSpeed&#40;30&#41;;
player.setGravity&#40;30&#41;;</pre> player.setGravity&#40;30&#41;;</pre><p> Apart from step height and character size, the <code>CharacterControl</code> lets you configure jumping, falling, and gravity speeds. Adjust the values to fit your game situation.</p><pre> player.setPhysicsLocation&#40;new Vector3f&#40;0, 10, 0&#41;&#41;;</pre><p> Finally we put the player in its starting position and update its state – remember to use setPhysicsLocation() instead of setLocalTranslation(). since you are dealing with a physical object.</p></div><h3><a
<p> name="activating_the_physicsspace">Activating the PhysicsSpace</a></h3><div
Apart from step height and character size, the <code>CharacterControl</code> lets you configure jumping, falling, and gravity speeds. Adjust the values to fit your game situation. class="level3"><p> As in every JME3 application, you must attach the scene and the player to the <code>rootNode</code> to make them appear in the game world.</p><pre> rootNode.attachChild&#40;landscape&#41;;
</p> rootNode.attachChild&#40;player&#41;;</pre><p> Remember that for physical games, you must also add all solid objects (usually the characters and the scene) to the <code>PhysicsSpace</code>!</p><pre> bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;landscape&#41;;
<pre> player.setPhysicsLocation&#40;new Vector3f&#40;0, 10, 0&#41;&#41;;</pre> bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;player&#41;;</pre></div><h2><a
<p> name="navigation">Navigation</a></h2><div
Finally we put the player in its starting position and update its state – remember to use setPhysicsLocation() instead of setLocalTranslation(). since you are dealing with a physical object. class="level2"><p> The default camera controller <code>cam</code> is a third-person camera. JME3 also offers a first-person controller, <code>flyCam</code>, which we use here to handle camera rotation.
</p>
</div>
<h3><a>Activating the PhysicsSpace</a></h3>
<div>
<p>
As in every JME3 application, you must attach the scene and the player to the <code>rootNode</code> to make them appear in the game world.
</p>
<pre> rootNode.attachChild&#40;landscape&#41;;
rootNode.attachChild&#40;player&#41;;</pre>
<p>
Remember that for physical games, you must also add all solid objects (usually the characters and the scene) to the <code>PhysicsSpace</code>!
</p>
<pre> bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;landscape&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;player&#41;;</pre>
</div>
<h2><a>Navigation</a></h2>
<div>
<p>
The default camera controller <code>cam</code> is a third-person camera. JME3 also offers a first-person controller, <code>flyCam</code>, which we use here to handle camera rotation.
</p>
<p>
However we must redefine how walking is handled for physics-controlled objects: When you navigate a physical node, you do not specify a <em>target location</em>, but a <em>walk direction</em>. The physics space calculates how far the character can actually go in the desired direction – or whether it will be stoped by an obstacle. However we must redefine how walking is handled for physics-controlled objects: When you navigate a physical node, you do not specify a <em>target location</em>, but a <em>walk direction</em>. The physics space calculates how far the character can actually go in the desired direction – or whether it will be stoped by an obstacle.
</p> This is why we must re-define the flyCam&#039;s navigational key mappings to use <code>setWalkDirection()</code> instead of <code>setLocalTranslation()</code>. Here are the steps:</p></div><h3><a
name="inputmanager">1. inputManager</a></h3><div
<p> class="level3"><p> Configure the familiar WASD inputs for walking, and Space for jumping.</p><pre> inputManager.addMapping&#40;&quot;Lefts&quot;, new KeyTrigger&#40;KeyInput.KEY_A&#41;&#41;;
This is why we must re-define the flyCam&#039;s navigational key mappings to use <code>setWalkDirection()</code> instead of <code>setLocalTranslation()</code>. Here are the steps:
</p>
</div>
<h3><a>1. inputManager</a></h3>
<div>
<p>
Configure the familiar WASD inputs for walking, and Space for jumping.
</p>
<pre> inputManager.addMapping&#40;&quot;Lefts&quot;, new KeyTrigger&#40;KeyInput.KEY_A&#41;&#41;;
inputManager.addMapping&#40;&quot;Rights&quot;, new KeyTrigger&#40;KeyInput.KEY_D&#41;&#41;; inputManager.addMapping&#40;&quot;Rights&quot;, new KeyTrigger&#40;KeyInput.KEY_D&#41;&#41;;
inputManager.addMapping&#40;&quot;Ups&quot;, new KeyTrigger&#40;KeyInput.KEY_W&#41;&#41;; inputManager.addMapping&#40;&quot;Ups&quot;, new KeyTrigger&#40;KeyInput.KEY_W&#41;&#41;;
inputManager.addMapping&#40;&quot;Downs&quot;, new KeyTrigger&#40;KeyInput.KEY_S&#41;&#41;; inputManager.addMapping&#40;&quot;Downs&quot;, new KeyTrigger&#40;KeyInput.KEY_S&#41;&#41;;
@ -381,21 +209,9 @@ Configure the familiar WASD inputs for walking, and Space for jumping.
inputManager.addListener&#40;this, &quot;Rights&quot;&#41;; inputManager.addListener&#40;this, &quot;Rights&quot;&#41;;
inputManager.addListener&#40;this, &quot;Ups&quot;&#41;; inputManager.addListener&#40;this, &quot;Ups&quot;&#41;;
inputManager.addListener&#40;this, &quot;Downs&quot;&#41;; inputManager.addListener&#40;this, &quot;Downs&quot;&#41;;
inputManager.addListener&#40;this, &quot;Jumps&quot;&#41;;</pre> inputManager.addListener&#40;this, &quot;Jumps&quot;&#41;;</pre><p> In the code sample above, this block of code was moved into an auxiliary method <code>setupKeys()</code> that is called from <code>simpleInitApp()</code>–this is just to keep the code more readable.</p></div><h3><a
<p> name="onaction">2. onAction()</a></h3><div
In the code sample above, this block of code was moved into an auxiliary method <code>setupKeys()</code> that is called from <code>simpleInitApp()</code>–this is just to keep the code more readable. class="level3"><p> Remember that we declared this class an <code>ActionListener</code> so we could customize the flyCam. The <code>ActionListener</code> interface requires us to implement the <code>onAction()</code> method: You re-define the actions triggered by navigation key presses to work with physics.</p><pre> public void onAction&#40;String binding, boolean value, float tpf&#41; &#123;
</p>
</div>
<h3><a>2. onAction()</a></h3>
<div>
<p>
Remember that we declared this class an <code>ActionListener</code> so we could customize the flyCam. The <code>ActionListener</code> interface requires us to implement the <code>onAction()</code> method: You re-define the actions triggered by navigation key presses to work with physics.
</p>
<pre> public void onAction&#40;String binding, boolean value, float tpf&#41; &#123;
if &#40;binding.equals&#40;&quot;Lefts&quot;&#41;&#41; &#123; if &#40;binding.equals&#40;&quot;Lefts&quot;&#41;&#41; &#123;
left = value; left = value;
&#125; else if &#40;binding.equals&#40;&quot;Rights&quot;&#41;&#41; &#123; &#125; else if &#40;binding.equals&#40;&quot;Rights&quot;&#41;&#41; &#123;
@ -407,94 +223,42 @@ Remember that we declared this class an <code>ActionListener</code> so we could
&#125; else if &#40;binding.equals&#40;&quot;Jumps&quot;&#41;&#41; &#123; &#125; else if &#40;binding.equals&#40;&quot;Jumps&quot;&#41;&#41; &#123;
player.jump&#40;&#41;; player.jump&#40;&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Every time the user presses one of the WASD keys, you keep track of the direction the user wants to go – by storing this info in four directional Booleans. We will use them soon.
<p>
Every time the user presses one of the WASD keys, you keep track of the direction the user wants to go – by storing this info in four directional Booleans. We will use them soon.
</p>
<p>
Note that no actual walking happens here – not yet! Note that no actual walking happens here – not yet!
</p> The only movement that you do not have to implement yourself is the jumping action. The call <code>player.jump()</code> is a special method that handles a correct jumping motion for your <code>PhysicsCharacterNode</code>.</p></div><h3><a
name="setwalkdirection">3. setWalkDirection()</a></h3><div
<p> class="level3"><p> In <code>onAction()</code> you have determined in which direction the user wants to go in terms of &quot;forward&quot; or &quot;left&quot;.
The only movement that you do not have to implement yourself is the jumping action. The call <code>player.jump()</code> is a special method that handles a correct jumping motion for your <code>PhysicsCharacterNode</code>. Now you need poll the current rotation of the camera to find to which vectors &quot;forward&quot; and &quot;left&quot; correspond in the coordinate system.
</p> This last and most important code snippet goes into the main event loop, <code>simpleUpdate()</code>.</p><pre> Vector3f camDir = cam.getDirection&#40;&#41;.clone&#40;&#41;.multLocal&#40;0.6f&#41;;
</div>
<h3><a>3. setWalkDirection()</a></h3>
<div>
<p>
In <code>onAction()</code> you have determined in which direction the user wants to go in terms of “forward” or “left”.
Now you need poll the current rotation of the camera to find to which vectors “forward” and “left” correspond in the coordinate system.
This last and most important code snippet goes into the main event loop, <code>simpleUpdate()</code>.
</p>
<pre> Vector3f camDir = cam.getDirection&#40;&#41;.clone&#40;&#41;.multLocal&#40;0.6f&#41;;
Vector3f camLeft = cam.getLeft&#40;&#41;.clone&#40;&#41;.multLocal&#40;0.4f&#41;; Vector3f camLeft = cam.getLeft&#40;&#41;.clone&#40;&#41;.multLocal&#40;0.4f&#41;;
walkDirection.set&#40;0, 0, 0&#41;; walkDirection.set&#40;0, 0, 0&#41;;
if &#40;left&#41; &#123; walkDirection.addLocal&#40;camLeft&#41;; &#125; if &#40;left&#41; &#123; walkDirection.addLocal&#40;camLeft&#41;; &#125;
if &#40;right&#41; &#123; walkDirection.addLocal&#40;camLeft.negate&#40;&#41;&#41;; &#125; if &#40;right&#41; &#123; walkDirection.addLocal&#40;camLeft.negate&#40;&#41;&#41;; &#125;
if &#40;up&#41; &#123; walkDirection.addLocal&#40;camDir&#41;; &#125; if &#40;up&#41; &#123; walkDirection.addLocal&#40;camDir&#41;; &#125;
if &#40;down&#41; &#123; walkDirection.addLocal&#40;camDir.negate&#40;&#41;&#41;; &#125;</pre> if &#40;down&#41; &#123; walkDirection.addLocal&#40;camDir.negate&#40;&#41;&#41;; &#125;</pre><p> Reset the variable <code>walkDirection</code> to zero. Then add to it all latest motion vectors that you polled from the camera. It is posible for a character to move forward and to the left simultaneously.</p><pre>player.setWalkDirection&#40;walkDirection&#41;;</pre><p> This one line does the &quot;walking&quot; magic: Always use <code>setWalkDirection()</code> to make a physics-controlled object move continuously, and the physics engine automatically handles collision detection for you! <strong>Important:</strong> Do not use <code>setLocalTranslation()</code> to walk the player around. You may get it stuck by overlapping with another physical object. You can put the player in a start position with <code>setPhysicalLocation()</code> if you make sure to place it a bit above the floor and away from obstacles.
<p> Lastly, do not forget to make the first-person camera object move along with the physics-controlled player node:</p><pre> cam.setLocation&#40;player.getPhysicsLocation&#40;&#41;&#41;;</pre><p> That&#039;s it!</p></div><h2><a
Reset the variable <code>walkDirection</code> to zero. Then add to it all latest motion vectors that you polled from the camera. It is posible for a character to move forward and to the left simultaneously. name="conclusion">Conclusion</a></h2><div
</p> class="level2"><p> You have learned how to load a &quot;solid&quot; physical scene model and walk around in it with a first-person perspective.
<pre>player.setWalkDirection&#40;walkDirection&#41;;</pre>
<p>
This one line does the “walking” magic: Always use <code>setWalkDirection()</code> to make a physics-controlled object move continuously, and the physics engine automatically handles collision detection for you!
</p>
<p>
<strong>Important:</strong> Do not use <code>setLocalTranslation()</code> to walk the player around. You may get it stuck by overlapping with another physical object. You can put the player in a start position with <code>setPhysicalLocation()</code> if you make sure to place it a bit above the floor and away from obstacles.
</p>
<p>
Lastly, do not forget to make the first-person camera object move along with the physics-controlled player node:
</p>
<pre> cam.setLocation&#40;player.getPhysicsLocation&#40;&#41;&#41;;</pre>
<p>
That&#039;s it!
</p>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned how to load a “solid” physical scene model and walk around in it with a first-person perspective.
You had JME3 calculate the CollisionShapes, and you represented collidables as PhysicsNodes that you registered to the Physics Space. You had JME3 calculate the CollisionShapes, and you represented collidables as PhysicsNodes that you registered to the Physics Space.
You also made certain to use <code>player.setWalkDirection(walkDirection)</code> to move physical characters around. You also made certain to use <code>player.setWalkDirection(walkDirection)</code> to move physical characters around.
</p> To learn more about different ways of loading models and scene have a look at <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>,<a
<p> href="/com/jme3/gde/core/docs/sdk/scene_explorer.html">Scene Explorer</a> and <a
To learn more about different ways of loading models and scene have a look at <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>,<a href="/com/jme3/gde/core/docs/sdk/scene_explorer.html">Scene Explorer</a> and <a href="/com/jme3/gde/core/docs/sdk/scene_composer.html">Scene Composer</a> href="/com/jme3/gde/core/docs/sdk/scene_composer.html">Scene Composer</a> There are also other possible solutions for this task that do not require physics.
</p> Have a look at <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/collision/TestSimpleCollision.java?r=5192&amp;spec=svn5192">jme3test.collision.TestSimpleCollision.java</a> (and SphereMotionAllowedListener.java).
<p> To learn more about complex physics scenes where several mobile physical objects bump into each other, read <a
There are also other possible solutions for this task that do not require physics. href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a>.
Have a look at <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/collision/TestSimpleCollision.java?r=5192&amp;spec=svn5192"><param name="text" value="<html><u>jme3test.collision.TestSimpleCollision.java</u></html>"><param name="textColor" value="blue"></object> (and SphereMotionAllowedListener.java). Do you want to hear your player say &quot;ouch!&quot; when he bumps into a wall? Continue with learning <a
To learn more about complex physics scenes where several mobile physical objects bump into each other, read <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a>. href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">how to add sound</a> to your game.</p><div
</p> class="tags"><span> <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
<p> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
Do you want to hear your player say “ouch!” when he bumps into a wall? Continue with learning <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">how to add sound</a> to your game. href="/wiki/doku.php/tag:collision?do=showtag&amp;tag=tag%3Acollision">collision</a>, <a
href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>, <a
</p> href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a>, <a
<div><span> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>, <a
<a href="/wiki/doku.php/tag:collision?do=showtag&amp;tag=tag%3Acollision">collision</a>, href="/wiki/doku.php/tag:physics?do=showtag&amp;tag=tag%3Aphysics">physics</a> </span></div></div>
<a href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>,
<a href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>,
<a href="/wiki/doku.php/tag:physics?do=showtag&amp;tag=tag%3Aphysics">physics</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_collision?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_collision?do=export_xhtmlbody">view online version</a></em></p>

@ -1,57 +1,30 @@
<h1><a
<h1><a>JME 3 Tutorial (12) - Hello Effects</a></h1> name="jme_3_tutorial_12_-_hello_effects">JME 3 Tutorial (12) - Hello Effects</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a></p><p> <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a>, href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-effect-fire.png?id=jme3%3Abeginner%3Ahello_effects"><img
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-effect-fire.png?w=150&amp;h=165" class="mediaright" align="right" alt="" width="150" height="165" /></a></p><p> When you see one of the following in a game, then a particle system is likely behind it:</p><ul><li
</p> class="level1"><div
class="li"> Fire, flames, sparks;</div></li><li
<p> class="level1"><div
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-effect-fire.png"> class="li"> Rain, snow, waterfalls, leaves;</div></li><li
</p> class="level1"><div
class="li"> Explosions, debris, shockwaves;</div></li><li
<p> class="level1"><div
When you see one of the following in a game, then a particle system is likely behind it: class="li"> Dust, fog, clouds, smoke;</div></li><li
</p> class="level1"><div
<ul> class="li"> Insects swarms, meteor showers;</div></li><li
<li><div> Fire, flames, sparks;</div> class="level1"><div
</li> class="li"> Magic spells.</div></li></ul><p> These things typically cannot be modeled by meshes.
<li><div> Rain, snow, waterfalls, leaves;</div> In very simple terms:</p><ul><li
</li> class="level1"><div
<li><div> Explosions, debris, shockwaves;</div> class="li"> The difference between an explosion and a dust cloud is the speed of the effect.</div></li><li
</li> class="level1"><div
<li><div> Dust, fog, clouds, smoke;</div> class="li"> The difference between flames and a waterfall is the direction and the color of the effect.</div></li></ul><p> Particle effects can be animated (e.g. sparks, drops) and static (strands of grass, hair). Non-particle effects include bloom/glow, and motion blur/afterimage. In this tutorial we will look at animated particles (com.jme3.effect).</p></div><h2><a
</li> name="sample_code">Sample Code</a></h2><div
<li><div> Insects swarms, meteor showers;</div> class="level2"><pre>package jme3test.helloworld;
</li>
<li><div> Magic spells.</div>
</li>
</ul>
<p>
These things typically cannot be modeled by meshes.
In very simple terms:
</p>
<ul>
<li><div> The difference between an explosion and a dust cloud is the speed of the effect. </div>
</li>
<li><div> The difference between flames and a waterfall is the direction and the color of the effect. </div>
</li>
</ul>
<p>
Particle effects can be animated (e.g. sparks, drops) and static (strands of grass, hair). Non-particle effects include bloom/glow, and motion blur/afterimage. In this tutorial we will look at animated particles (com.jme3.effect).
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.effect.ParticleEmitter; import com.jme3.effect.ParticleEmitter;
@ -102,236 +75,147 @@ public class HelloEffects extends SimpleApplication &#123;
debris.emitAllParticles&#40;&#41;; debris.emitAllParticles&#40;&#41;;
&nbsp; &nbsp;
&#125; &#125;
&#125;</pre> &#125;</pre><p> You should see an explosion that sends debris flying, and a fire. <a
<p> href="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test/jme3test/effect/">More example code</a></p></div><h3><a
You should see an explosion that sends debris flying, and a fire. name="texture_animation_and_variation">Texture Animation and Variation</a></h3><div
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine/src/test/jme3test/effect/"><param name="text" value="<html><u>More example code</u></html>"><param name="textColor" value="blue"></object> class="level3"><p> <a
</p> href="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png"><img
src="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;w=96&amp;h=96&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png" class="mediaright" align="right" alt="" width="96" height="96" /></a></p><p> Start by choosing a material texture for your effect. If you provide the emitter with a set of textures (see image), it can use them either for variation (random order), or as animation steps (fixed order).</p><p> Setting emitter textures works just as you have already learned in previous chapters. This time we use the <code>Particle.j3md</code> default material. In the following example, we have a closer look at the Debris effect.</p><pre> ...
</div>
<h3><a>Texture Animation and Variation</a></h3>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
Start by choosing a material texture for your effect. If you provide the emitter with a set of textures (see image), it can use them either for variation (random order), or as animation steps (fixed order).
</p>
<p>
Setting emitter textures works just as you have already learned in previous chapters. This time we use the <code>Particle.j3md</code> default material. In the following example, we have a closer look at the Debris effect.
</p>
<pre> ...
Material debris_mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;; Material debris_mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;;
debris_mat.setTexture&#40;&quot;Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/Debris.png&quot;&#41;&#41;; debris_mat.setTexture&#40;&quot;Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/Debris.png&quot;&#41;&#41;;
debris.setMaterial&#40;debris_mat&#41;; debris.setMaterial&#40;debris_mat&#41;;
debris.setImagesX&#40;3&#41;; // columns debris.setImagesX&#40;3&#41;; // columns
debris.setImagesY&#40;3&#41;; // rows debris.setImagesY&#40;3&#41;; // rows
debris.setSelectRandomImage&#40;true&#41;; debris.setSelectRandomImage&#40;true&#41;;
...</pre><ol> ...</pre><ol><li
<li><div> Load the texture in the emitter&#039;s material.</div> class="level1"><div
</li> class="li"> Load the texture in the emitter&#039;s material.</div></li><li
<li><div> Tell the Emitter into how many animation steps (x*y) the texture is divided. 1&times;1 is default.</div> class="level1"><div
</li> class="li"> Tell the Emitter into how many animation steps (x*y) the texture is divided. 1x1 is default.</div></li><li
<li><div> Optionally, tell the Emitter whether the animation steps are to be at random, or in order.</div> class="level1"><div
</li> class="li"> Optionally, tell the Emitter whether the animation steps are to be at random, or in order.</div></li></ol><p> As you see in the debris example, texture animations improve effects because each &quot;flame&quot; or &quot;piece of debris&quot; looks different. Also think of electric or magic effects, where you can create very interesting animations by using an ordered morphing series of lightning bolts; or flying leaves or snow flakes, for instance.</p></div><h3><a
</ol> name="default_particle_textures">Default Particle Textures</a></h3><div
class="level3"><p> The following effect textures are some of the example textures included in <code>test-data.jar</code>.</p><div
<p> class="table sectionedit1"><table
class="inline"><tr
As you see in the debris example, texture animations improve effects because each “flame” or “piece of debris” looks different. Also think of electric or magic effects, where you can create very interesting animations by using an ordered morphing series of lightning bolts; or flying leaves or snow flakes, for instance. class="row0"><th
</p> class="col0 leftalign"> Texture Path</th><th
class="col1"> Dimension</th><th
</div> class="col2"> Preview</th></tr><tr
class="row1"><td
<h3><a>Default Particle Textures</a></h3> class="col0 leftalign"> Effects/Explosion/Debris.png</td><td
<div> class="col1 leftalign"> 3*3</td><td
class="col2"> <a
<p> href="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png"><img
src="/wiki/lib/exe/fetch.php?hash=3fc13d&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2FDebris.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
The following effect textures are some of the example textures included in <code>test-data.jar</code>. class="row2"><td
class="col0 leftalign"> Effects/Explosion/flame.png</td><td
</p> class="col1 leftalign"> 2*2</td><td
<table> class="col2"> <a
<tr> href="/wiki/lib/exe/fetch.php?hash=27332f&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png"><img
<th> Texture Path </th><th> Dimension </th><th> Preview </th> src="/wiki/lib/exe/fetch.php?hash=27332f&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
</tr> class="row3"><td
<tr> class="col0 leftalign"> Effects/Explosion/shockwave.png</td><td
<td> Effects/Explosion/Debris.png </td><td> 3*3 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col1 leftalign"> 1*1</td><td
</tr> class="col2"> <a
<tr> href="/wiki/lib/exe/fetch.php?hash=fc0cbc&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fshockwave.png"><img
<td> Effects/Explosion/flame.png </td><td> 2*2 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> src="/wiki/lib/exe/fetch.php?hash=fc0cbc&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fshockwave.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
</tr> class="row4"><td
<tr> class="col0"> Effects/Explosion/smoketrail.png</td><td
<td> Effects/Explosion/shockwave.png </td><td> 1*1 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col1 leftalign"> 1*3</td><td
</tr> class="col2"> <a
<tr> href="/wiki/lib/exe/fetch.php?hash=cb2aa9&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fsmoketrail.png"><img
<td> Effects/Explosion/smoketrail.png </td><td> 1*3 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> src="/wiki/lib/exe/fetch.php?hash=cb2aa9&amp;w=32&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fsmoketrail.png" class="media" alt="" width="32" height="32" /></a></td></tr><tr
</tr> class="row5"><td
<tr> class="col0 leftalign"> Effects/Smoke/Smoke.png</td><td
<td> Effects/Smoke/Smoke.png </td><td> 1*15 </td><td> <img src="/wiki/lib/exe/fetch.php"> </td> class="col1"> 1*15</td><td
</tr> class="col2"> <a
</table> href="/wiki/lib/exe/fetch.php?hash=9adb0f&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FSmoke%2FSmoke.png"><img
src="/wiki/lib/exe/fetch.php?hash=9adb0f&amp;w=96&amp;h=32&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FSmoke%2FSmoke.png" class="media" alt="" width="96" height="32" /></a></td></tr></table></div><p> Copy them into you <code>assets/Effects</code> directory to use them.</p></div><h2><a
<p> name="creating_custom_textures">Creating Custom Textures</a></h2><div
class="level2"><p> For your game, you will likely create custom textures. Look at the fire example again.</p><pre> ParticleEmitter fire = new ParticleEmitter&#40;&quot;Emitter&quot;, ParticleMesh.Type.Triangle, 30&#41;;
Copy them into you <code>assets/Effects</code> directory to use them.
</p>
</div>
<h2><a>Creating Custom Textures</a></h2>
<div>
<p>
For your game, you will likely create custom textures. Look at the fire example again.
</p>
<pre> ParticleEmitter fire = new ParticleEmitter&#40;&quot;Emitter&quot;, ParticleMesh.Type.Triangle, 30&#41;;
Material mat_red = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;; Material mat_red = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Particle.j3md&quot;&#41;;
mat_red.setTexture&#40;&quot;m_Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/flame.png&quot;&#41;&#41;; mat_red.setTexture&#40;&quot;m_Texture&quot;, assetManager.loadTexture&#40;&quot;Effects/Explosion/flame.png&quot;&#41;&#41;;
fire.setMaterial&#40;mat_red&#41;; fire.setMaterial&#40;mat_red&#41;;
fire.setImagesX&#40;2&#41;; // columns fire.setImagesX&#40;2&#41;; // columns
fire.setImagesY&#40;2&#41;; // rows fire.setImagesY&#40;2&#41;; // rows
fire.setEndColor&#40; new ColorRGBA&#40;1f, 0f, 0f, 1f&#41;&#41;; // red fire.setEndColor&#40; new ColorRGBA&#40;1f, 0f, 0f, 1f&#41;&#41;; // red
fire.setStartColor&#40;new ColorRGBA&#40;1f, 1f, 0f, 0.5f&#41;&#41;; // yellow</pre> fire.setStartColor&#40;new ColorRGBA&#40;1f, 1f, 0f, 0.5f&#41;&#41;; // yellow</pre><p> <a
<p> href="/wiki/lib/exe/fetch.php?hash=27332f&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png"><img
<img src="/wiki/lib/exe/fetch.php"> src="/wiki/lib/exe/fetch.php?hash=27332f&amp;w=96&amp;h=96&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FEffects%2FExplosion%2Fflame.png" class="mediaright" align="right" alt="" width="96" height="96" /></a></p><ul><li
</p> class="level1"><div
<ul> class="li"> Black parts of the image will be rendered transparent.</div></li><li
<li><div> Black parts of the image will be rendered transparent. </div> class="level1"><div
</li> class="li"> White/gray parts of the image are transparent and will be colored.</div></li><li
<li><div> White/gray parts of the image are transparent and will be colored.</div> class="level1"><div
</li> class="li"> You set the color (here, a gradient from yellow to red) in the code.</div></li><li
<li><div> You set the color (here, a gradient from yellow to red) in the code. </div> class="level1"><div
</li> class="li"> By default the animation will be played in order (?) and loop.</div></li></ul><p> Create a grayscale texture in a graphic editor, and save it to your <code>assets/Effects</code> directory. If you split up one image file into x*y animation steps, make sure each animation step is of equal size–just as you see in the examples here.</p></div><h3><a
<li><div> By default the animation will be played in order (?) and loop.</div> name="emitter_parameters">Emitter Parameters</a></h3><div
</li> class="level3"><p> A particle system is always centered around an emitter.</p><p> Use the <code>setShape()</code> method to change the EmitterShape:</p><ul><li
</ul> class="level1"><div
class="li"> EmitterPointShape(Vector3f.ZERO) – default shape</div></li><li
<p> class="level1"><div
class="li"> EmitterSphereShape(Vector3f.ZERO,2f)</div></li><li
Create a grayscale texture in a graphic editor, and save it to your <code>assets/Effects</code> directory. If you split up one image file into x*y animation steps, make sure each animation step is of equal size–just as you see in the examples here. class="level1"><div
</p> class="li"> EmitterBoxShape(new Vector3f(-1f,-1f,-1f),new Vector3f(1f,1f,1f))</div></li></ul><p> Example: <code>emitter.setShape(new EmitterPointShape(Vector3f.ZERO));</code></p><p> You create different effects by changing the emitter parameters:</p><div
class="table sectionedit2"><table
</div> class="inline"><tr
class="row0"><th
<h3><a>Emitter Parameters</a></h3> class="col0 leftalign"> Parameter</th><th
<div> class="col1"> Method (default value)</th><th
class="col2"> Description</th></tr><tr
<p> class="row1"><td
class="col0 leftalign"> number</td><td
A particle system is always centered around an emitter. class="col1"> <code>setNumParticles()</code></td><td
</p> class="col2"> The maximum number of particles visible at the same time. Value is specified by user in constructor.</td></tr><tr
class="row2"><td
<p> class="col0 leftalign"> velocity</td><td
Use the <code>setShape()</code> method to change the EmitterShape: class="col1"> <code>setInitialVelocity()</code> (Vector3f.ZERO)</td><td
</p> class="col2"> You must specify a vector how fast particles should move and it which start direction.</td></tr><tr
<ul> class="row3"><td
<li><div> EmitterPointShape(Vector3f.ZERO) – default shape</div> class="col0 leftalign"> direction</td><td
</li> class="col1"> <code>setVelocityVariation()</code> (0.2f) <br/> <code>setFacingVelocity()</code> (false) <br/> <code>setRandomAngle()</code> (false) <br/> <code>setFaceNormal()</code> (Vector3f.NAN) <br/> <code>setRotateSpeed()</code> (0f)</td><td
<li><div> EmitterSphereShape(Vector3f.ZERO,2f)</div> class="col2"> Optional accessors that control in which direction particles face when flying.</td></tr><tr
</li> class="row4"><td
<li><div> EmitterBoxShape(new Vector3f(-1f,-1f,-1f),new Vector3f(1f,1f,1f))</div> class="col0 leftalign"> lifetime</td><td
</li> class="col1"> <code>setLowLife()</code> (3f) <br/> <code>setHighLife()</code> (7f)</td><td
</ul> class="col2"> Minimum and maximum time period before particles fade.</td></tr><tr
class="row5"><td
<p> class="col0 leftalign"> emission rate</td><td
Example: <code>emitter.setShape(new EmitterPointShape(Vector3f.ZERO));</code> class="col1"> <code>setParticlesPerSec()</code> (20)</td><td
</p> class="col2"> How many new particles are emitted per second.</td></tr><tr
class="row6"><td
<p> class="col0 leftalign"> color</td><td
You create different effects by changing the emitter parameters: class="col1"> <code>setStartColor()</code> <br/> <code>setEndColor()</code> (gray)</td><td
class="col2"> Set to two different colors for gradient effects, or to same color.</td></tr><tr
</p> class="row7"><td
<table> class="col0 leftalign"> size</td><td
<tr> class="col1"> <code>setStartSize()</code> (0.2f) <br/> <code>setEndSize()</code> (2f)</td><td
<th> Parameter </th><th> Method (default value) </th><th> Description </th> class="col2"> Set to two different values for shrink/grow effect, or to same size.</td></tr><tr
</tr> class="row8"><td
<tr> class="col0 leftalign"> gravity</td><td
<td> number </td><td> <code>setNumParticles()</code> </td><td> The maximum number of particles visible at the same time. Value is specified by user in constructor. </td> class="col1"> <code>setGravity()</code> (0.1f)</td><td
</tr> class="col2"> Whether particles falls down eventually. Set to 0f for zero-g effects.</td></tr></table></div><p> You can find details about <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters#configure_parameters.html">effect parameters</a> in the user guide.
<td> velocity </td><td> <code>setInitialVelocity()</code> (Vector3f.ZERO) </td><td> You must specify a vector how fast particles should move and it which start direction. </td> Add and modify one paramter at a time, and try different values until you get the effect you want. <strong>Tip:</strong> Use the jMonkeyPlatform SceneComposer to preview effects settings (instructions: TODO).</p></div><h2><a
</tr> name="exercise">Exercise</a></h2><div
<tr> class="level2"><p> Can you &quot;invert&quot; the campfire into a small waterfall?</p><ul><li
<td> direction </td><td> <code>setVelocityVariation()</code> (0.2f) <br/> class="level1"><div
<code>setFacingVelocity()</code> (false) <br/> class="li"> Change the Red and Yellow color to Cyan and Blue…</div></li><li
<code>setRandomAngle()</code> (false) <br/> class="level1"><div
<code>setFaceNormal()</code> (Vector3f.NAN) <br/> class="li"> Invert the velocity vector (direction) by using a negative number…</div></li><li
<code>setRotateSpeed()</code> (0f) </td><td> Optional accessors that control in which direction particles face when flying. </td> class="level1"><div
</tr> class="li"> Swap start and end size…</div></li><li
<tr> class="level1"><div
<td> lifetime </td><td> <code>setLowLife()</code> (3f) <br/> class="li"> Activate gravity by setting it to 1…</div></li></ul></div><h2><a
<code>setHighLife()</code> (7f) </td><td> Minimum and maximum time period before particles fade. </td> name="conclusion">Conclusion</a></h2><div
</tr> class="level2"><p> You have learned that many different effects can be created by changing the parameters and textures of one general emitter object.</p><p> Now we move on to the next exciting chapter – the simulation of <a
<tr> href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics">physical objects</a>. Let&#039;s shoot some cannon balls at a brick wall!</p><div
<td> emission rate </td><td> <code>setParticlesPerSec()</code> (20) </td><td> How many new particles are emitted per second. </td> class="tags"><span> <a
</tr> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
<tr> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<td> color </td><td> <code>setStartColor()</code> <br/> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<code>setEndColor()</code> (gray)</td><td> Set to two different colors for gradient effects, or to same color. </td> href="/wiki/doku.php/tag:transparency?do=showtag&amp;tag=tag%3Atransparency">transparency</a>, <a
</tr> href="/wiki/doku.php/tag:effect?do=showtag&amp;tag=tag%3Aeffect">effect</a> </span></div></div>
<tr>
<td> size </td><td> <code>setStartSize()</code> (0.2f) <br/>
<code>setEndSize()</code> (2f) </td><td> Set to two different values for shrink/grow effect, or to same size. </td>
</tr>
<tr>
<td> gravity </td><td> <code>setGravity()</code> (0.1f) </td><td> Whether particles falls down eventually. Set to 0f for zero-g effects. </td>
</tr>
</table>
<p>
You can find details about <a href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters#configure_parameters.html">effect parameters</a> in the user guide.
Add and modify one paramter at a time, and try different values until you get the effect you want. <strong>Tip:</strong> Use the jMonkeyPlatform SceneComposer to preview effects settings (instructions: TODO).
</p>
</div>
<h2><a>Exercise</a></h2>
<div>
<p>
Can you “invert” the campfire into a small waterfall?
</p>
<ul>
<li><div> Change the Red and Yellow color to Cyan and Blue…</div>
</li>
<li><div> Invert the velocity vector (direction) by using a negative number…</div>
</li>
<li><div> Swap start and end size…</div>
</li>
<li><div> Activate gravity by setting it to 1…</div>
</li>
</ul>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned that many different effects can be created by changing the parameters and textures of one general emitter object.
</p>
<p>
Now we move on to the next exciting chapter – the simulation of <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics"><param name="text" value="<html><u>physical objects</u></html>"><param name="textColor" value="blue"></object>. Let&#039;s shoot some cannon balls at a brick wall!
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:transparency?do=showtag&amp;tag=tag%3Atransparency">transparency</a>,
<a href="/wiki/doku.php/tag:effect?do=showtag&amp;tag=tag%3Aeffect">effect</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_effects?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_effects?do=export_xhtmlbody">view online version</a></em></p>

@ -1,26 +1,11 @@
<h1><a
<h1><a>JME 3 Tutorial (5) - Hello Input System</a></h1> name="jme_3_tutorial_5_-_hello_input_system">JME 3 Tutorial (5) - Hello Input System</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Update Loop</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></p><p> By default, SimpleApplication sets up an input system that allows you to steer the camera with the WASD keys, the arrow keys, and the mouse. You can use it as a flying first-person camera right away. But what if you need a third-person camera, or you want keys to trigger special game actions?</p><p> Every game has its custom keybindings, and this tutorial explains how you define them. We first define the key presses and mouse events, and then we define the actions they should trigger.</p></div><h2><a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Update Loop</a>, name="sample_code">Sample Code</a></h2><div
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> class="level2"><pre>package jme3test.helloworld;
</p>
<p>
By default, SimpleApplication sets up an input system that allows you to steer the camera with the WASD keys, the arrow keys, and the mouse. You can use it as a flying first-person camera right away. But what if you need a third-person camera, or you want keys to trigger special game actions?
</p>
<p>
Every game has its custom keybindings, and this tutorial explains how you define them. We first define the key presses and mouse events, and then we define the actions they should trigger.
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.material.Material; import com.jme3.material.Material;
@ -97,59 +82,31 @@ public class HelloInput extends SimpleApplication &#123;
&#125; &#125;
&#125; &#125;
&#125;; &#125;;
&#125;</pre> &#125;</pre><p> Build and run the example.</p><ul><li
<p> class="level1"><div
Build and run the example. class="li"> Press the Spacebar or click to rotate the cube.</div></li><li
</p> class="level1"><div
<ul> class="li"> Press the J and K keys to move the cube.</div></li><li
<li><div> Press the Spacebar or click to rotate the cube. </div> class="level1"><div
</li> class="li"> Press P to pause and unpause the game. While paused, the game should not respond to any input, other than <code>P</code>.</div></li></ul></div><h2><a
<li><div> Press the J and K keys to move the cube.</div> name="defining_mappings_and_triggers">Defining Mappings and Triggers</a></h2><div
</li> class="level2"><p> First you register each mapping name with its trigger(s). Remember the following:</p><ul><li
<li><div> Press P to pause and unpause the game. While paused, the game should not respond to any input, other than <code>P</code>.</div> class="level1"><div
</li> class="li"> The trigger can be a key press or mouse action.</div></li><li
</ul> class="level1"><div
class="li"> The mapping name is a string that you can choose. <br/> The name should describe the action, not the trigger.</div></li><li
</div> class="level1"><div
class="li"> One named mapping can have several triggers. <br/> The &quot;Rotate&quot; action can be triggered by a click and by pressing the spacebar.</div></li></ul><p> Have a look at the code:</p><ol><li
<h2><a>Defining Mappings and Triggers</a></h2> class="level1"><div
<div> class="li"> You register the mapping named &quot;Rotate&quot; to the Spacebar trigger <br/> <code>new KeyTrigger(KeyInput.KEY_SPACE)</code>).</div></li><li
class="level1"><div
<p> class="li"> In the same line, you also register &quot;Rotate&quot; to the mouse button trigger <br/> <code>new MouseButtonTrigger(MouseInput.BUTTON_LEFT)</code></div></li><li
class="level1"><div
First you register each mapping name with its trigger(s). Remember the following: class="li"> You map the <code>Pause, Left, Right</code> mappings to the P, J, K keys, respectively.</div></li><li
class="level1"><div
</p> class="li"> You register the (on/off) pause action to the ActionListener</div></li><li
<ul> class="level1"><div
<li><div> The trigger can be a key press or mouse action.</div> class="li"> You register the (gradual) movement actions to the AnalogListener</div></li></ol><pre> // You can map one or several inputs to one named action
</li>
<li><div> The mapping name is a string that you can choose. <br/>
The name should describe the action, not the trigger.</div>
</li>
<li><div> One named mapping can have several triggers. <br/>
The “Rotate” action can be triggered by a click and by pressing the spacebar.</div>
</li>
</ul>
<p>
Have a look at the code:
</p>
<ol>
<li><div> You register the mapping named “Rotate” to the Spacebar trigger <br/>
<code>new KeyTrigger(KeyInput.KEY_SPACE)</code>). </div>
</li>
<li><div> In the same line, you also register “Rotate” to the mouse button trigger <br/>
<code>new MouseButtonTrigger(MouseInput.BUTTON_LEFT)</code></div>
</li>
<li><div> You map the <code>Pause, Left, Right</code> mappings to the P, J, K keys, respectively. </div>
</li>
<li><div> You register the (on/off) pause action to the ActionListener </div>
</li>
<li><div> You register the (gradual) movement actions to the AnalogListener</div>
</li>
</ol>
<pre> // You can map one or several inputs to one named action
inputManager.addMapping&#40;&quot;Pause&quot;, new KeyTrigger&#40;KeyInput.KEY_P&#41;&#41;; inputManager.addMapping&#40;&quot;Pause&quot;, new KeyTrigger&#40;KeyInput.KEY_P&#41;&#41;;
inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_J&#41;&#41;; inputManager.addMapping&#40;&quot;Left&quot;, new KeyTrigger&#40;KeyInput.KEY_J&#41;&#41;;
inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_K&#41;&#41;; inputManager.addMapping&#40;&quot;Right&quot;, new KeyTrigger&#40;KeyInput.KEY_K&#41;&#41;;
@ -157,40 +114,17 @@ Have a look at the code:
new MouseButtonTrigger&#40;MouseInput.BUTTON_LEFT&#41;&#41;; new MouseButtonTrigger&#40;MouseInput.BUTTON_LEFT&#41;&#41;;
// Add the names to the action listener. // Add the names to the action listener.
inputManager.addListener&#40;actionListener, new String&#91;&#93;&#123;&quot;Pause&quot;&#125;&#41;; inputManager.addListener&#40;actionListener, new String&#91;&#93;&#123;&quot;Pause&quot;&#125;&#41;;
inputManager.addListener&#40;analogListener, new String&#91;&#93;&#123;&quot;Left&quot;, &quot;Right&quot;, &quot;Rotate&quot;&#125;&#41;;</pre> inputManager.addListener&#40;analogListener, new String&#91;&#93;&#123;&quot;Left&quot;, &quot;Right&quot;, &quot;Rotate&quot;&#125;&#41;;</pre><p> This code usually goes into the <code>simpleInitApp()</code> method. But since we will likely add many keybindings, we extract these lines and wrap them in an auxiliary method, <code>initKeys()</code>. The <code>initKeys()</code> method is not part of the Input Controls interface – so you can name it whatever you like. Just don&#039;t forget to call your method from the <code>initSimpleApp()</code> method.</p></div><h2><a
<p> name="implementing_the_actions">Implementing the Actions</a></h2><div
This code usually goes into the <code>simpleInitApp()</code> method. But since we will likely add many keybindings, we extract these lines and wrap them in an auxiliary method, <code>initKeys()</code>. The <code>initKeys()</code> method is not part of the Input Controls interface – so you can name it whatever you like. Just don&#039;t forget to call your method from the <code>initSimpleApp()</code> method. class="level2"><p> Now you have mapped action names to input triggers. Now you specify the actions themselves.</p><p> The two important methods here are the <code>ActionListener</code> with its <code>onAction()</code> method, and the <code>AnalogListener</code> with its <code>onAnalog()</code> method. In these two methods, you test for each named mapping, and call the game action you want to trigger.</p><p> In this example, we set the following mappings:</p><ol><li
</p> class="level1"><div
class="li"> The <em>Rotate</em> mapping triggers the action <code>player.rotate(0, value, 0)</code>.</div></li><li
</div> class="level1"><div
class="li"> The <em>Left</em> and <em>Right</em> mappings increase and decrease the player&#039;s x coordinate.</div></li><li
<h2><a>Implementing the Actions</a></h2> class="level1"><div
<div> class="li"> The <em>Pause</em> mapping flips a boolean <code>isRunning</code>.</div></li><li
class="level1"><div
<p> class="li"> We also want to check the boolean <code>isRunning</code> before any action (other than unpausing) is executed.</div></li></ol><pre> private ActionListener&#40;&#41; &#123;
Now you have mapped action names to input triggers. Now you specify the actions themselves.
</p>
<p>
The two important methods here are the <code>ActionListener</code> with its <code>onAction()</code> method, and the <code>AnalogListener</code> with its <code>onAnalog()</code> method. In these two methods, you test for each named mapping, and call the game action you want to trigger.
</p>
<p>
In this example, we set the following mappings:
</p>
<ol>
<li><div> The <em>Rotate</em> mapping triggers the action <code>player.rotate(0, value, 0)</code>. </div>
</li>
<li><div> The <em>Left</em> and <em>Right</em> mappings increase and decrease the player&#039;s x coordinate. </div>
</li>
<li><div> The <em>Pause</em> mapping flips a boolean <code>isRunning</code>. </div>
</li>
<li><div> We also want to check the boolean <code>isRunning</code> before any action (other than unpausing) is executed.</div>
</li>
</ol>
<pre> private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
if &#40;name.equals&#40;&quot;Pause&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; if &#40;name.equals&#40;&quot;Pause&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
isRunning = !isRunning; isRunning = !isRunning;
@ -216,145 +150,76 @@ In this example, we set the following mappings:
System.out.println&#40;&quot;Press P to unpause.&quot;&#41;; System.out.println&#40;&quot;Press P to unpause.&quot;&#41;;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre><p> It&#039;s okay to use only one of the two Listeners, and not implement the other one, if you are not using this type of interaction. In the following, we have a closer look how to decide which of the two listeners is best suited for which situation.</p></div><h2><a
<p> name="analog_pressed_or_released">Analog, Pressed, or Released?</a></h2><div
It&#039;s okay to use only one of the two Listeners, and not implement the other one, if you are not using this type of interaction. In the following, we have a closer look how to decide which of the two listeners is best suited for which situation. class="level2"><p> Technically, every input can be an &quot;Analog&quot; or a &quot;on-off Action&quot;. Here is how you find out which listener is the right one for which type of input.</p><p> Mappings registered to the <strong>AnalogListener</strong> are triggered repeatedly and gradually.</p><ul><li
</p> class="level1"><div
class="li"> Parameters:</div><ol><li
</div> class="level2"><div
class="li"> JME gives you access to the name of the triggered action.</div></li><li
<h2><a>Analog, Pressed, or Released?</a></h2> class="level2"><div
<div> class="li"> JME gives you access to a gradual value between 0-9 how long the key has been pressed.</div></li></ol></li><li
class="level1"><div
<p> class="li"> Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously.</div></li></ul><p> Mappings registered to the <strong>ActionListener</strong> are treated in an absolute way – &quot;Pressed or released? On or off?&quot;</p><ul><li
class="level1"><div
Technically, every input can be an “Analog” or a “on-off Action”. Here is how you find out which listener is the right one for which type of input. class="li"> Parameters:</div><ol><li
</p> class="level2"><div
class="li"> JME gives you access to the name of the triggered action.</div></li><li
<p> class="level2"><div
Mappings registered to the <strong>AnalogListener</strong> are triggered repeatedly and gradually. class="li"> JME gives you access to a boolean whether the key is pressed or not.</div></li></ol></li><li
</p> class="level1"><div
<ul> class="li"> Example: Pause button, shooting, selecting, jumping, one-time click interactions.</div></li></ul><p> <strong>Tip:</strong> It&#039;s very common that you want an action to be only triggered once, in the moment when the key is <em>released</em>. For instance when opening a door, flipping a boolean state, or picking up an item. To achieve that, you use an <code>ActionListener</code> and test for <code>&amp;&amp; !keyPressed</code>. For an example, look at the Pause button code.</p><pre> if &#40;name.equals&#40;&quot;Pause&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
<li><div> Parameters: </div>
<ol>
<li><div> JME gives you access to the name of the triggered action.</div>
</li>
<li><div> JME gives you access to a gradual value between 0-9 how long the key has been pressed.</div>
</li>
</ol>
</li>
<li><div> Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously. </div>
</li>
</ul>
<p>
Mappings registered to the <strong>ActionListener</strong> are treated in an absolute way – “Pressed or released? On or off?”
</p>
<ul>
<li><div> Parameters: </div>
<ol>
<li><div> JME gives you access to the name of the triggered action.</div>
</li>
<li><div> JME gives you access to a boolean whether the key is pressed or not.</div>
</li>
</ol>
</li>
<li><div> Example: Pause button, shooting, selecting, jumping, one-time click interactions.</div>
</li>
</ul>
<p>
<strong>Tip:</strong> It&#039;s very common that you want an action to be only triggered once, in the moment when the key is <em>released</em>. For instance when opening a door, flipping a boolean state, or picking up an item. To achieve that, you use an <code>ActionListener</code> and test for <code>&amp;&amp; !keyPressed</code>. For an example, look at the Pause button code.
</p>
<pre> if &#40;name.equals&#40;&quot;Pause&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
isRunning = !isRunning; isRunning = !isRunning;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="table_of_triggers">Table of Triggers</a></h2><div
class="level2"><p> You can find the list of input constants in the files <code>src/core/com/jme3/input/KeyInput.java</code>, <code>JoyInput.java</code>, and <code>MouseInput.java</code>. Here is an overview of the most common triggers constants:</p><div
<h2><a>Table of Triggers</a></h2> class="table sectionedit1"><table
<div> class="inline"><tr
class="row0"><th
<p> class="col0"> Trigger</th><th
class="col1"> Code</th></tr><tr
You can find the list of input constants in the files <code>src/core/com/jme3/input/KeyInput.java</code>, <code>JoyInput.java</code>, and <code>MouseInput.java</code>. Here is an overview of the most common triggers constants: class="row1"><td
class="col0"> Mouse button: Left Click</td><td
</p> class="col1"> MouseButtonTrigger(MouseInput.BUTTON_LEFT)</td></tr><tr
<table> class="row2"><td
<tr> class="col0"> Mouse button: Right Click</td><td
<th> Trigger </th><th> Code </th> class="col1"> MouseButtonTrigger(MouseInput.BUTTON_RIGHT)</td></tr><tr
</tr> class="row3"><td
<tr> class="col0"> Keyboard: Characters and Numbers</td><td
<td> Mouse button: Left Click </td><td> MouseButtonTrigger(MouseInput.BUTTON_LEFT) </td> class="col1"> KeyTrigger(KeyInput.KEY_X)</td></tr><tr
</tr> class="row4"><td
<tr> class="col0 leftalign"> Keyboard: Spacebar</td><td
<td> Mouse button: Right Click </td><td> MouseButtonTrigger(MouseInput.BUTTON_RIGHT) </td> class="col1"> KeyTrigger(KeyInput.KEY_SPACE)</td></tr><tr
</tr> class="row5"><td
<tr> class="col0"> Keyboard: Return, Enter</td><td
<td> Keyboard: Characters and Numbers </td><td> KeyTrigger(KeyInput.KEY_X) </td> class="col1 leftalign"> KeyTrigger(KeyInput.KEY_RETURN), KeyTrigger(KeyInput.KEY_NUMPADENTER)</td></tr><tr
</tr> class="row6"><td
<tr> class="col0"> Keyboard: Escape</td><td
<td> Keyboard: Spacebar </td><td> KeyTrigger(KeyInput.KEY_SPACE) </td> class="col1"> KeyTrigger(KeyInput.KEY_ESCAPE)</td></tr><tr
</tr> class="row7"><td
<tr> class="col0"> Keyboard: Arrows</td><td
<td> Keyboard: Return, Enter </td><td> KeyTrigger(KeyInput.KEY_RETURN), KeyTrigger(KeyInput.KEY_NUMPADENTER) </td> class="col1"> KeyTrigger(KeyInput.KEY_UP), KeyTrigger(KeyInput.KEY_DOWN) <br/> KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT)</td></tr></table></div><p> <strong>Tip:</strong> If you don&#039;t recall an input constant during development, you benefit from an IDE&#039;s code completion functionality: Place the caret after e.g. <code>KeyInput.|</code> and trigger code completion to select possible input identifiers.</p></div><h2><a
</tr> name="exercises">Exercises</a></h2><div
<tr> class="level2"><ol><li
<td> Keyboard: Escape </td><td> KeyTrigger(KeyInput.KEY_ESCAPE) </td> class="level1"><div
</tr> class="li"> Add mappings for moving the player (box) up and down with the H and L keys.</div></li><li
<tr> class="level1"><div
<td> Keyboard: Arrows </td><td> KeyTrigger(KeyInput.KEY_UP), KeyTrigger(KeyInput.KEY_DOWN) <br/> class="li"> Modify the mappings so that you can also trigger the up an down motion with the mouse scroll wheel.</div><ul><li
KeyTrigger(KeyInput.KEY_LEFT), KeyTrigger(KeyInput.KEY_RIGHT) </td> class="level2"><div
</tr> class="li"> Tip: Use <code>new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)</code></div></li></ul></li><li
</table> class="level1"><div
class="li"> In which situation would it be better to use variables for the MouseInput/KeyInput definitions?<pre>int usersPauseKey = KeyInput.KEY_P;
<p>
<strong>Tip:</strong> If you don&#039;t recall an input constant during development, you benefit from an IDE&#039;s code completion functionality: Place the caret after e.g. <code>KeyInput.|</code> and trigger code completion to select possible input identifiers.
</p>
</div>
<h2><a>Exercises</a></h2>
<div>
<ol>
<li><div> Add mappings for moving the player (box) up and down with the H and L keys.</div>
</li>
<li><div> Modify the mappings so that you can also trigger the up an down motion with the mouse scroll wheel.</div>
<ul>
<li><div> Tip: Use <code>new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)</code></div>
</li>
</ul>
</li>
<li><div> In which situation would it be better to use variables for the MouseInput/KeyInput definitions? <pre>int usersPauseKey = KeyInput.KEY_P;
... ...
inputManager.addMapping&#40;&quot;Pause&quot;, new KeyTrigger&#40;usersPauseKey&#41;&#41;;</pre></div> inputManager.addMapping&#40;&quot;Pause&quot;, new KeyTrigger&#40;usersPauseKey&#41;&#41;;</pre></div></li></ol></div><h2><a
</li> name="conclusion">Conclusion</a></h2><div
</ol> class="level2"><p> You now how to add custom interactions to your game: You know now that you first have to define the key mappings, and then the actions for each mapping. You have learned to respond to mouse events and to the keyboard. You understand the difference between &quot;analog&quot; (gradually repeated) and &quot;digital&quot; (on/off) inputs.</p><p> Now you can already write a little interactive game! But wouldn&#039;t it be cooler if these old boxes were a bit more fancy? Let&#039;s continue with learning about <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">materials</a>.</p><div
</div> class="tags"><span> <a
href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<h2><a>Conclusion</a></h2> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<div> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
<p> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
You now how to add custom interactions to your game: You know now that you first have to define the key mappings, and then the actions for each mapping. You have learned to respond to mouse events and to the keyboard. You understand the difference between “analog” (gradually repeated) and “digital” (on/off) inputs. href="/wiki/doku.php/tag:click?do=showtag&amp;tag=tag%3Aclick">click</a> </span></div></div>
</p>
<p>
Now you can already write a little interactive game! But wouldn&#039;t it be cooler if these old boxes were a bit more fancy? Let&#039;s continue with learning about <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">materials</a>.
</p>
<div><span>
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:click?do=showtag&amp;tag=tag%3Aclick">click</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_input_system?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_input_system?do=export_xhtmlbody">view online version</a></em></p>

@ -1,22 +1,11 @@
<h1><a
<h1><a>JME 3 Tutorial (4) - Hello Update Loop</a></h1> name="jme_3_tutorial_4_-_hello_update_loop">JME 3 Tutorial (4) - Hello Update Loop</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Assets</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input System</a></p><p> Now that you know how to load assets such as 3-D models, you want them to implement the actual gameplay. In this tutorial we look at the update loop. The update loop of your game is where the action happens.</p></div><h2><a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Assets</a>, name="code_sample">Code Sample</a></h2><div
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input System</a> class="level2"><pre>package jme3test.helloworld;
</p>
<p>
Now that you know how to load assets such as 3-D models, you want them to implement the actual gameplay. In this tutorial we look at the update loop. The update loop of your game is where the action happens.
</p>
</div>
<h2><a>Code Sample</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.material.Material; import com.jme3.material.Material;
@ -53,110 +42,50 @@ public class HelloLoop extends SimpleApplication &#123;
// make the player rotate // make the player rotate
player.rotate&#40;0, 2*tpf, 0&#41;; player.rotate&#40;0, 2*tpf, 0&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Build and run the file: You see a constantly rotating cube.</p></div><h2><a
<p> name="understanding_the_code">Understanding the Code</a></h2><div
Build and run the file: You see a constantly rotating cube. class="level2"><p> Compared to our previous code samples you note that the player Geometry is now a class field. This is because we want the update loop to be able to access and transform this Geometry. As you can see, we initialize the player object in the <code>simpleInitApp()</code> method.</p><p> Now have a closer look at the <code>simpleUpdate()</code> method, this is the update loop.</p><ul><li
</p> class="level1"><div
class="li"> The <code>player.rotate(0, 2*tpf, 0);</code> line changes the rotation of the player object.</div></li><li
</div> class="level1"><div
class="li"> We use the <code>tpf</code> variable (&quot;time per frame&quot;) to time this action depending on the current frames per second rate. This means the cube rotates with the same speed on fast machines, and the game remains playable.</div></li></ul></div><h2><a
<h2><a>Understanding the Code</a></h2> name="the_update_loop">The Update Loop</a></h2><div
<div> class="level2"><p> A rotating object is just a simple example. In the update loop, you can update score and health points, check for collisions, make enemies calculate their next move, roll the dice whether a trap has been set off, play random ambient sounds, and much more.</p><ul><li
class="level1"><div
<p> class="li"> The update loop starts after the <code>simpleInitApp()</code> method has set up the scenegraph and state variables.</div></li><li
class="level1"><div
Compared to our previous code samples you note that the player Geometry is now a class field. This is because we want the update loop to be able to access and transform this Geometry. As you can see, we initialize the player object in the <code>simpleInitApp()</code> method. class="li"> JME executes everything in the <code>simpleUpdate()</code> method repeatedly, as fast as possible.</div><ol><li
</p> class="level2"><div
class="li"> Use the loop to poll the game state and initiate actions.</div></li><li
<p> class="level2"><div
Now have a closer look at the <code>simpleUpdate()</code> method, this is the update loop. class="li"> Use the loop to trigger reactions and update the game state.</div></li><li
</p> class="level2"><div
<ul> class="li"> Use it wisely, because having too many calls in the loop also slows down the game.</div></li></ol></li></ul></div><h2><a
<li><div> The <code>player.rotate(0, 2*tpf, 0);</code> line changes the rotation of the player object. </div> name="exercises">Exercises</a></h2><div
</li> class="level2"><p> Here are some fun things to try:</p><ol><li
<li><div> We use the <code>tpf</code> variable (“time per frame”) to time this action depending on the current frames per second rate. This means the cube rotates with the same speed on fast machines, and the game remains playable.</div> class="level1"><div
</li> class="li"> What happens if you give the rotate() method negative numbers?</div></li><li
</ul> class="level1"><div
class="li"> Can you create two models next to each other, and make one rotate twice as fast as the other? (use the <code>tpf</code>)</div></li><li
</div> class="level1"><div
class="li"> Can you make a cube that pulsates? (grows and shrinks)</div></li><li
<h2><a>The Update Loop</a></h2> class="level1"><div
<div> class="li"> Can you make a rolling cube? (spin around the x axis, and translate along the z axis)</div></li></ol><p> Look back at the <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> tutorial if you do not remember the transformation methods for scaling, translating, and rotating.</p></div><h2><a
<p> name="conclusion">Conclusion</a></h2><div
class="level2"><p> Now you are listening to the update loop, &quot;the heart beat&quot; of the game, and you can add all kinds of action to it.</p><p> The next thing the game needs is some <em>inter</em>action! Continue learning how to <a
A rotating object is just a simple example. In the update loop, you can update score and health points, check for collisions, make enemies calculate their next move, roll the dice whether a trap has been set off, play random ambient sounds, and much more. href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">respond to user input</a>.</p><hr
/><p> See also: Advanced jME3 developers additionally use <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a
<ul> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> to implement more complex mechanics in their game loops. You will come across these topics later when you proceed to advanced documentation.</p><div
<li><div> The update loop starts after the <code>simpleInitApp()</code> method has set up the scenegraph and state variables.</div> class="tags"><span> <a
</li> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<li><div> JME executes everything in the <code>simpleUpdate()</code> method repeatedly, as fast as possible.</div> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
<ol> href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>, <a
<li><div> Use the loop to poll the game state and initiate actions. </div> href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>, <a
</li> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<li><div> Use the loop to trigger reactions and update the game state.</div> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</li> href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>, <a
<li><div> Use it wisely, because having too many calls in the loop also slows down the game. </div> href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a>, <a
</li> href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a> </span></div></div>
</ol>
</li>
</ul>
</div>
<h2><a>Exercises</a></h2>
<div>
<p>
Here are some fun things to try:
</p>
<ol>
<li><div> What happens if you give the rotate() method negative numbers?</div>
</li>
<li><div> Can you create two models next to each other, and make one rotate twice as fast as the other? (use the <code>tpf</code>)</div>
</li>
<li><div> Can you make a cube that pulsates? (grows and shrinks)</div>
</li>
<li><div> Can you make a rolling cube? (spin around the x axis, and translate along the z axis)</div>
</li>
</ol>
<p>
Look back at the <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> tutorial if you do not remember the transformation methods for scaling, translating, and rotating.
</p>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
Now you are listening to the update loop, “the heart beat” of the game, and you can add all kinds of action to it.
</p>
<p>
The next thing the game needs is some <em>inter</em>action! Continue learning how to <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">respond to user input</a>.
</p>
<hr />
<p>
See also: Advanced jME3 developers additionally use <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> to implement more complex mechanics in their game loops. You will come across these topics later when you proceed to advanced documentation.
</p>
<div><span>
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>,
<a href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>,
<a href="/wiki/doku.php/tag:controllers?do=showtag&amp;tag=tag%3Acontrollers">controllers</a>,
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_main_event_loop?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_main_event_loop?do=export_xhtmlbody">view online version</a></em></p>

@ -1,27 +1,15 @@
<h1><a
<h1><a>JME 3 Tutorial (6) - Hello Materials</a></h1> name="jme_3_tutorial_6_-_hello_materials">JME 3 Tutorial (6) - Hello Materials</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input System</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a> When we speak of Materials, we mean everything that influences what the surface of a 3D model looks like: The color, texture, and material (shininess, opacity/transparency). Simple coloring is covered in <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input System</a>, href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>. Loading models that come with materials is covered in <a
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a> href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>. Here we focus on using and creating JME3 Material Definitions. <a
</p> href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-materials.png?id=jme3%3Abeginner%3Ahello_material"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-materials.png?w=320&amp;h=250" class="mediacenter" alt="" width="320" height="250" /></a></p></div><h2><a
<p> name="sample_code">Sample Code</a></h2><div
When we speak of Materials, we mean everything that influences what the surface of a 3D model looks like: The color, texture, and material (shininess, opacity/transparency). Simple coloring is covered in <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>. Loading models that come with materials is covered in <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>. Here we focus on using and creating JME3 Material Definitions. class="level2"><pre>package jme3test.helloworld;
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-materials.png">
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
@ -34,21 +22,16 @@ import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.util.TangentBinormalGenerator; import com.jme3.util.TangentBinormalGenerator;
import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.renderer.queue.RenderQueue.Bucket;
&nbsp;
&nbsp;
<span>/** Sample 6 - how to give an object's surface a material and texture. <span>/** Sample 6 - how to give an object's surface a material and texture.
* How to make objects transparent, or let colors &quot;leak&quot; through partially * How to make objects transparent, or let colors &quot;leak&quot; through partially
* transparent textures. How to make bumpy and shiny surfaces. */</span> * transparent textures. How to make bumpy and shiny surfaces. */</span>
public class HelloMaterial extends SimpleApplication &#123; public class HelloMaterial extends SimpleApplication &#123;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
HelloMaterial app = new HelloMaterial&#40;&#41;; HelloMaterial app = new HelloMaterial&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
&nbsp;
/** A simple textured cube -- in good MIP map quality. */ /** A simple textured cube -- in good MIP map quality. */
Box&#40;new Vector3f&#40;-3f,1.1f,0f&#41;, 1f,1f,1f&#41;; Box&#40;new Vector3f&#40;-3f,1.1f,0f&#41;, 1f,1f,1f&#41;;
Geometry cube = new Geometry&#40;&quot;My Textured Box&quot;, boxshape1&#41;; Geometry cube = new Geometry&#40;&quot;My Textured Box&quot;, boxshape1&#41;;
@ -57,7 +40,6 @@ public class HelloMaterial extends SimpleApplication &#123;
mat_stl.setTexture&#40;&quot;ColorMap&quot;, tex_ml&#41;; mat_stl.setTexture&#40;&quot;ColorMap&quot;, tex_ml&#41;;
cube.setMaterial&#40;mat_stl&#41;; cube.setMaterial&#40;mat_stl&#41;;
rootNode.attachChild&#40;cube&#41;; rootNode.attachChild&#40;cube&#41;;
&nbsp;
/** A translucent/transparent texture, similar to a window frame. */ /** A translucent/transparent texture, similar to a window frame. */
Box&#40;new Vector3f&#40;0f,0f,0f&#41;, 1f,1f,0.01f&#41;; Box&#40;new Vector3f&#40;0f,0f,0f&#41;, 1f,1f,0.01f&#41;;
Geometry window_frame = new Geometry&#40;&quot;window frame&quot;, boxshape3&#41;; Geometry window_frame = new Geometry&#40;&quot;window frame&quot;, boxshape3&#41;;
@ -69,7 +51,6 @@ public class HelloMaterial extends SimpleApplication &#123;
/** Objects with transparency need to be in the render bucket for transparent objects: */ /** Objects with transparency need to be in the render bucket for transparent objects: */
window_frame.setQueueBucket&#40;Bucket.Transparent&#41;; window_frame.setQueueBucket&#40;Bucket.Transparent&#41;;
rootNode.attachChild&#40;window_frame&#41;; rootNode.attachChild&#40;window_frame&#41;;
&nbsp;
/** A cube with base color &quot;leaking&quot; through a partially transparent texture */ /** A cube with base color &quot;leaking&quot; through a partially transparent texture */
Box&#40;new Vector3f&#40;3f,-1f,0f&#41;, 1f,1f,1f&#41;; Box&#40;new Vector3f&#40;3f,-1f,0f&#41;, 1f,1f,1f&#41;;
Geometry cube_leak = new Geometry&#40;&quot;Leak-through color cube&quot;, boxshape4&#41;; Geometry cube_leak = new Geometry&#40;&quot;Leak-through color cube&quot;, boxshape4&#41;;
@ -79,7 +60,6 @@ public class HelloMaterial extends SimpleApplication &#123;
mat_tl.setColor&#40;&quot;Color&quot;, new ColorRGBA&#40;1f,0f,1f, 1f&#41;&#41;; // purple mat_tl.setColor&#40;&quot;Color&quot;, new ColorRGBA&#40;1f,0f,1f, 1f&#41;&#41;; // purple
cube_leak.setMaterial&#40;mat_tl&#41;; cube_leak.setMaterial&#40;mat_tl&#41;;
rootNode.attachChild&#40;cube_leak&#41;; rootNode.attachChild&#40;cube_leak&#41;;
&nbsp;
/** A bumpy rock with a shiny light effect */ /** A bumpy rock with a shiny light effect */
Sphere rock = new Sphere&#40;32,32, 2f&#41;; Sphere rock = new Sphere&#40;32,32, 2f&#41;;
Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;; Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;;
@ -100,71 +80,36 @@ public class HelloMaterial extends SimpleApplication &#123;
sun.setDirection&#40;new Vector3f&#40;1,0,-2&#41;.normalizeLocal&#40;&#41;&#41;; sun.setDirection&#40;new Vector3f&#40;1,0,-2&#41;.normalizeLocal&#40;&#41;&#41;;
sun.setColor&#40;ColorRGBA.White&#41;; sun.setColor&#40;ColorRGBA.White&#41;;
rootNode.addLight&#40;sun&#41;; rootNode.addLight&#40;sun&#41;;
&nbsp;
&#125; &#125;
&#125;</pre> &#125;</pre><p> You should see</p><ul><li
<p> class="level1"><div
You should see class="li"> Left – A cube with a brown monkey texture.</div></li><li
</p> class="level1"><div
<ul> class="li"> Middle – A translucent monkey picture in front of a shiny rock.</div></li><li
<li><div> Left – A cube with a brown monkey texture.</div> class="level1"><div
</li> class="li"> Right – A cube with a purple monkey texture.</div></li></ul><p> Move around with the WASD keys to have a closer look at the translucency, and the rock&#039;s bumpiness.</p></div><h2><a
<li><div> Middle – A translucent monkey picture in front of a shiny rock.</div> name="simple_unshaded_texture">Simple Unshaded Texture</a></h2><div
</li> class="level2"><p> Typically you want to give objects in your scene textures: It can be rock, grass, brick, wood, water, metal, paper… A texture is a normal image file in <acronym
<li><div> Right – A cube with a purple monkey texture. </div> title="Joint Photographics Experts Group">JPG</acronym> or <acronym
</li> title="Portable Network Graphics">PNG</acronym> format. In this example, we create a box with a simple unshaded Monkey texture as material.</p><pre> /** A simple textured cube. */
</ul>
<p>
Move around with the WASD keys to have a closer look at the translucency, and the rock&#039;s bumpiness.
</p>
</div>
<h2><a>Simple Unshaded Texture</a></h2>
<div>
<p>
Typically you want to give objects in your scene textures: It can be rock, grass, brick, wood, water, metal, paper… A texture is a normal image file in <acronym title="Joint Photographics Experts Group">JPG</acronym> or <acronym title="Portable Network Graphics">PNG</acronym> format. In this example, we create a box with a simple unshaded Monkey texture as material.
</p>
<pre> /** A simple textured cube. */
Box&#40;new Vector3f&#40;-3f,1.1f,0f&#41;, 1f,1f,1f&#41;; Box&#40;new Vector3f&#40;-3f,1.1f,0f&#41;, 1f,1f,1f&#41;;
Geometry cube = new Geometry&#40;&quot;My Textured Box&quot;, boxshape1&#41;; Geometry cube = new Geometry&#40;&quot;My Textured Box&quot;, boxshape1&#41;;
Material mat_stl = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat_stl = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
Texture tex_ml = assetManager.loadTexture&#40;&quot;Interface/Logo/Monkey.jpg&quot;&#41;; Texture tex_ml = assetManager.loadTexture&#40;&quot;Interface/Logo/Monkey.jpg&quot;&#41;;
mat_stl.setTexture&#40;&quot;ColorMap&quot;, tex_ml&#41;; mat_stl.setTexture&#40;&quot;ColorMap&quot;, tex_ml&#41;;
cube.setMaterial&#40;mat_stl&#41;; cube.setMaterial&#40;mat_stl&#41;;
rootNode.attachChild&#40;cube&#41;;</pre> rootNode.attachChild&#40;cube&#41;;</pre><p> Here is what we did:</p><ol><li
<p> class="level1"><div
Here is what we did: class="li"> Create a Geometry from a mesh. This geometry is a cube.</div></li><li
</p> class="level1"><div
<ol> class="li"> Create a Material based on jME3&#039;s default <code>Unshaded.j3md</code> material definition.</div></li><li
<li><div> Create a Geometry from a mesh. This geometry is a cube.</div> class="level1"><div
</li> class="li"> Create a texture from the <code>Monkey.jpg</code> file and load it into the material. <br/> The ColorMap is the material layer where textures go.</div></li><li
<li><div> Create a Material based on jME3&#039;s default <code>Unshaded.j3md</code> material definition.</div> class="level1"><div
</li> class="li"> Apply the material to the cube and attach the cube to the rootnode.</div></li></ol></div><h2><a
<li><div> Create a texture from the <code>Monkey.jpg</code> file and load it into the material. <br/> name="transparent_unshaded_texture">Transparent Unshaded Texture</a></h2><div
The ColorMap is the material layer where textures go.</div> class="level2"><p> <code>Monkey.png</code> is the same texture as <code>Monkey.jpg</code>, but with an added alpha channel. The alpha channel allows you to specify which areas of the texture you want to be translucent: Black areas remain opaque, gray areas become translucent, and white areas become transparent. In combination with setting the texture blend mode to <code>BlendMode.Alpha</code>, this results in a partially translucent/transparent texture!
</li> You also need to set the render bucket of the object with the translucent texture to <code>Bucket.Transparent</code>. This ensures that the translucent object is drawn on top of objects behind it, and they show up correctly under the translucent parts. For non-translucent objects the drawing order is not so important, because the z-buffer keeps track of whether a pixel is behind something else or not, and the color of a pixel doesn&#039;t depend on the pixels under it, so they can be drawn in any order.</p><pre> /** A translucent/transparent texture. */
<li><div> Apply the material to the cube and attach the cube to the rootnode.</div>
</li>
</ol>
</div>
<h2><a>Transparent Unshaded Texture</a></h2>
<div>
<p>
<code>Monkey.png</code> is the same texture as <code>Monkey.jpg</code>, but with an added alpha channel. The alpha channel allows you to specify which areas of the texture you want to be translucent: Black areas remain opaque, gray areas become translucent, and white areas become transparent. In combination with setting the texture blend mode to <code>BlendMode.Alpha</code>, this results in a partially translucent/transparent texture!
</p>
<p>
You also need to set the render bucket of the object with the translucent texture to <code>Bucket.Transparent</code>. This ensures that the translucent object is drawn on top of objects behind it, and they show up correctly under the translucent parts. For non-translucent objects the drawing order is not so important, because the z-buffer keeps track of whether a pixel is behind something else or not, and the color of a pixel doesn&#039;t depend on the pixels under it, so they can be drawn in any order.
</p>
<pre> /** A translucent/transparent texture. */
Box&#40;new Vector3f&#40;0f,0f,0f&#41;, 1f,1f,0.01f&#41;; Box&#40;new Vector3f&#40;0f,0f,0f&#41;, 1f,1f,0.01f&#41;;
Geometry seethrough = new Geometry&#40;&quot;see-through box&quot;, boxshape3&#41;; Geometry seethrough = new Geometry&#40;&quot;see-through box&quot;, boxshape3&#41;;
Material mat_tt = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat_tt = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
@ -173,254 +118,149 @@ You also need to set the render bucket of the object with the translucent textur
mat_tt.getAdditionalRenderState&#40;&#41;.setBlendMode&#40;BlendMode.Alpha&#41;; // activate transparency mat_tt.getAdditionalRenderState&#40;&#41;.setBlendMode&#40;BlendMode.Alpha&#41;; // activate transparency
seethrough.setMaterial&#40;mat_tt&#41;; seethrough.setMaterial&#40;mat_tt&#41;;
seethrough.setQueueBucket&#40;Bucket.Transparent&#41;; seethrough.setQueueBucket&#40;Bucket.Transparent&#41;;
rootNode.attachChild&#40;seethrough&#41;;</pre> rootNode.attachChild&#40;seethrough&#41;;</pre><p> What we did it the same as before, with only one added step for the transparency.</p><ol><li
<p> class="level1"><div
What we did it the same as before, with only one added step for the transparency. class="li"> Create a Geometry from a mesh. This Geometry is flat upright box.</div></li><li
</p> class="level1"><div
<ol> class="li"> Create a Material based on jME3&#039;s default <code>Unshaded.j3md</code> material definition.</div></li><li
<li><div> Create a Geometry from a mesh. This Geometry is flat upright box.</div> class="level1"><div
</li> class="li"> Create a texture from the <code>Monkey.png</code> file and load it into the material. <br/> The ColorMap is the material layer where textures go. The <acronym
<li><div> Create a Material based on jME3&#039;s default <code>Unshaded.j3md</code> material definition.</div> title="Portable Network Graphics">PNG</acronym> file must have an alpha layer.</div></li><li
</li> class="level1"><div
<li><div> Create a texture from the <code>Monkey.png</code> file and load it into the material. <br/> class="li"> Activate transparency in the material by setting the blend mode to Alpha!</div></li><li
The ColorMap is the material layer where textures go. The <acronym title="Portable Network Graphics">PNG</acronym> file must have an alpha layer.</div> class="level1"><div
</li> class="li"> Apply the material to the cube.</div></li><li
<li><div> Activate transparency in the material by setting the blend mode to Alpha! </div> class="level1"><div
</li> class="li"> Set the QueueBucket of the cube to <code>Bucket.Transparent</code> to ensure that the translucent objects is drawn after objects behind it.</div></li><li
<li><div> Apply the material to the cube.</div> class="level1"><div
</li> class="li"> Attach the cube to the rootnode.</div></li></ol><p> <strong>Tip:</strong> Learn more about creating <acronym
<li><div> Set the QueueBucket of the cube to <code>Bucket.Transparent</code> to ensure that the translucent objects is drawn after objects behind it.</div> title="Portable Network Graphics">PNG</acronym> images with an alpha layer in the help system of your graphic editor.</p></div><h2><a
</li> name="shininess_and_bumpiness">Shininess and Bumpiness</a></h2><div
<li><div> Attach the cube to the rootnode.</div> class="level2"><p> But textures are not all. Have a look at the shiny bumpy sphere again – you cannot get such a nice material with just a texture. We will have a quick look at some advanced jme features here – lit materials:
</li>
</ol>
<p>
<strong>Tip:</strong> Learn more about creating <acronym title="Portable Network Graphics">PNG</acronym> images with an alpha layer in the help system of your graphic editor.
</p>
</div>
<h2><a>Shininess and Bumpiness</a></h2>
<div>
<p>
But textures are not all. Have a look at the shiny bumpy sphere again – you cannot get such a nice material with just a texture. We will have a quick look at some advanced jme features here – lit materials:
</p>
<p>
In a lit material, the standard texture layer is refered to as <em>Diffuse Map</em>, any material can have it. A lit material can additionally have lighting effects such as <em>Shininess</em> used together with the <em>Specular Map</em> layer, and even a realistically bumpy or cracked surface with help of the <em>Normal Map</em> layer. In a lit material, the standard texture layer is refered to as <em>Diffuse Map</em>, any material can have it. A lit material can additionally have lighting effects such as <em>Shininess</em> used together with the <em>Specular Map</em> layer, and even a realistically bumpy or cracked surface with help of the <em>Normal Map</em> layer.
</p> Let&#039;s have a look at the part of the code example where you create the shiny bumpy rock.</p><ol><li
class="level1"><div
<p> class="li"> Create a Geometry from a mesh. This Geometrx is a normal smooth sphere.<pre> Sphere rock = new Sphere&#40;32,32, 2f&#41;;
Let&#039;s have a look at the part of the code example where you create the shiny bumpy rock. Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;;</pre></div><ol><li
</p> class="level2"><div
<ol> class="li"> (Only for Spheres) Change the sphere&#039;s TextureMode to make the square texture project better onto the sphere.<pre> rock.setTextureMode&#40;Sphere.TextureMode.Projected&#41;; </pre></div></li><li
<li><div> Create a Geometry from a mesh. This Geometrx is a normal smooth sphere. <pre> Sphere rock = new Sphere&#40;32,32, 2f&#41;; class="level2"><div
Geometry shiny_rock = new Geometry&#40;&quot;Shiny rock&quot;, rock&#41;;</pre></div> class="li"> You generate TangentBinormals to enable rendering the bumpiness (stored in the NormalMap) of the texture.<pre> TangentBinormalGenerator.generate&#40;rock&#41;;</pre></div></li></ol></li><li
<ol> class="level1"><div
<li><div> (Only for Spheres) Change the sphere&#039;s TextureMode to make the square texture project better onto the sphere.<pre> rock.setTextureMode&#40;Sphere.TextureMode.Projected&#41;; </pre></div> class="li"> Create a material based on the <code>Lighting.j3md</code> default material.<pre> Material mat_lit = new Material&#40;assetManager,
</li> &quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;;</pre></div><ol><li
<li><div> You generate TangentBinormals to enable rendering the bumpiness (stored in the NormalMap) of the texture.<pre> TangentBinormalGenerator.generate&#40;rock&#41;;</pre></div> class="level2"><div
</li> class="li"> Set a standard rocky texture in the <code>DiffuseMap</code> layer. <br/> <a
</ol> href="/wiki/lib/exe/fetch.php?hash=4ed1d3&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FPond%2FPond.png"><img
</li> src="/wiki/lib/exe/fetch.php?hash=4ed1d3&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FPond%2FPond.png" class="mediaright" align="right" alt="" width="64" height="64" /></a><pre> mat_lit.setTexture&#40;&quot;DiffuseMap&quot;,
<li><div> Create a material based on the <code>Lighting.j3md</code> default material.<pre> Material mat_lit = new Material&#40;assetManager, assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond.png&quot;&#41;&#41;;</pre></div></li><li
&quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;;</pre></div> class="level2"><div
<ol> class="li"> Set the <code>NormalMap</code> layer that contains the bumpiness. The NormalMap was generated for this particular DiffuseMap with a special tool (e.g. Blender). <a
<li><div> Set a standard rocky texture in the <code>DiffuseMap</code> layer. <br/> href="/wiki/lib/exe/fetch.php?hash=b26e64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FPond%2FPond_normal.png"><img
<img src="/wiki/lib/exe/fetch.php"><pre> mat_lit.setTexture&#40;&quot;DiffuseMap&quot;, src="/wiki/lib/exe/fetch.php?hash=b26e64&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FPond%2FPond_normal.png" class="mediaright" align="right" alt="" width="64" height="64" /></a><pre> mat_lit.setTexture&#40;&quot;NormalMap&quot;,
assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond.png&quot;&#41;&#41;;</pre></div> assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond_normal.png&quot;&#41;&#41;;</pre></div></li><li
</li> class="level2"><div
<li><div> Set the <code>NormalMap</code> layer that contains the bumpiness. The NormalMap was generated for this particular DiffuseMap with a special tool (e.g. Blender). <img src="/wiki/lib/exe/fetch.php"> <pre> mat_lit.setTexture&#40;&quot;NormalMap&quot;, class="li"> Set the material&#039;s Shininess to a value between 0 and 127.<pre> mat_lit.setFloat&#40;&quot;Shininess&quot;, 5f&#41;; // [0,128]</pre></div></li></ol></li><li
assetManager.loadTexture&#40;&quot;Textures/Terrain/Pond/Pond_normal.png&quot;&#41;&#41;;</pre></div> class="level1"><div
</li> class="li"> Assign your newly created material to the rock.<pre> shiny_rock.setMaterial&#40;mat_lit&#41;;</pre></div></li><li
<li><div> Set the material&#039;s Shininess to a value between 0 and 127.<pre> mat_lit.setFloat&#40;&quot;Shininess&quot;, 5f&#41;; // [0,128]</pre></div> class="level1"><div
</li> class="li"> Let&#039;s move and rotate the geometry a bit to position it better.<pre> shiny_rock.setLocalTranslation&#40;0,2,-2&#41;; // Move it a bit
</ol>
</li>
<li><div> Assign your newly created material to the rock.<pre> shiny_rock.setMaterial&#40;mat_lit&#41;;</pre></div>
</li>
<li><div> Let&#039;s move and rotate the geometry a bit to position it better. <pre> shiny_rock.setLocalTranslation&#40;0,2,-2&#41;; // Move it a bit
shiny_rock.rotate&#40;1.6f, 0, 0&#41;; // Rotate it a bit shiny_rock.rotate&#40;1.6f, 0, 0&#41;; // Rotate it a bit
rootNode.attachChild&#40;shiny_rock&#41;;</pre></div> rootNode.attachChild&#40;shiny_rock&#41;;</pre></div></li><li
</li> class="level1"><div
<li><div> Note that any lighting material requires a light source.</div> class="li"> Note that any lighting material requires a light source.</div></li></ol></div><h2><a
</li> name="default_material_definitions">Default Material Definitions</a></h2><div
</ol> class="level2"><p> As you have seen, the following default materials can always be found in <code>jme/core-data/Common</code>.</p><div
class="table sectionedit1"><table
</div> class="inline"><tr
class="row0"><th
<h2><a>Default Material Definitions</a></h2> class="col0 leftalign"> Default Definition</th><th
<div> class="col1"> Usage</th><th
class="col2 leftalign"> Parameters</th></tr><tr
<p> class="row1"><td
class="col0"> <code>Common/MatDefs/Misc/Unshaded.j3md</code></td><td
As you have seen, the following default materials can always be found in <code>jme/core-data/Common</code>. class="col1"> Textured: Use with mat.setTexture() and TextureKey. <br/> Colored: Use with mat.setColor() and RGBAColor.</td><td
class="col2"> ColorMap : Texture.</td></tr><tr
</p> class="row2"><td
<table> class="col0 leftalign"> <code>Common/MatDefs/Light/Lighting.j3md</code></td><td
<tr> class="col1"> Use with shiny Textures, Bump- and NormalMaps textures. <br/> Requires a light source.</td><td
<th> Default Definition </th><th> Usage </th><th> Parameters </th> class="col2"> Ambient, Diffuse, Specular : Color <br/> DiffuseMap, NormalMap, SpecularMap : Texture <br/> Shininess : Float</td></tr></table></div><p> In a real game, you will create your custom Materials based these existing ones – as you have just seen in the example with the shiny rock.</p></div><h2><a
</tr> name="exercises">Exercises</a></h2><div
<tr> class="level2"></div><h3><a
<td> <code>Common/MatDefs/Misc/Unshaded.j3md</code> </td><td> Textured: Use with mat.setTexture() and TextureKey. <br/> name="exercise_1custom_materials">Exercise 1: Custom Materials</a></h3><div
Colored: Use with mat.setColor() and RGBAColor. </td><td> ColorMap : Texture. </td> class="level3"><p> Look at the purple leak-through sample above again. It takes four lines to create and set the Material.</p><ul><li
</tr> class="level1"><div
<tr> class="li"> Note how it loads the <code>Unshaded.j3md</code> Material definition.</div></li><li
<td> <code>Common/MatDefs/Light/Lighting.j3md</code> </td><td> Use with shiny Textures, Bump- and NormalMaps textures. <br/> class="level1"><div
Requires a light source. </td><td> Ambient, Diffuse, Specular : Color <br/> class="li"> Note how it sets to <code>Color</code> parameter to purple (<code>new ColorRGBA(1f,0f,1f,1f)</code>).</div></li><li
DiffuseMap, NormalMap, SpecularMap : Texture <br/> class="level1"><div
Shininess : Float </td> class="li"> Note how it sets the <code>ColorMap</code> to a texture path.</div></li></ul><p> If you want to use one custom material for several models, you can store it in a .j3m file, and save a few lines of code every time. Here is an example:
</tr> Create a file <code>assets/Materials/LeakThrough.j3m</code> with the following content:</p><pre>Material Leak Through : Common/MatDefs/Misc/Unshaded.j3md {
</table>
<p>
In a real game, you will create your custom Materials based these existing ones – as you have just seen in the example with the shiny rock.
</p>
</div>
<h2><a>Exercises</a></h2>
<div>
</div>
<h3><a>Exercise 1: Custom Materials</a></h3>
<div>
<p>
Look at the purple leak-through sample above again. It takes four lines to create and set the Material.
</p>
<ul>
<li><div> Note how it loads the <code>Unshaded.j3md</code> Material definition.</div>
</li>
<li><div> Note how it sets to <code>Color</code> parameter to purple (<code>new ColorRGBA(1f,0f,1f,1f)</code>).</div>
</li>
<li><div> Note how it sets the <code>ColorMap</code> to a texture path.</div>
</li>
</ul>
<p>
If you want to use one custom material for several models, you can store it in a .j3m file, and save a few lines of code every time. Here is an example:
</p>
<p>
Create a file <code>assets/Materials/LeakThrough.j3m</code> with the following content:
</p>
<pre>Material Leak Through : Common/MatDefs/Misc/Unshaded.j3md {
MaterialParameters { MaterialParameters {
Color : 1 0 1 1 Color : 1 0 1 1
ColorMap : Textures/ColoredTex/Monkey.png ColorMap : Textures/ColoredTex/Monkey.png
} }
}</pre> }</pre><ul><li
<ul> class="level1"><div
<li><div> Note that <code>Material</code> is a keyword.</div> class="li"> Note that <code>Material</code> is a keyword.</div></li><li
</li> class="level1"><div
<li><div> Note that <code>Leak Through</code> is a name that you can choose.</div> class="li"> Note that <code>Leak Through</code> is a name that you can choose.</div></li><li
</li> class="level1"><div
<li><div> Note how it sets the same three properties, Color, ColorMap, and Unshaded.j3md.</div> class="li"> Note how it sets the same three properties, Color, ColorMap, and Unshaded.j3md.</div></li></ul><p> Using this new custom material <code>LeakThrough.j3m</code> only takes one line.</p><ol><li
</li> class="level1"><div
</ul> class="li"> In the code sample, comment out the three lines with <code>mat_tl</code> in them.</div></li><li
class="level1"><div
<p> class="li"> Below them, add the following line:<pre>cube_leak.setMaterial&#40;&#40;Material&#41; assetManager.loadAsset&#40; &quot;Materials/LeakThrough.j3m&quot;&#41;&#41;;</pre></div></li><li
Using this new custom material <code>LeakThrough.j3m</code> only takes one line. class="level1"><div
</p> class="li"> Run the app. The result is the same.</div></li></ol><p> You have replaced the three lines of an on-the-fly material definition with one line that loads a custom material from a file. This method is very handy if you use the same material often.</p></div><h3><a
<ol> name="exercise_2bumpiness_and_shininess">Exercise 2: Bumpiness and Shininess</a></h3><div
<li><div> In the code sample, comment out the three lines with <code>mat_tl</code> in them.</div> class="level3"><p> Go back to the bumpy rock sample above:</p><ol><li
</li> class="level1"><div
<li><div> Below them, add the following line: <pre>cube_leak.setMaterial&#40;&#40;Material&#41; assetManager.loadAsset&#40; &quot;Materials/LeakThrough.j3m&quot;&#41;&#41;;</pre></div> class="li"> Comment out the DiffuseMap line, and run the app. (Uncomment it again.)</div></li><li
</li> class="level1"><div
<li><div> Run the app. The result is the same. </div> class="li"> Comment out the NormalMap line, and run the app. (Uncomment it again.)</div><ul><li
</li> class="level2"><div
</ol> class="li"> Compare: Which property of the rock is lost in either case?</div></li></ul></li><li
class="level1"><div
<p> class="li"> Change the value of Shininess to values like 0, 63, 127.</div><ul><li
class="level2"><div
You have replaced the three lines of an on-the-fly material definition with one line that loads a custom material from a file. This method is very handy if you use the same material often. class="li"> What aspect of the Shininess changes?</div></li></ul></li></ol></div><h2><a
</p> name="conclusion">Conclusion</a></h2><div
class="level2"><p> You have learned how to create a Material, specify its properties, and use it on a Geometry. You know how to load an image file (.png, .jpg) as texture into a material. You know to save texture files in a subfolder of your project&#039;s <code>assets/Textures/</code> directory.
</div>
<h3><a>Exercise 2: Bumpiness and Shininess</a></h3>
<div>
<p>
Go back to the bumpy rock sample above:
</p>
<ol>
<li><div> Comment out the DiffuseMap line, and run the app. (Uncomment it again.)</div>
</li>
<li><div> Comment out the NormalMap line, and run the app. (Uncomment it again.)</div>
<ul>
<li><div> Compare: Which property of the rock is lost in either case?</div>
</li>
</ul>
</li>
<li><div> Change the value of Shininess to values like 0, 63, 127. </div>
<ul>
<li><div> What aspect of the Shininess changes?</div>
</li>
</ul>
</li>
</ol>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned how to create a Material, specify its properties, and use it on a Geometry. You know how to load an image file (.png, .jpg) as texture into a material. You know to save texture files in a subfolder of your project&#039;s <code>assets/Textures/</code> directory.
</p>
<p>
You have also learned that a material can be stored in a .j3m file. The file references a built-in Material Definition and specifies values for properties of that MaterialDefinition. You know to save your custom .j3m files in your project&#039;s <code>assets/Materials/</code> directory. You have also learned that a material can be stored in a .j3m file. The file references a built-in Material Definition and specifies values for properties of that MaterialDefinition. You know to save your custom .j3m files in your project&#039;s <code>assets/Materials/</code> directory.
</p> Now that you know how to load models and how to assign good-looking materials to them, let&#039;s have a look at how to animate models in the next chapter, <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a>.</p><hr
<p> /><p> See also</p><ul><li
Now that you know how to load models and how to assign good-looking materials to them, let&#039;s have a look at how to animate models in the next chapter, <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a>. class="level1"><div
class="li"> <a
</p> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></div></li><li
<hr /> class="level1"><div
class="li"> <a
<p> href="/com/jme3/gde/core/docs/sdk/material_editing.html">Material Editing</a></div></li><li
See also class="level1"><div
</p> class="li"> <a
<ul> href="http://www.jmonkeyengine.com/forum/index.php?topic=14179.0">Materials</a> forum thread</div></li><li
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/jme3/jmonkeyplatform/material_editing.html">Material Editing</a></div> href="http://jmonkeyengine.googlecode.com/files/jME3_materials.pdf">jME3 Materials documentation</a> (<acronym
</li> title="Portable Document Format">PDF</acronym>)</div></li><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/forum/index.php?topic=14179.0"><param name="text" value="<html><u>Materials</u></html>"><param name="textColor" value="blue"></object> forum thread</div> class="level1"><div
</li> class="li"> <a
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/files/jME3_materials.pdf"><param name="text" value="<html><u>jME3 Materials documentation</u></html>"><param name="textColor" value="blue"></object> (<acronym title="Portable Document Format">PDF</acronym>)</div> href="http://www.youtube.com/watch?v=Feu3-mrpolc">Video Tutorial: Editing and Assigning Materials to Models in jMonkeyPlatform</a></div></li><li
</li> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.youtube.com/watch?v=Feu3-mrpolc"><param name="text" value="<html><u>Video Tutorial: Editing and Assigning Materials to Models in jMonkeyPlatform</u></html>"><param name="textColor" value="blue"></object></div> class="li"> <a
</li> href="http://www.blender.org/education-help/tutorials/materials/">Creating textures in Blender</a></div></li><li
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.blender.org/education-help/tutorials/materials/"><param name="text" value="<html><u>Creating textures in Blender</u></html>"><param name="textColor" value="blue"></object></div> class="level1"><div
</li> class="li"> <a
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.shaders.org/ifw2_textures/whatsin10.htm"><param name="text" value="<html><u>Various Material screenshots</u></html>"><param name="textColor" value="blue"></object> (Not done with JME3, this is just to show the fantastic range of Material parameters in the hands of an expert, until we have a JME3 demo for it.)</div> href="http://www.shaders.org/ifw2_textures/whatsin10.htm">Various Material screenshots</a> (Not done with JME3, this is just to show the fantastic range of Material parameters in the hands of an expert, until we have a JME3 demo for it.)</div></li></ul><div
</li> class="tags"><span> <a
</ul> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<div><span> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>, <a
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, href="/wiki/doku.php/tag:material?do=showtag&amp;tag=tag%3Amaterial">material</a>, <a
<a href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>, href="/wiki/doku.php/tag:color?do=showtag&amp;tag=tag%3Acolor">color</a>, <a
<a href="/wiki/doku.php/tag:material?do=showtag&amp;tag=tag%3Amaterial">material</a>, href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a>, <a
<a href="/wiki/doku.php/tag:color?do=showtag&amp;tag=tag%3Acolor">color</a>, href="/wiki/doku.php/tag:transparency?do=showtag&amp;tag=tag%3Atransparency">transparency</a> </span></div></div>
<a href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a>,
<a href="/wiki/doku.php/tag:transparency?do=showtag&amp;tag=tag%3Atransparency">transparency</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_material?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_material?do=export_xhtmlbody">view online version</a></em></p>

@ -1,27 +1,12 @@
<h1><a
<h1><a>JME 3 Tutorial (2) - Hello Node</a></h1> name="jme_3_tutorial_2_-_hello_node">JME 3 Tutorial (2) - Hello Node</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html">Hello SimpleApplication</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Assets</a>. <br/> <br/> When creating a 3D game, you start out with creating a scene and some objects. You place the objects (player tokens, obstacles, etc) in the scene, and move, resize, rotate, color, and animate them. <br/> <br/> In this tutorial we will have a look at a simple 3D scene. You will learn that the 3D world is represented in a scene graph, and why the rootNode is important. You will learn how to create simple objects and how to transform them – move, scale, rotate. You will understand the difference between the two types of Spatials in the scene graph, Node and Geometry. For a visual introduction to the scene graph check out our <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html">Hello SimpleApplication</a>, href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html"> Scene Graph for Dummies</a> presentation.</p></div><h2><a
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Assets</a>. name="code_sample">Code Sample</a></h2><div
</p> class="level2"><pre>package jme3test.helloworld;
<p>
When creating a 3D game, you start out with creating a scene and some objects. You place the objects (player tokens, obstacles, etc) in the scene, and move, resize, rotate, color, and animate them.
</p>
<p>
In this tutorial we will have a look at a simple 3D scene. You will learn that the 3D world is represented in a scene graph, and why the rootNode is important. You will learn how to create simple objects and how to transform them – move, scale, rotate. You will understand the difference between the two types of Spatials in the scene graph, Node and Geometry. For a visual introduction to the scene graph check out our <a href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html"> Scene Graph for Dummies</a> presentation.
</p>
</div>
<h2><a>Code Sample</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
@ -29,297 +14,203 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.scene.Node; import com.jme3.scene.Node;
&nbsp;
<span>/** Sample 2 - How to use nodes as handles to manipulate objects in the scene graph. <span>/** Sample 2 - How to use nodes as handles to manipulate objects in the scene graph.
* You can rotate, translate, and scale objects by manipulating their parent nodes. * You can rotate, translate, and scale objects by manipulating their parent nodes.
* The Root Node is special: Only what is attached to the Root Node appears in the scene. */</span> * The Root Node is special: Only what is attached to the Root Node appears in the scene. */</span>
public class HelloNode extends SimpleApplication &#123; public class HelloNode extends SimpleApplication &#123;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41;&#123; public static void main&#40;String&#91;&#93; args&#41;&#123;
HelloNode app = new HelloNode&#40;&#41;; HelloNode app = new HelloNode&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
&nbsp;
// create a blue box at coordinates (1,-1,1) // create a blue box at coordinates (1,-1,1)
Box&#40; new Vector3f&#40;1,-1,1&#41;, 1,1,1&#41;; Box&#40; new Vector3f&#40;1,-1,1&#41;, 1,1,1&#41;;
Geometry blue = new Geometry&#40;&quot;Box&quot;, box1&#41;; Geometry blue = new Geometry&#40;&quot;Box&quot;, box1&#41;;
Material mat1 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat1 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;
blue.setMaterial&#40;mat1&#41;; blue.setMaterial&#40;mat1&#41;;
&nbsp;
// create a red box straight above the blue one at (1,3,1) // create a red box straight above the blue one at (1,3,1)
Box&#40; new Vector3f&#40;1,3,1&#41;, 1,1,1&#41;; Box&#40; new Vector3f&#40;1,3,1&#41;, 1,1,1&#41;;
Geometry red = new Geometry&#40;&quot;Box&quot;, box2&#41;; Geometry red = new Geometry&#40;&quot;Box&quot;, box2&#41;;
Material mat2 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat2 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat2.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;; mat2.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;;
red.setMaterial&#40;mat2&#41;; red.setMaterial&#40;mat2&#41;;
&nbsp;
// create a pivot node at (0,0,0) and attach it to root // create a pivot node at (0,0,0) and attach it to root
Node pivot = new Node&#40;&quot;pivot&quot;&#41;; Node pivot = new Node&#40;&quot;pivot&quot;&#41;;
rootNode.attachChild&#40;pivot&#41;; rootNode.attachChild&#40;pivot&#41;;
&nbsp;
// attach the two boxes to the *pivot* node! // attach the two boxes to the *pivot* node!
pivot.attachChild&#40;blue&#41;; pivot.attachChild&#40;blue&#41;;
pivot.attachChild&#40;red&#41;; pivot.attachChild&#40;red&#41;;
// rotate pivot node: Both boxes have rotated! // rotate pivot node: Both boxes have rotated!
pivot.rotate&#40; 0.4f , 0.4f , 0.0f &#41;; pivot.rotate&#40; 0.4f , 0.4f , 0.0f &#41;;
&nbsp;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Build and run the code sample. You should see two colored boxes tilted at the same angle.</p></div><h2><a
<p> name="understanding_the_terminology">Understanding the Terminology</a></h2><div
Build and run the code sample. You should see two colored boxes tilted at the same angle. class="level2"><p> In this tutorial, you will learn some new terms:</p><ol><li
</p> class="level1"><div
class="li"> The <em>scene graph</em> represents your 3D world.</div></li><li
</div> class="level1"><div
class="li"> Objects in the scene graph (such as the boxes in this example) are called <em>Spatials</em>.</div><ul><li
<h2><a>Understanding the Terminology</a></h2> class="level2"><div
<div> class="li"> A Spatial is a collection of information about an object: its location, rotation, and scale.</div></li><li
class="level2"><div
<p> class="li"> A Spatial can be loaded, transformed, and saved.</div></li></ul></li><li
class="level1"><div
In this tutorial, you will learn some new terms: class="li"> There are two types of Spatials, <em>Nodes</em> and <em>Geometries</em>.</div></li><li
class="level1"><div
</p> class="li"> To add a Spatial to the scene graph, you attach the Spatial to the <em>rootNode</em>.</div></li><li
<ol> class="level1"><div
<li><div> The <em>scene graph</em> represents your 3D world.</div> class="li"> Everything attached to the <em>rootNode</em> is part of the scene graph.</div></li></ol></div><h2><a
</li> name="understanding_the_code">Understanding the Code</a></h2><div
<li><div> Objects in the scene graph (such as the boxes in this example) are called <em>Spatials</em>.</div> class="level2"><p> So what exactly happens in this code snippet? Note that we are using the <code>simpleInitApp()</code> method that was introduced in the first tutorial.</p><ol><li
<ul> class="level1"><div
<li><div> A Spatial is a collection of information about an object: its location, rotation, and scale.</div> class="li"> We create a box Geometry.</div><ul><li
</li> class="level2"><div
<li><div> A Spatial can be loaded, transformed, and saved.</div> class="li"> The box Geometry&#039;s extends are (1,1,1), that makes it 2x2x2 world units big.</div></li><li
</li> class="level2"><div
</ul> class="li"> We place the box at (1,-1,1)</div></li><li
</li> class="level2"><div
<li><div> There are two types of Spatials, <em>Nodes</em> and <em>Geometries</em>.</div> class="li"> We give it a solid blue material.<pre> Box&#40; new Vector3f&#40;1,-1,1&#41;, 1,1,1&#41;;
</li>
<li><div> To add a Spatial to the scene graph, you attach the Spatial to the <em>rootNode</em>. </div>
</li>
<li><div> Everything attached to the <em>rootNode</em> is part of the scene graph.</div>
</li>
</ol>
</div>
<h2><a>Understanding the Code</a></h2>
<div>
<p>
So what exactly happens in this code snippet? Note that we are using the <code>simpleInitApp()</code> method that was introduced in the first tutorial.
</p>
<ol>
<li><div> We create a box Geometry. </div>
<ul>
<li><div> The box Geometry&#039;s extends are (1,1,1), that makes it 2x2x2 world units big. </div>
</li>
<li><div> We place the box at (1,-1,1)</div>
</li>
<li><div> We give it a solid blue material. <pre> Box&#40; new Vector3f&#40;1,-1,1&#41;, 1,1,1&#41;;
Geometry blue = new Geometry&#40;&quot;Box&quot;, box1&#41;; Geometry blue = new Geometry&#40;&quot;Box&quot;, box1&#41;;
Material mat1 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat1 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; mat1.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;;
blue.setMaterial&#40;mat1&#41;;</pre></div> blue.setMaterial&#40;mat1&#41;;</pre></div></li></ul></li><li
</li> class="level1"><div
</ul> class="li"> We create a second box Geometry.</div><ul><li
</li> class="level2"><div
<li><div> We create a second box Geometry. </div> class="li"> This box Geometry is also 2x2x2 world units big.</div></li><li
<ul> class="level2"><div
<li><div> This box Geometry is also 2x2x2 world units big. </div> class="li"> We place the second box at (1,3,1). This is straight above the blue box, with a gap of 2 world units inbetween.</div></li><li
</li> class="level2"><div
<li><div> We place the second box at (1,3,1). This is straight above the blue box, with a gap of 2 world units inbetween.</div> class="li"> We give it a solid red material<pre> Box&#40; new Vector3f&#40;1,3,1&#41;, 1,1,1&#41;;
</li>
<li><div> We give it a solid red material<pre> Box&#40; new Vector3f&#40;1,3,1&#41;, 1,1,1&#41;;
Geometry red = new Geometry&#40;&quot;Box&quot;, box2&#41;; Geometry red = new Geometry&#40;&quot;Box&quot;, box2&#41;;
Material mat2 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;; Material mat2 = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/Unshaded.j3md&quot;&#41;;
mat2.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;; mat2.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;;
red.setMaterial&#40;mat2&#41;;</pre></div> red.setMaterial&#40;mat2&#41;;</pre></div></li></ul></li><li
</li> class="level1"><div
</ul> class="li"> We create a Node.</div><ul><li
</li> class="level2"><div
<li><div> We create a Node. </div> class="li"> By default the Node is placed at (0,0,0).</div></li><li
<ul> class="level2"><div
<li><div> By default the Node is placed at (0,0,0). </div> class="li"> We attach the Node to the rootNode.</div></li><li
</li> class="level2"><div
<li><div> We attach the Node to the rootNode.</div> class="li"> An attached Node has no visible appearance in the scene.<pre> Node pivot = new Node&#40;&quot;pivot&quot;&#41;;
</li> rootNode.attachChild&#40;pivot&#41;;</pre></div></li></ul></li><li
<li><div> An attached Node has no visible appearance in the scene. <pre> Node pivot = new Node&#40;&quot;pivot&quot;&#41;; class="level1"><div
rootNode.attachChild&#40;pivot&#41;;</pre></div> class="li"> Note that we have not attached the two boxes to anything yet!</div><ul><li
</li> class="level2"><div
</ul> class="li"> <em>If we ran the application now, the scenegraph would appear empty.</em></div></li></ul></li><li
</li> class="level1"><div
<li><div> Note that we have not attached the two boxes to anything yet! </div> class="li"> We attach the two boxes to the node.</div><ul><li
<ul> class="level2"><div
<li><div> <em>If we ran the application now, the scenegraph would appear empty.</em></div> class="li"> <em>If we ran the app now, we would see two boxes: one straight above the other.</em><pre> pivot.attachChild&#40;blue&#41;;
</li> pivot.attachChild&#40;red&#41;; </pre></div></li></ul></li><li
</ul> class="level1"><div
</li> class="li"> Now, we rotate the node.</div><ul><li
<li><div> We attach the two boxes to the node.</div> class="level2"><div
<ul> class="li"> <em>When we run the application now, we see two boxes on top of each other – but both are tilted at the same angle.</em><pre> pivot.rotate&#40; 0.4f , 0.4f , 0.0f &#41;;</pre></div></li></ul></li></ol><p> What has happened? We have attached two box Geometries to a Node. Then we used the Node as a handle to grab the two boxes and transform (rotate) both, in one step. This is a common task and you will use this method a lot in your games when you move game characters around.</p></div><h3><a
<li><div> <em>If we ran the app now, we would see two boxes: one straight above the other.</em> <pre> pivot.attachChild&#40;blue&#41;; name="definitiongeometry_vs_node">Definition: Geometry vs Node</a></h3><div
pivot.attachChild&#40;red&#41;; </pre></div> class="level3"><p> You work with two types of Spatials in your scenegraph: Nodes and Geometries. Here is the difference:</p><div
</li> class="table sectionedit1"><table
</ul> class="inline"><tr
</li> class="row0"><td
<li><div> Now, we rotate the node.</div> class="col0 leftalign"></td><th
<ul> class="col1"> Geometry</th><th
<li><div> <em>When we run the application now, we see two boxes on top of each other – but both are tilted at the same angle.</em> <pre> pivot.rotate&#40; 0.4f , 0.4f , 0.0f &#41;;</pre></div> class="col2"> Node</th></tr><tr
</li> class="row1"><th
</ul> class="col0"> Visibility:</th><td
</li> class="col1"> A visible 3-D object.</td><td
</ol> class="col2"> An invisible &quot;handle&quot;.</td></tr><tr
class="row2"><th
<p> class="col0"> Purpose:</th><td
class="col1"> A Geometry stores an object&#039;s looks.</td><td
What has happened? We have attached two box Geometries to a Node. Then we used the Node as a handle to grab the two boxes and transform (rotate) both, in one step. This is a common task and you will use this method a lot in your games when you move game characters around. class="col2"> A Node groups Geometries and other Nodes together.</td></tr><tr
</p> class="row3"><th
class="col0"> Examples:</th><td
</div> class="col1"> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc…</td><td
class="col2"> The default <code>rootNode</code>, the <code>guiNode</code> (for on-screen text); a floor node, a custom vehicle-with-passengers node, an audio node, etc…</td></tr></table></div></div><h2><a
<h3><a>Definition: Geometry vs Node</a></h3> name="faqhow_to_populate_the_scenegraph">FAQ: How to Populate the Scenegraph?</a></h2><div
<div> class="level2"><div
class="table sectionedit2"><table
<p> class="inline"><tr
class="row0"><th
You work with two types of Spatials in your scenegraph: Nodes and Geometries. Here is the difference: class="col0"> Task?</th><th
class="col1"> Solution!</th></tr><tr
</p> class="row1"><td
<table> class="col0"> Create a Spatial</td><td
<tr> class="col1"> Create a shape and give it a Material. For instance a box shape:<pre>Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
<td> </td><th> Geometry </th><th> Node </th>
</tr>
<tr>
<th> Visibility: </th><td> A visible 3-D object. </td><td> An invisible “handle”. </td>
</tr>
<tr>
<th> Purpose: </th><td> A Geometry stores an object&#039;s looks. </td><td> A Node groups Geometries and other Nodes together. </td>
</tr>
<tr>
<th> Examples: </th><td> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc… </td><td> The default <code>rootNode</code>, the <code>guiNode</code> (for on-screen text); a floor node, a custom vehicle-with-passengers node, an audio node, etc… </td>
</tr>
</table>
</div>
<h2><a>FAQ: How to Populate the Scenegraph?</a></h2>
<div>
<table>
<tr>
<th> Task? </th><th> Solution! </th>
</tr>
<tr>
<td> Create a Spatial </td><td> Create a shape and give it a Material. For instance a box shape: <pre>Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
Geometry thing = new Geometry&#40;&quot;thing&quot;, mesh&#41;; Geometry thing = new Geometry&#40;&quot;thing&quot;, mesh&#41;;
Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;; Material mat = new Material&#40;assetManager, &quot;Common/MatDefs/Misc/ShowNormals.j3md&quot;&#41;;
thing.setMaterial&#40;mat&#41;;</pre></td> thing.setMaterial&#40;mat&#41;;</pre></td></tr><tr
</tr> class="row2"><td
<tr> class="col0"> Make an object appear in the scene</td><td
<td> Make an object appear in the scene </td><td> Attach the Spatial to the <code>rootNode</code>, or to any node that is attached to the rootNode. <pre>rootNode.attachChild&#40;thing&#41;;</pre></td> class="col1"> Attach the Spatial to the <code>rootNode</code>, or to any node that is attached to the rootNode.<pre>rootNode.attachChild&#40;thing&#41;;</pre></td></tr><tr
</tr> class="row3"><td
<tr> class="col0"> Remove objects from the scene</td><td
<td> Remove objects from the scene </td><td> Detach the Spatial from the <code>rootNode</code>, and from any node that is attached to the rootNode. <pre>rootNode.detachChild&#40;thing&#41;;</pre><pre>rootNode.detachAllChildren&#40;&#41;;</pre></td> class="col1"> Detach the Spatial from the <code>rootNode</code>, and from any node that is attached to the rootNode.<pre>rootNode.detachChild&#40;thing&#41;;</pre><pre>rootNode.detachAllChildren&#40;&#41;;</pre></td></tr><tr
</tr> class="row4"><td
<tr> class="col0"> Find a Spatial in the scene by the object&#039;s name or ID</td><td
<td> Find a Spatial in the scene by the object&#039;s name or ID </td><td> Look at the node&#039;s children. <pre>Spatial thing = rootNode.getChild&#40;&quot;thing&quot;&#41;;</pre><pre>Spatial twentythird = rootNode.getChild&#40;22&#41;;</pre></td> class="col1"> Look at the node&#039;s children.<pre>Spatial thing = rootNode.getChild&#40;&quot;thing&quot;&#41;;</pre><pre>Spatial twentyThird = rootNode.getChild&#40;22&#41;;</pre></td></tr><tr
</tr> class="row5"><td
<tr> class="col0"> Specify what should be loaded at the start</td><td
<td> Specify what should be loaded at the start </td><td> Everything you initialize and attach to the <code>rootNode</code> in the <code>simpleInitApp()</code> method is part of the scene at the start of the game. </td> class="col1"> Everything you initialize and attach to the <code>rootNode</code> in the <code>simpleInitApp()</code> method is part of the scene at the start of the game.</td></tr></table></div></div><h2><a
</tr> name="how_to_transform_objects">How to Transform Objects?</a></h2><div
</table> class="level2"><p> There are three types of 3D transformation: Translation (moving), Scaling (resizing), and Rotation (turning).</p><div
class="table sectionedit3"><table
</div> class="inline"><tr
class="row0"><th
<h2><a>How to Transform Objects?</a></h2> class="col0"> Task?</th><th
<div> class="col1"> Solution!</th><th
class="col2"> X</th><th
<p> class="col3"> Y</th><th
class="col4"> Z</th></tr><tr
There are three types of 3D transformation: Translation (moving), Scaling (resizing), and Rotation (turning). class="row1"><td
class="col0"> Position and move objects</td><td
</p> class="col1"> <strong>Translation:</strong> Specify the new location in three dimensions: right/left, up/down, forward/backward. <br/> Example 1. To move an object <em>to</em> specific coordinates, such as (0,40.2f,-2), use:<pre>thing.setLocalTranslation&#40; new Vector3f&#40; 0.0f, 40.2f, -2.0f &#41; &#41;;</pre><p> <br/> Example 2: To move an object <em>by</em> a certain amount, e.g. higher up (y=40.2f) and further back (z=-2.0f):</p><pre>thing.move&#40; 0.0f, 40.2f, -2.0f &#41;;</pre></td><td
<table> class="col2">right/left</td><td
<tr> class="col3">up/down</td><td
<th> Task? </th><th> Solution! </th><th> X </th><th> Y </th><th> Z </th> class="col4">forward/ backward</td></tr><tr
</tr> class="row2"><td
<tr> class="col0"> Resize objects</td><td
<td> Position and move objects </td><td> <strong>Translation:</strong> Specify the new location in three dimensions: right/left, up/down, forward/backward. <br/> class="col1"> <strong>Scaling:</strong> To resize a Spatial, specify the scale factor in each dimension: length, height, width. A value between 0.0f and 1.0f will shrink the object; a value bigger than 1.0f will make it grow; and 1.0f will keep this dimension the same. Using the same value for each dimension scales an object proportionally, using different values stretches it. <br/> Example: Make it 10 times longer, one tenth of the height, same width:<pre>thing.setLocalScale&#40; 10.0f, 0.1f, 1.0f &#41;;</pre><pre>thing.scale&#40; 10.0f, 0.1f, 1.0f &#41;;</pre></td><td
Example 1. To move an object <em>to</em> specific coordinates, such as (0,40.2f,-2), use: <pre>thing.setLocalTranslation&#40; new Vector3f&#40; 0.0f, 40.2f, -2.0f &#41; &#41;;</pre> class="col2">length</td><td
<p> class="col3">height</td><td
<br/> class="col4">width</td></tr><tr
Example 2: To move an object <em>by</em> a certain amount, e.g. higher up (y=40.2f) and further back (z=-2.0f): class="row3"><td
</p> class="col0"> Turn objects</td><td
<pre>thing.move&#40; 0.0f, 40.2f, -2.0f &#41;;</pre></td><td>right/left</td><td>up/down</td><td>foreward/ backward</td> class="col1"> <strong>Rotation:</strong> 3-D rotation is a bit tricky (<a
</tr> href="/com/jme3/gde/core/docs/jme2/rotate.html">learn details here</a>). In short: You can rotate around three axes, pitch, yaw, and roll. <br/> Important: <strong>You do not specify the rotation in degrees from 0° to 360°, but in radians from 0.0f to 6.28f (FastMath.PI*2) !</strong> <br/> Example: To roll an object 180° around the z axis:<pre>thing.rotate&#40; 0f , 0f , FastMath.PI &#41;;</pre><p> If you do want to specify angles in degrees then multiply your degrees value with FastMath.DEG_TO_RAD <br/> Example:</p><pre>thing.rotate&#40; 0f , 0f , 180*FastMath.DEG_TO_RAD &#41;;</pre><p> Tip: If your game idea calls for a serious amount of rotations, it is worth looking into <a
<tr> href="/com/jme3/gde/core/docs/jme2/quaternion.html">quaternion</a>s, a data structure that can combine and store rotations efficiently.</p><pre>thing.setLocalRotation&#40; new Quaternion&#40;&#41;. fromAngleAxis&#40;FastMath.PI/2, new Vector3f&#40;1,0,0&#41;&#41;&#41;;</pre></td><td
<td> Resize objects </td><td> <strong>Scaling:</strong> To resize a Spatial, specify the scale factor in each dimension: length, height, width. A value between 0.0f and 1.0f will shrink the object; a value bigger than 1.0f will make it grow; and 1.0f will keep this dimension the same. Using the same value for each dimension scales an object proportionally, using different values stretches it. <br/> class="col2">pitch</td><td
Example: Make it 10 times longer, one tenth of the height, same width: <pre>thing.setLocalScale&#40; 10.0f, 0.1f, 1.0f &#41;;</pre><pre>thing.scale&#40; 10.0f, 0.1f, 1.0f &#41;;</pre></td><td>length</td><td>height</td><td>width</td> class="col3">yaw</td><td
</tr> class="col4">roll</td></tr></table></div></div><h2><a
<tr> name="how_to_troubleshoot_nodes">How to Troubleshoot Nodes?</a></h2><div
<td> Turn objects </td><td> <strong>Rotation:</strong> 3-D rotation is a bit tricky (<a href="/com/jme3/gde/core/docs/jme2/rotate.html">learn details here</a>). In short: You can rotate around three axes, pitch, yaw, and roll. <br/> class="level2"><p> If you get unexpected results, check whether you made the following common mistakes:</p><div
Important: <strong>You do not specify the rotation in degrees from 0° to 360°, but in radians from 0.0f to 6.28f (FastMath.PI*2) !</strong> <br/> class="table sectionedit4"><table
Example: To roll an object 180° around the z axis: <pre>thing.rotate&#40; 0f , 0f , FastMath.PI &#41;;</pre> class="inline"><tr
<p> class="row0"><th
Tip: If your game idea calls for a serious amount of rotations, it is worth looking into <a href="/com/jme3/gde/core/docs/jme2/quaternion.html">quaternion</a>s, a data structure that can combine and store rotations efficiently. class="col0"> Problem?</th><th
</p> class="col1"> Solution!</th></tr><tr
<pre>thing.setLocalRotation&#40; new Quaternion&#40;&#41;. fromAngleAxis&#40;FastMath.PI/2, new Vector3f&#40;1,0,0&#41;&#41;&#41;;</pre></td><td>pitch</td><td>yaw</td><td>roll</td> class="row1"><td
</tr> class="col0"> Created Geometry does not appear in scene</td><td
</table> class="col1"> Have you attached it to (a node that is attached to) the rootNode? <br/> Does it have a Material? <br/> What is its translation (position)? Is it covered up by another Geometry? <br/> Is it too far from the camera? try <a
href="http://jmonkeyengine.org/javadoc/com/jme3/renderer/Camera.html#setFrustumFar%28float%29">cam.setFrustumFar</a>(111111f);</td></tr><tr
</div> class="row2"><td
class="col0"> Spatial rotates wrong</td><td
<h2><a>How to Troubleshoot Nodes?</a></h2> class="col1"> Did you use radian values, and not degrees? (if you used degrees multiply them with FastMath.DEG_TO_RAD to get them converted to radians)<br/> Did you rotate the intended pivot node? <br/> Did you rotate around the right axis?</td></tr><tr
<div> class="row3"><td
class="col0"> Geometry has an unexpected Material</td><td
<p> class="col1 leftalign"> Did you reuse a Material from another Geometry and have inadvertently changed its properties? <br/> (if so, maybe consider cloning: mat2 = mat.clone(); )</td></tr></table></div></div><h2><a
name="conclusion">Conclusion</a></h2><div
If you get unexpected results, check whether you made the following common mistakes: class="level2"><p> You have learned that the 3D world is a Scene Graph of Spatials: Visible Geometries and invisible Nodes. You can transform Spatials, or attach them to nodes and transform the nodes. <br/> <br/> Since standard shapes like spheres and boxes get old fast, continue with the next chapter where you learn to <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">load assets, such as 3-D models</a>.</p><div
</p> class="tags"><span> <a
<table> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
<tr> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
<th> Problem? </th><th> Solution! </th> href="/wiki/doku.php/tag:rootnode?do=showtag&amp;tag=tag%3Arootnode">rootNode</a>, <a
</tr> href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>, <a
<tr> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<td> Created Geometry does not appear in scene </td><td> Have you attached it to (a node that is attached to) the rootNode? <br/> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
Does it have a Material? <br/> href="/wiki/doku.php/tag:color?do=showtag&amp;tag=tag%3Acolor">color</a> </span></div></div>
What is its translation (positition)? Is it covered up by another Geometry? </td>
</tr>
<tr>
<td> Spatial rotates wrong </td><td> Did you use radian values, and not degrees? <br/>
Did you rotate the intended pivot node? <br/>
Did you rotate around the right axis? </td>
</tr>
<tr>
<td> Geometry has an unexpected Material </td><td> Did you reuse a Material from another Geometry and have inadvertently changed its properties? </td>
</tr>
</table>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned that the 3D world is a Scene Graph of Spatials: Visible Geometries and invisible Nodes. You can transform Spatials, or attach them to nodes and transform the nodes.
</p>
<p>
Since standard shapes like spheres and boxes get old fast, continue with the next chapter where you learn to <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">load assets, such as 3-D models</a>.
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:rootnode?do=showtag&amp;tag=tag%3Arootnode">rootnode</a>,
<a href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:color?do=showtag&amp;tag=tag%3Acolor">color</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_node?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_node?do=export_xhtmlbody">view online version</a></em></p>

@ -1,51 +1,26 @@
<h1><a
<h1><a>JME 3 Tutorial (13) - Hello Physics</a></h1> name="jme_3_tutorial_13_-_hello_physics">JME 3 Tutorial (13) - Hello Physics</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3.html">JME 3 documentation</a></p><p> For the simulation of physical forces, jME3 integrates the <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a>, href="http://jbullet.advel.cz/">jBullet</a> library. The most common use cases for physics in 3D games are:</p><ul><li
Next: <a href="/com/jme3/gde/core/docs/jme3.html">JME 3 documentation</a> class="level1"><div
</p> class="li"> Driving vehicles with suspensions, tyre friction, ramp jumping, drifting – example: car racers</div></li><li
class="level1"><div
<p> class="li"> Rolling and bouncing balls – example: pong, pool billiard, bowling</div></li><li
For the simulation of physical forces, jME3 integrates the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jbullet.advel.cz/"><param name="text" value="<html><u>jBullet</u></html>"><param name="textColor" value="blue"></object> library. The most common use cases for physics in 3D games are: class="level1"><div
class="li"> Sliding and falling boxes – example: Breakout, Arkanoid</div></li><li
</p> class="level1"><div
<ul> class="li"> Exposing objects to forces and gravity – example: spaceships or zero-g flight</div></li><li
<li><div> Driving vehicles with suspensions, tyre friction, ramp jumping, drifting – example: car racers</div> class="level1"><div
</li> class="li"> Animating ragdolls – example: &quot;realistic&quot; character simulations</div></li><li
<li><div> Rolling and bouncing balls – example: pong, pool billiard, bowling</div> class="level1"><div
</li> class="li"> … and much more: swinging pendulums, flexible chains…</div></li></ul><p> All that can be done in JME3. Let&#039;s have a look at a Physics simulation in this example where we shoot cannon balls at a wall.</p><p> <a
<li><div> Sliding and falling boxes – example: Breakout, Arkanoid</div> href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-physics.png?id=jme3%3Abeginner%3Ahello_physics"><img
</li> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-physics.png?w=360&amp;h=291" class="mediacenter" alt="" width="360" height="291" /></a></p></div><h2><a
<li><div> Exposing objects to forces and gravity – example: spaceships or zero-g flight</div> name="sample_code">Sample Code</a></h2><div
</li> class="level2"><p> Thanks to double1984 for contributing this fun sample!</p><pre>package jme3test.helloworld;
<li><div> Animating ragdolls – example: “realistic” character simulations</div>
</li>
<li><div> … and much more: swinging pendulums, flexible chains…</div>
</li>
</ul>
<p>
All that can be done in JME3. Let&#039;s have a look at a Physics simulation in this example where we shoot cannon balls at a wall.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-physics.png">
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<p>
Thanks to double1984 for contributing this fun sample!
</p>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey; import com.jme3.asset.TextureKey;
@ -253,51 +228,20 @@ public class HelloPhysics extends SimpleApplication &#123;
settings.getHeight&#40;&#41; / 2 + ch.getLineHeight&#40;&#41; / 2, 0&#41;; settings.getHeight&#40;&#41; / 2 + ch.getLineHeight&#40;&#41; / 2, 0&#41;;
guiNode.attachChild&#40;ch&#41;; guiNode.attachChild&#40;ch&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> You should see a brick wall that is casting a shadow on a floor. Click to shoot cannon balls. Watch the bricks fall and bounce off one another!</p></div><h2><a
<p> name="a_basic_physics_application">A Basic Physics Application</a></h2><div
You should see a brick wall that is casting a shadow on a floor. Click to shoot cannon balls. Watch the bricks fall and bounce off one another! class="level2"><p> In the previous tutorials, we were using Geometries (boxes, spheres, and models) that we placed in the scene. Geometries can float in mid-air and even overlap – they are not affected by &quot;gravity&quot; and have no physical mass. This tutorial shows how to add physical properties to Geometries.</p><p> As always, we start with a standard com.jme3.app.SimpleApplication. To activate physics, we create a com.jme3.bullet.BulletAppState, and and attach it to the SimpleApplication&#039;s application state manager.</p><pre>public class HelloPhysics extends SimpleApplication &#123;
</p>
</div>
<h2><a>A Basic Physics Application</a></h2>
<div>
<p>
In the previous tutorials, we were using Geometries (boxes, spheres, and models) that we placed in the scene. Geometries can float in mid-air and even overlap – they are not affected by “gravity” and have no physical mass. This tutorial shows how to add physical properties to Geometries.
</p>
<p>
As always, we start with a standard com.jme3.app.SimpleApplication. To activate physics, we create a com.jme3.bullet.BulletAppState, and and attach it to the SimpleApplication&#039;s application state manager.
</p>
<pre>public class HelloPhysics extends SimpleApplication &#123;
private BulletAppState bulletAppState; private BulletAppState bulletAppState;
&nbsp; &nbsp;
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
bulletAppState = new BulletAppState&#40;&#41;; bulletAppState = new BulletAppState&#40;&#41;;
stateManager.attach&#40;bulletAppState&#41;; stateManager.attach&#40;bulletAppState&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> The BulletAppState gives the game access to a Physics Space. The Physics Space allows us to use com.jme3.bullet.control.PhysicsControls that add physical properties to Nodes.</p></div><h2><a
<p> name="creating_bricks_and_cannon_balls">Creating Bricks and Cannon Balls</a></h2><div
The BulletAppState gives the game access to a Physics Space. The Physics Space allows us to use com.jme3.bullet.control.PhysicsControls that add physical properties to Nodes. class="level2"></div><h3><a
</p> name="geometries">Geometries</a></h3><div
class="level3"><p> In this &quot;shoot at the wall&quot; example, we use Geometries such as cannon balls and bricks. A geometry just describes the shape and look of an object.</p><pre> /** Prepare geometries and physical nodes for bricks and cannon balls. */
</div>
<h2><a>Creating Bricks and Cannon Balls</a></h2>
<div>
</div>
<h3><a>Geometries</a></h3>
<div>
<p>
In this “shoot at the wall” example, we use Geometries such as cannon balls and bricks. A geometry just describes the shape and look of an object.
</p>
<pre> /** Prepare geometries and physical nodes for bricks and cannon balls. */
private static final Box box; private static final Box box;
private static final Sphere sphere; private static final Sphere sphere;
private static final Box floor; private static final Box floor;
@ -317,31 +261,15 @@ In this “shoot at the wall” example, we use Geometries such as cannon balls
/** Initialize the floor geometry */ /** Initialize the floor geometry */
floor = new Box&#40;Vector3f.ZERO, 10f, 0.1f, 5f&#41;; floor = new Box&#40;Vector3f.ZERO, 10f, 0.1f, 5f&#41;;
floor.scaleTextureCoordinates&#40;new Vector2f&#40;3, 6&#41;&#41;; floor.scaleTextureCoordinates&#40;new Vector2f&#40;3, 6&#41;&#41;;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="rigidbodycontrolbrick">RigidBodyControl: Brick</a></h3><div
class="level3"><p> For each Geometry that we want to have physcial properties, we add a RigidBodyControl.</p><pre> private RigidBodyControl brick_phy;</pre><p> The <code>makeBrick(loc)</code> methods creates a physics node <code>brickNode</code> at a location loc. Our brick shall have</p><ul><li
<h3><a>RigidBodyControl: Brick</a></h3> class="level1"><div
<div> class="li"> a visible Geometry <code>brick_geo</code></div></li><li
class="level1"><div
<p> class="li"> physical properties <code>brick_phy</code></div><ul><li
class="level2"><div
For each Geometry that we want to have physcial properties, we add a RigidBodyControl. class="li"> a mass of 2.0f.</div></li></ul></li></ul><pre> public void makeBrick&#40;Vector3f loc&#41; &#123;
</p>
<pre> private RigidBodyControl brick_phy;</pre>
<p>
The <code>makeBrick(loc)</code> methods creates a physics node <code>brickNode</code> at a location loc. Our brick shall have
</p>
<ul>
<li><div> a visible Geometry <code>brick_geo</code></div>
</li>
<li><div> physical properties <code>brick_phy</code></div>
<ul>
<li><div> a mass of 2.0f. </div>
</li>
</ul>
</li>
</ul>
<pre> public void makeBrick&#40;Vector3f loc&#41; &#123;
/** Create a brick geometry and attach to scene graph. */ /** Create a brick geometry and attach to scene graph. */
Geometry brick_geo = new Geometry&#40;&quot;brick&quot;, box&#41;; Geometry brick_geo = new Geometry&#40;&quot;brick&quot;, box&#41;;
brick_geo.setMaterial&#40;wall_mat&#41;; brick_geo.setMaterial&#40;wall_mat&#41;;
@ -354,45 +282,23 @@ The <code>makeBrick(loc)</code> methods creates a physics node <code>brickNode</
/** Add physical brick to physics space. */ /** Add physical brick to physics space. */
brick_geo.addControl&#40;brick_phy&#41;; brick_geo.addControl&#40;brick_phy&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;brick_phy&#41;; bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;brick_phy&#41;;
&#125;</pre> &#125;</pre><p> This code sample does the following:</p><ol><li
<p> class="level1"><div
This code sample does the following: class="li"> We use a box shape as brick, and give it a brick-colored material.</div></li><li
</p> class="level1"><div
<ol> class="li"> We attach the brick to the rootNode and position it at the position loc in the scene graph.</div></li><li
<li><div> We use a box shape as brick, and give it a brick-colored material. </div> class="level1"><div
</li> class="li"> (Optionally, we activate a &quot;Cast and Receive&quot; shadow mode for each brick.)</div></li><li
<li><div> We attach the brick to the rootNode and position it at the position loc in the scene graph.</div> class="level1"><div
</li> class="li"> We create a RigidBodyControl for the brick, add it to the brick Geometry, and register it to the PhysicsSpace.</div></li></ol></div><h3><a
<li><div> (Optionally, we activate a “Cast and Receive” shadow mode for each brick.)</div> name="rigidbodycontrolcannonball">RigidBodyControl: Cannonball</a></h3><div
</li> class="level3"><p> You will notice that the cannon ball is created in the same way:</p><p> The <code>makeCannonBall()</code> methods creates a physics node <code>cannonballNode</code>. The cannon ball shall have</p><ul><li
<li><div> We create a RigidBodyControl for the brick, add it to the brick Geometry, and register it to the PhysicsSpace. </div> class="level1"><div
</li> class="li"> a visible Geometry <code>ball_geo</code></div></li><li
</ol> class="level1"><div
class="li"> physical properties <code>ball_phy</code></div><ul><li
</div> class="level2"><div
class="li"> a mass of 1.0f.</div></li></ul></li></ul><pre> public void makeCannonBall&#40;&#41; &#123;
<h3><a>RigidBodyControl: Cannonball</a></h3>
<div>
<p>
You will notice that the cannon ball is created in the same way:
</p>
<p>
The <code>makeCannonBall()</code> methods creates a physics node <code>cannonballNode</code>. The cannon ball shall have
</p>
<ul>
<li><div> a visible Geometry <code>ball_geo</code></div>
</li>
<li><div> physical properties <code>ball_phy</code></div>
<ul>
<li><div> a mass of 1.0f. </div>
</li>
</ul>
</li>
</ul>
<pre> public void makeCannonBall&#40;&#41; &#123;
/** Create a cannon ball geometry and attach to scene graph. */ /** Create a cannon ball geometry and attach to scene graph. */
Geometry ball_geo = new Geometry&#40;&quot;cannon ball&quot;, sphere&#41;; Geometry ball_geo = new Geometry&#40;&quot;cannon ball&quot;, sphere&#41;;
ball_geo.setMaterial&#40;stone_mat&#41;; ball_geo.setMaterial&#40;stone_mat&#41;;
@ -407,47 +313,25 @@ The <code>makeCannonBall()</code> methods creates a physics node <code>cannonbal
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;ball_phy&#41;; bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;ball_phy&#41;;
/** Accelerate the physcial ball to shoot it. */ /** Accelerate the physcial ball to shoot it. */
ball_phy.setLinearVelocity&#40;cam.getDirection&#40;&#41;.mult&#40;25&#41;&#41;; ball_phy.setLinearVelocity&#40;cam.getDirection&#40;&#41;.mult&#40;25&#41;&#41;;
&#125;</pre> &#125;</pre><p> This code sample does the following:</p><ol><li
<p> class="level1"><div
This code sample does the following: class="li"> We use a sphere shape as cannonball, and give it a stone material.</div></li><li
</p> class="level1"><div
<ol> class="li"> We attach the ball to the rootNode and position it where the camera is.</div></li><li
<li><div> We use a sphere shape as cannonball, and give it a stone material. </div> class="level1"><div
</li> class="li"> (Optionally, we activate a &quot;Cast and Receive&quot; shadow mode for the ball.)</div></li><li
<li><div> We attach the ball to the rootNode and position it where the camera is.</div> class="level1"><div
</li> class="li"> We create a RigidBodyControl for the ball, add it to the ball Geometry, and register it to the PhysicsSpace.</div></li><li
<li><div> (Optionally, we activate a “Cast and Receive” shadow mode for the ball.)</div> class="level1"><div
</li> class="li"> Since are are shooting cannon balls here, we accelerate the ball in the direction the camera is looking, with a speed of 25f.</div></li></ol></div><h3><a
<li><div> We create a RigidBodyControl for the ball, add it to the ball Geometry, and register it to the PhysicsSpace. </div> name="rigidbodycontrolfloor">RigidBodyControl: Floor</a></h3><div
</li> class="level3"><p> The (static) floor has one important difference compared to the (dynamic) bricks and cannonballs: A mass of zero.</p><p> As before, we write a custom <code>initFloor()</code> method that creates a flat box with a rock texture that we use as floor. The floor shall have:</p><ul><li
<li><div> Since are are shooting cannon balls here, we accelerate the ball in the direction the camera is looking, with a speed of 25f.</div> class="level1"><div
</li> class="li"> a visible Geometry <code>floor_geo</code></div></li><li
</ol> class="level1"><div
class="li"> physical properties <code>floor_phy</code></div><ul><li
</div> class="level2"><div
class="li"> A mass of 0.0f!</div></li></ul></li></ul><pre> private RigidBodyControl floor_phy;
<h3><a>RigidBodyControl: Floor</a></h3>
<div>
<p>
The (static) floor has one important difference compared to the (dynamic) bricks and cannonballs: A mass of zero.
</p>
<p>
As before, we write a custom <code>initFloor()</code> method that creates a flat box with a rock texture that we use as floor. The floor shall have:
</p>
<ul>
<li><div> a visible Geometry <code>floor_geo</code></div>
</li>
<li><div> physical properties <code>floor_phy</code></div>
<ul>
<li><div> A mass of 0.0f!</div>
</li>
</ul>
</li>
</ul>
<pre> private RigidBodyControl floor_phy;
... ...
public void initFloor&#40;&#41; &#123; public void initFloor&#40;&#41; &#123;
Box&#40;Vector3f.ZERO, 10f, 0.1f, 5f&#41;; Box&#40;Vector3f.ZERO, 10f, 0.1f, 5f&#41;;
@ -461,144 +345,54 @@ As before, we write a custom <code>initFloor()</code> method that creates a flat
floor_phy = new RigidBodyControl&#40;0.0f&#41;; floor_phy = new RigidBodyControl&#40;0.0f&#41;;
floor_geo.addControl&#40;floor_phy&#41;; floor_geo.addControl&#40;floor_phy&#41;;
bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;floor_phy&#41;; bulletAppState.getPhysicsSpace&#40;&#41;.add&#40;floor_phy&#41;;
&nbsp;</pre> &nbsp;</pre><p> This code sample does the following:</p><ol><li
<p> class="level1"><div
This code sample does the following: class="li"> We use a box shape as floor, and give it a floor material.</div></li><li
</p> class="level1"><div
<ol> class="li"> We attach the floor to the rootNode and position it a bit below the origin – to prevent overlap with other physical nodes.</div></li><li
<li><div> We use a box shape as floor, and give it a floor material. </div> class="level1"><div
</li> class="li"> (Optionally, we activate a &quot;Receive&quot; shadow mode for the floor. The floor does not cast any shadows, this saves computing time.)</div></li><li
<li><div> We attach the floor to the rootNode and position it a bit below the origin – to prevent overlap with other physical nodes.</div> class="level1"><div
</li> class="li"> Static objects such as floors are mass-less and are not affected by gravity! Therefor we create a RigidBodyControl with a mass of 0.0f.</div></li><li
<li><div> (Optionally, we activate a “Receive” shadow mode for the floor. The floor does not cast any shadows, this saves computing time.)</div> class="level1"><div
</li> class="li"> We add the RigidBodyControl to the floor Geometry, and register it to the PhysicsSpace.</div></li></ol></div><h2><a
<li><div> Static objects such as floors are mass-less and are not affected by gravity! Therefor we create a RigidBodyControl with a mass of 0.0f. </div> name="creating_the_scene">Creating the Scene</a></h2><div
</li> class="level2"><p> Let&#039;s have a quick look at the remaining custom helper methods: <code>initMaterial()</code>, <code>initShadows()</code>, <code>initCrossHairs()</code>, and <code>initWall()</code>.</p><ul><li
<li><div> We add the RigidBodyControl to the floor Geometry, and register it to the PhysicsSpace. </div> class="level1"><div
</li> class="li"> <code>initMaterial()</code> – This method initializes all the materials we use in this demo.</div></li><li
</ol> class="level1"><div
class="li"> <code>initShadows()</code> – (Optional) We deactivate the rootNode&#039;s default ShadowMode and use a JME SceneProcessor called BasicShadowRenderer from the <code>com.jme3.shadow</code> package. For every relevant scene node (floor, cannon balls, bricks) we specify individually what shadow behaviour we want, Cast, Receive, or both.</div></li><li
</div> class="level1"><div
class="li"> <code>initWall()</code> – A double loop that generates a wall by positioning brick objects: 15 rows high with 4 bricks per row. It&#039;s important to space the bricks so the do not overlap.</div></li><li
<h2><a>Creating the Scene</a></h2> class="level1"><div
<div> class="li"> <code>initCrossHairs()</code> – This method simply displays a plus sign that we use as crosshairs for aiming. Note that screen elements such as crosshairs are attached to the <code>guiNode</code>, not the <code>rootNode</code>.</div></li></ul><p> These methods are each called once from the <code>simpleInitApp()</code> method at the start of the game. As you see, you write any number of custom methods to set up your game&#039;s scene.</p></div><h2><a
name="the_cannon_ball_shooting_action">The Cannon Ball Shooting Action</a></h2><div
<p> class="level2"><p> In the <code>initSimpleApp()</code> we add an input mapping that triggers a shoot action when the left mouse button is pressed.</p><pre> public void simpleInitApp&#40;&#41; &#123;
Let&#039;s have a quick look at the remaining custom helper methods: <code>initMaterial()</code>, <code>initShadows()</code>, <code>initCrossHairs()</code>, and <code>initWall()</code>.
</p>
<ul>
<li><div> <code>initMaterial()</code> – This method initializes all the materials we use in this demo.</div>
</li>
<li><div> <code>initShadows()</code> – (Optional) We deactivate the rootNode&#039;s default ShadowMode and use a JME SceneProcessor called BasicShadowRenderer from the <code>com.jme3.shadow</code> package. For every relevant scene node (floor, cannon balls, bricks) we specify individually what shadow behaviour we want, Cast, Receive, or both.</div>
</li>
<li><div> <code>initWall()</code> – A double loop that generates a wall by positioning brick objects: 15 rows high with 4 bricks per row. It&#039;s important to space the bricks so the do not overlap.</div>
</li>
<li><div> <code>initCrossHairs()</code> – This method simply displays a plus sign that we use as crosshairs for aiming. Note that screen elements such as crosshairs are attached to the <code>guiNode</code>, not the <code>rootNode</code>.</div>
</li>
</ul>
<p>
These methods are each called once from the <code>simpleInitApp()</code> method at the start of the game. As you see, you write any number of custom methods to set up your game&#039;s scene.
</p>
</div>
<h2><a>The Cannon Ball Shooting Action</a></h2>
<div>
<p>
In the <code>initSimpleApp()</code> we add an input mapping that triggers a shoot action when the left mouse button is pressed.
</p>
<pre> public void simpleInitApp&#40;&#41; &#123;
... ...
inputManager.addMapping&#40;&quot;shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;; inputManager.addMapping&#40;&quot;shoot&quot;, new MouseButtonTrigger&#40;0&#41;&#41;;
inputManager.addListener&#40;actionListener, &quot;shoot&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;shoot&quot;&#41;;
... ...
&#125;</pre> &#125;</pre><p> The action of shooting a new cannon ball is defined as follows:</p><pre> private ActionListener&#40;&#41; &#123;
<p>
The action of shooting a new cannon ball is defined as follows:
</p>
<pre> private ActionListener&#40;&#41; &#123;
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
if &#40;name.equals&#40;&quot;shoot&quot;&#41; &amp;&amp; !keyPressed&#41; &#123; if &#40;name.equals&#40;&quot;shoot&quot;&#41; &amp;&amp; !keyPressed&#41; &#123;
makeCannonBall&#40;&#41;; makeCannonBall&#40;&#41;;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre><p> In the moment the cannonball appears in the scene, it flies off with the velocity (and in the direction) that we have specified using <code>setLinearVelocity()</code> inside <code>makeCannonBall()</code>. The newly created cannon ball flies off, hits the wall, and exerts a <em>physical force</em> that shifts the individual bricks.</p></div><h2><a
<p> name="movement_of_the_physics_enabled_spatial">Movement of the physics enabled Spatial</a></h2><div
In the moment the cannonball appears in the scene, it flies off with the velocity (and in the direction) that we have specified using <code>setLinearVelocity()</code> inside <code>makeCannonBall()</code>. The newly created cannon ball flies off, hits the wall, and exerts a <em>physical force</em> that shifts the individual bricks. class="level2"><p> The location of the spatial is defined by the RigidBodyControl, move that to move the spatial or if its a non-world-object set the RigidBodyControl to kinematic mode to have it move along with the spatial. This will make the RigidBody be unaffected by the physics but it will effect the physics objects around it based on its location and amount of movement that is applied. Note that a kinematic RigidBody needs to have a mass!</p></div><h2><a
</p> name="excercises">Excercises</a></h2><div
class="level2"><p> <strong>Exercise 1</strong></p><p> What happens if you give a static node such as the floor a mass of more than 0.0f?</p><p> <strong>Exercise 2</strong></p><p> Popular AAA games use a clever mix of physics, animation and prerendered graphics to give you the illusion of a real, &quot;physical&quot; world. Look at your favorite games and try to spot where and how the game designers trick you into believing that the whole scene is physical. – For example, a building &quot;breaking&quot; into 4-8 parts when falling apart is most likely being replaced by dynamic physics nodes only after it has been destroyed… Now that you start to implement game physics yourself, look behind the curtain.</p></div><h2><a
</div> name="conclusion">Conclusion</a></h2><div
class="level2"><p> Using physics everywhere in a game sounds like a cool idea, but it is easily overused. Although the physics nodes are put to &quot;sleep&quot; when they are not moved, creating a world solely out of dynamic physics nodes will quickly bring you to the limits of your computer&#039;s capabilities.</p><p> You have learned how to add a PhysicsSpace to an application by attaching a <code>BulletAppState</code>. You know how to create PhysicsNodes from a geometry, a collision shape, and a mass value. You have learned that physical objects are not only attached to the rootNode but also registered to the PhysicsSpace. You are aware that overusing physics has a huge performance impact.</p><p> Additionally you have learned how to add shadows to a scene.</p><hr
<h2><a>Movement of the physics enabled Spatial</a></h2> /><p> This is the last beginner tutorial for now. Now you are ready to start <a
<div> href="/com/jme3/gde/core/docs/jme3.html">combining</a> what you learned to create a game of your own!</p><div
class="tags"><span> <a
<p> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
The location of the spatial is defined by the RigidBodyControl, move that to move the spatial or if its a non-world-object set the RigidBodyControl to kinematic mode to have it move along with the spatial. This will make the RigidBody be unaffected by the physics but it will effect the physics objects around it based on its location and amount of movement that is applied. Note that a kinematic RigidBody needs to have a mass! href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
</p> href="/wiki/doku.php/tag:physics?do=showtag&amp;tag=tag%3Aphysics">physics</a>, <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
</div> href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>, <a
<h2><a>Excercises</a></h2> href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a> </span></div></div>
<div>
<p>
<strong>Exercise 1</strong>
</p>
<p>
What happens if you give a static node such as the floor a mass of more than 0.0f?
</p>
<p>
<strong>Exercise 2</strong>
</p>
<p>
Popular AAA games use a clever mix of physics, animation and prerendered graphics to give you the illusion of a real, “physical” world. Look at your favorite games and try to spot where and how the game designers trick you into believing that the whole scene is physical. – For example, a building “breaking” into 4-8 parts when falling apart is most likely being replaced by dynamic physics nodes only after it has been destroyed… Now that you start to implement game physics yourself, look behind the curtain.
</p>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
Using physics everywhere in a game sounds like a cool idea, but it is easily overused. Although the physics nodes are put to “sleep” when they are not moved, creating a world solely out of dynamic physics nodes will quickly bring you to the limits of your computer&#039;s capabilities.
</p>
<p>
You have learned how to add a PhysicsSpace to an application by attaching a <code>BulletAppState</code>. You know how to create PhysicsNodes from a geometry, a collision shape, and a mass value. You have learned that physical objects are not only attached to the rootNode but also registered to the PhysicsSpace. You are aware that overusing physics has a huge performance impact.
</p>
<p>
Additionally you have learned how to add shadows to a scene.
</p>
<hr />
<p>
This is the last beginner tutorial for now. Now you are ready to start <a href="/com/jme3/gde/core/docs/jme3.html">combining</a> what you learned to create a game of your own!
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:physics?do=showtag&amp;tag=tag%3Aphysics">physics</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:model?do=showtag&amp;tag=tag%3Amodel">model</a>,
<a href="/wiki/doku.php/tag:controller?do=showtag&amp;tag=tag%3Acontroller">controller</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_physics?do=export_xhtmlbody">view online version</a></em></p>

@ -1,39 +1,16 @@
<h1><a
<h1><a>JME 3 Tutorial (8) - Hello Picking</a></h1> name="jme_3_tutorial_8_-_hello_picking">JME 3 Tutorial (8) - Hello Picking</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a></p><p> <br/> Typical interactions in games include shooting, picking up objects, and opening doors.
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a>,
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a>
</p>
<p>
Typical interactions in games include shooting, picking up objects, and opening doors.
</p>
<p>
From an implementation point of view, these apparently different interactions are very similar: The user first aims and selects a target in the 3D scene, and then triggers an action on it. We call this process picking. From an implementation point of view, these apparently different interactions are very similar: The user first aims and selects a target in the 3D scene, and then triggers an action on it. We call this process picking.
</p> You can pick something by either pressing a key on the keyboard, or by clicking with the mouse. In either case, you identify the target by aiming a ray –a straight line– into the scene. This method to implement picking is called <em>ray casting</em> (which is not the same as <em>ray tracing</em>). <a
href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-picking.png?id=jme3%3Abeginner%3Ahello_picking"><img
<p> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-picking.png" class="mediacenter" alt="" /></a> This tutorial relies on what you have learned in the <a
You can pick something by either pressing a key on the keyboard, or by clicking with the mouse. In either case, you identify the target by aiming a ray –a straight line– into the scene. This method to implement picking is called <em>ray casting</em> (which is not the same as <em>ray tracing</em>). href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> tutorial.</p></div><h2><a
</p> name="sample_code">Sample Code</a></h2><div
class="level2"><pre>package jme3test.helloworld;
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-picking.png">
</p>
<p>
This tutorial relies on what you have learned in the <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> tutorial.
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.collision.CollisionResult; import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults; import com.jme3.collision.CollisionResults;
@ -50,25 +27,20 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere; import com.jme3.scene.shape.Sphere;
&nbsp;
<span>/** Sample 8 - how to let the user pick (select) objects in the scene <span>/** Sample 8 - how to let the user pick (select) objects in the scene
* using the mouse or key presses. Can be used for shooting, opening doors, etc. */</span> * using the mouse or key presses. Can be used for shooting, opening doors, etc. */</span>
public class HelloPicking extends SimpleApplication &#123; public class HelloPicking extends SimpleApplication &#123;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
HelloPicking app = new HelloPicking&#40;&#41;; HelloPicking app = new HelloPicking&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
Node shootables; Node shootables;
Geometry mark; Geometry mark;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
initCrossHairs&#40;&#41;; // a &quot;+&quot; in the middle of the screen to help aiming initCrossHairs&#40;&#41;; // a &quot;+&quot; in the middle of the screen to help aiming
initKeys&#40;&#41;; // load custom key mappings initKeys&#40;&#41;; // load custom key mappings
initMark&#40;&#41;; // a red sphere to mark the hit initMark&#40;&#41;; // a red sphere to mark the hit
&nbsp;
/** create four colored boxes and a floor to shoot at: */ /** create four colored boxes and a floor to shoot at: */
shootables = new Node&#40;&quot;Shootables&quot;&#41;; shootables = new Node&#40;&quot;Shootables&quot;&#41;;
rootNode.attachChild&#40;shootables&#41;; rootNode.attachChild&#40;shootables&#41;;
@ -78,7 +50,6 @@ public class HelloPicking extends SimpleApplication &#123;
shootables.attachChild&#40;makeCube&#40;&quot;the Deputy&quot;, 1f, 0f,-4f&#41;&#41;; shootables.attachChild&#40;makeCube&#40;&quot;the Deputy&quot;, 1f, 0f,-4f&#41;&#41;;
shootables.attachChild&#40;makeFloor&#40;&#41;&#41;; shootables.attachChild&#40;makeFloor&#40;&#41;&#41;;
&#125; &#125;
&nbsp;
/** Declaring the &quot;Shoot&quot; action and mapping to its triggers. */ /** Declaring the &quot;Shoot&quot; action and mapping to its triggers. */
private void initKeys&#40;&#41; &#123; private void initKeys&#40;&#41; &#123;
inputManager.addMapping&#40;&quot;Shoot&quot;, inputManager.addMapping&#40;&quot;Shoot&quot;,
@ -86,7 +57,6 @@ public class HelloPicking extends SimpleApplication &#123;
new MouseButtonTrigger&#40;0&#41;&#41;; // trigger 2: left-button click new MouseButtonTrigger&#40;0&#41;&#41;; // trigger 2: left-button click
inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;; inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;;
&#125; &#125;
&nbsp;
/** Defining the &quot;Shoot&quot; action: Determine what was hit and how to respond. */ /** Defining the &quot;Shoot&quot; action: Determine what was hit and how to respond. */
private ActionListener&#40;&#41; &#123; private ActionListener&#40;&#41; &#123;
@Override @Override
@ -122,7 +92,6 @@ public class HelloPicking extends SimpleApplication &#123;
&#125; &#125;
&#125; &#125;
&#125;; &#125;;
&nbsp;
/** A cube object for target practice */ /** A cube object for target practice */
protected Geometry makeCube&#40;String name, float x, float y, float z&#41; &#123; protected Geometry makeCube&#40;String name, float x, float y, float z&#41; &#123;
Box&#40;new Vector3f&#40;x, y, z&#41;, 1, 1, 1&#41;; Box&#40;new Vector3f&#40;x, y, z&#41;, 1, 1, 1&#41;;
@ -132,7 +101,6 @@ public class HelloPicking extends SimpleApplication &#123;
cube.setMaterial&#40;mat1&#41;; cube.setMaterial&#40;mat1&#41;;
return cube; return cube;
&#125; &#125;
&nbsp;
/** A floor to show that the &quot;shot&quot; can go through several objects. */ /** A floor to show that the &quot;shot&quot; can go through several objects. */
protected Geometry makeFloor&#40;&#41; &#123; protected Geometry makeFloor&#40;&#41; &#123;
Box&#40;new Vector3f&#40;0,-4,-5&#41;, 15,.2f,15&#41;; Box&#40;new Vector3f&#40;0,-4,-5&#41;, 15,.2f,15&#41;;
@ -142,7 +110,6 @@ public class HelloPicking extends SimpleApplication &#123;
floor.setMaterial&#40;mat1&#41;; floor.setMaterial&#40;mat1&#41;;
return floor; return floor;
&#125; &#125;
&nbsp;
/** A red ball that marks the last spot that was &quot;hit&quot; by the &quot;shot&quot;. */ /** A red ball that marks the last spot that was &quot;hit&quot; by the &quot;shot&quot;. */
protected void initMark&#40;&#41; &#123; protected void initMark&#40;&#41; &#123;
Sphere sphere = new Sphere&#40;30, 30, 0.2f&#41;; Sphere sphere = new Sphere&#40;30, 30, 0.2f&#41;;
@ -151,7 +118,6 @@ public class HelloPicking extends SimpleApplication &#123;
mark_mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;; mark_mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Red&#41;;
mark.setMaterial&#40;mark_mat&#41;; mark.setMaterial&#40;mark_mat&#41;;
&#125; &#125;
&nbsp;
/** A centred plus sign to help the player aim. */ /** A centred plus sign to help the player aim. */
protected void initCrossHairs&#40;&#41; &#123; protected void initCrossHairs&#40;&#41; &#123;
guiNode.detachAllChildren&#40;&#41;; guiNode.detachAllChildren&#40;&#41;;
@ -164,99 +130,44 @@ public class HelloPicking extends SimpleApplication &#123;
settings.getHeight&#40;&#41;/2 + ch.getLineHeight&#40;&#41;/2, 0&#41;; settings.getHeight&#40;&#41;/2 + ch.getLineHeight&#40;&#41;/2, 0&#41;;
guiNode.attachChild&#40;ch&#41;; guiNode.attachChild&#40;ch&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> You should see four colored cubes floating over a gray floor, and cross-hairs. Aim the cross-hairs and click, or press the spacebar to shoot. The last hit will be marked with a red dot.
<p> Keep an eye on the application&#039;s output stream, it will give you more details: The name of the mesh that was hit, the coordinates of the hit, and the distance.</p></div><h2><a
You should see four colored cubes floating over a gray floor, and cross-hairs. Aim the cross-hairs and click, or press the spacebar to shoot. The last hit will be marked with a red dot. name="understanding_the_helper_methods">Understanding the Helper Methods</a></h2><div
</p> class="level2"><p> The methods <code>makeCube()</code>, <code>makeFloor()</code>, <code>initMark()</code>, and <code>initCrossHairs</code>, are custom helper methods. We call them from <code>simpleInitApp()</code> to initialize the scenegraph with sample content.</p><ol><li
class="level1"><div
<p> class="li"> <code>makeCube()</code> creates simple colored boxes for &quot;target practice&quot;.</div></li><li
Keep an eye on the application&#039;s output stream, it will give you more details: The name of the mesh that was hit, the coordinates of the hit, and the distance. class="level1"><div
</p> class="li"> <code>makeFloor()</code> creates a gray floor node for &quot;target practice&quot;.</div></li><li
class="level1"><div
</div> class="li"> <code>initMark()</code> creates a red sphere (&quot;mark&quot;). We will use it later to mark the spot that was hit.</div><ul><li
class="level2"><div
<h2><a>Understanding the Helper Methods</a></h2> class="li"> Note that the mark is not attached and therefor not visible at the start.</div></li></ul></li><li
<div> class="level1"><div
class="li"> <code>initCrossHairs()</code> creates simple cross-hairs by printing a &quot;+&quot; sign in the middle of the screen.</div><ul><li
<p> class="level2"><div
class="li"> Note that the cross-hairs are attached to the <code>guiNode</code>, not to the <code>rootNode</code>.</div></li></ul></li></ol><p> In this example, we attached all &quot;shootable&quot; objects to one custom node, <code>Shootables</code>. This is an optimization so the engine only has to calculate intersections with objects we are actually interested in. The <code>Shootables</code> node is attached to the <code>rootNode</code> as usual.</p></div><h2><a
The methods <code>makeCube()</code>, <code>makeFloor()</code>, <code>initMark()</code>, and <code>initCrossHairs</code>, are custom helper methods. We call them from <code>simpleInitApp()</code> to initialize the scenegraph with sample content. name="understanding_ray_casting_for_hit_testing">Understanding Ray Casting for Hit Testing</a></h2><div
class="level2"><p> Our goal is to determine which box the user &quot;shot&quot; (picked). In general, we want to determine which mesh the user has selected by aiming the cross-hairs at it. Mathematically, we draw a line from the camera and see whether it intersects with objects in the 3D scene. This line is called a ray.
</p> Here is our simple ray casting algorithm for picking objects:</p><ol><li
<ol> class="level1"><div
<li><div> <code>makeCube()</code> creates simple colored boxes for “target practice”. </div> class="li"> Reset the results list.</div></li><li
</li> class="level1"><div
<li><div> <code>makeFloor()</code> creates a gray floor node for “target practice”. </div> class="li"> Cast a ray from cam location into the cam direction.</div></li><li
</li> class="level1"><div
<li><div> <code>initMark()</code> creates a red sphere (“mark”). We will use it later to mark the spot that was hit. </div> class="li"> Collect all intersections between the ray and <code>Shootable</code> nodes in the <code>results</code> list.</div></li><li
<ul> class="level1"><div
<li><div> Note that the mark is not attached and therefor not visible at the start.</div> class="li"> Use the results list to determine what was hit:</div><ol><li
</li> class="level2"><div
</ul> class="li"> For each hit, JME reports its distance from the camera, impact point, and the name of the mesh.</div></li><li
</li> class="level2"><div
<li><div> <code>initCrossHairs()</code> creates simple cross-hairs by printing a ”+” sign in the middle of the screen. </div> class="li"> Sort the results by distance.</div></li><li
<ul> class="level2"><div
<li><div> Note that the cross-hairs are attached to the <code>guiNode</code>, not to the <code>rootNode</code>.</div> class="li"> Take the closest result, it is the mesh that was hit.</div></li></ol></li></ol></div><h2><a
</li> name="implementing_hit_testing">Implementing Hit Testing</a></h2><div
</ul> class="level2"></div><h3><a
</li> name="loading_the_scene">Loading the scene</a></h3><div
</ol> class="level3"><p> First initialize some shootable nodes and attach them to the scene. You will use the <code>mark</code> object later.</p><pre> Node shootables;
<p>
In this example, we attached all “shootable” objects to one custom node, <code>Shootables</code>. This is an optimization so the engine only has to calculate intersections with objects we are actually interested in. The <code>Shootables</code> node is attached to the <code>rootNode</code> as usual.
</p>
</div>
<h2><a>Understanding Ray Casting for Hit Testing</a></h2>
<div>
<p>
Our goal is to determine which box the user “shot” (picked). In general, we want to determine which mesh the user has selected by aiming the cross-hairs at it. Mathematically, we draw a line from the camera and see whether it intersects with objects in the 3D scene. This line is called a ray.
</p>
<p>
Here is our simple ray casting algorithm for picking objects:
</p>
<ol>
<li><div> Reset the results list.</div>
</li>
<li><div> Cast a ray from cam location into the cam direction.</div>
</li>
<li><div> Collect all intersections between the ray and <code>Shootable</code> nodes in the <code>results</code> list.</div>
</li>
<li><div> Use the results list to determine what was hit:</div>
<ol>
<li><div> For each hit, JME reports its distance from the camera, impact point, and the name of the mesh.</div>
</li>
<li><div> Sort the results by distance.</div>
</li>
<li><div> Take the closest result, it is the mesh that was hit.</div>
</li>
</ol>
</li>
</ol>
</div>
<h2><a>Implementing Hit Testing</a></h2>
<div>
</div>
<h3><a>Loading the scene</a></h3>
<div>
<p>
First initialize some shootable nodes and attach them to the scene. You will use the <code>mark</code> object later.
</p>
<pre> Node shootables;
Geometry mark; Geometry mark;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
initCrossHairs&#40;&#41;; initCrossHairs&#40;&#41;;
@ -269,51 +180,27 @@ First initialize some shootable nodes and attach them to the scene. You will use
shootables.attachChild&#40;makeCube&#40;&quot;the Sheriff&quot;, 0f, 1f,-2f&#41;&#41;; shootables.attachChild&#40;makeCube&#40;&quot;the Sheriff&quot;, 0f, 1f,-2f&#41;&#41;;
shootables.attachChild&#40;makeCube&#40;&quot;the Deputy&quot;, 1f, 0f, -4&#41;&#41;; shootables.attachChild&#40;makeCube&#40;&quot;the Deputy&quot;, 1f, 0f, -4&#41;&#41;;
shootables.attachChild&#40;makeFloor&#40;&#41;&#41;; shootables.attachChild&#40;makeFloor&#40;&#41;&#41;;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="setting_up_the_input_listener">Setting Up the Input Listener</a></h3><div
class="level3"><p> Next you declare the shooting action. It can be triggered either by clicking, or by pressing the space bar. The <code>initKeys()</code> method is called from <code>simpleInitApp()</code> to set up these input mappings.</p><pre> /** Declaring the &quot;Shoot&quot; action and its triggers. */
<h3><a>Setting Up the Input Listener</a></h3>
<div>
<p>
Next you declare the shooting action. It can be triggered either by clicking, or by pressing the space bar. The <code>initKeys()</code> method is called from <code>simpleInitApp()</code> to set up these input mappings.
</p>
<pre> /** Declaring the &quot;Shoot&quot; action and its triggers. */
private void initKeys&#40;&#41; &#123; private void initKeys&#40;&#41; &#123;
inputManager.addMapping&#40;&quot;Shoot&quot;, // Declare... inputManager.addMapping&#40;&quot;Shoot&quot;, // Declare...
new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;, // trigger 1: spacebar, or new KeyTrigger&#40;KeyInput.KEY_SPACE&#41;, // trigger 1: spacebar, or
new MouseButtonTrigger&#40;0&#41;&#41;; // trigger 2: left-button click new MouseButtonTrigger&#40;0&#41;&#41;; // trigger 2: left-button click
inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;; // ... and add. inputManager.addListener&#40;actionListener, &quot;Shoot&quot;&#41;; // ... and add.
&#125;</pre> &#125;</pre></div><h3><a
</div> name="defining_the_picking_action">Defining the Picking Action</a></h3><div
class="level3"><p> Next we implement the ActionListener that responds to the Shoot trigger with an action. The action follows the ray casting algorithm described above:</p><ol><li
<h3><a>Defining the Picking Action</a></h3> class="level1"><div
<div> class="li"> For every click or press of the spacebar, the <code>Shoot</code> action is triggered.</div></li><li
class="level1"><div
<p> class="li"> The action casts a ray forward and determines intersections with shootable objects (= ray casting).</div></li><li
class="level1"><div
Next we implement the ActionListener that responds to the Shoot trigger with an action. The action follows the ray casting algorithm described above: class="li"> For any target that has been hit, it prints name, distance, and coordinates of the hit.</div></li><li
class="level1"><div
</p> class="li"> Finally it attaches a red mark to the closest result, to highlight the spot that was actually hit.</div></li><li
<ol> class="level1"><div
<li><div> For every click or press of the spacebar, the <code>Shoot</code> action is triggered.</div> class="li"> When nothing was hit, the results list is empty, and the red mark is removed.</div></li></ol><p> Note how it prints a lot of output to show you which hits were registered.</p><pre> /** Defining the &quot;Shoot&quot; action: Determine what was hit and how to respond. */
</li>
<li><div> The action casts a ray forward and determines intersections with shootable objects (= ray casting).</div>
</li>
<li><div> For any target that has been hit, it prints name, distance, and coordinates of the hit.</div>
</li>
<li><div> Finally it attaches a red mark to the closest result, to highlight the spot that was actually hit.</div>
</li>
<li><div> When nothing was hit, the results list is empty, and the red mark is removed.</div>
</li>
</ol>
<p>
Note how it prints a lot of output to show you which hits were registered.
</p>
<pre> /** Defining the &quot;Shoot&quot; action: Determine what was hit and how to respond. */
private ActionListener&#40;&#41; &#123; private ActionListener&#40;&#41; &#123;
@Override @Override
public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123; public void onAction&#40;String name, boolean keyPressed, float tpf&#41; &#123;
@ -347,118 +234,56 @@ Note how it prints a lot of output to show you which hits were registered.
&#125; &#125;
&#125; &#125;
&#125; &#125;
&#125;;</pre> &#125;;</pre><p> Tip: Notice how you use the provided method <code>results.getClosestCollision().getContactPoint()</code> to determine the <em>closest</em> hit&#039;s location. If your game includes a &quot;weapon&quot; or &quot;spell&quot; that can hit multiple targets, you would instead loop over the list of results, and interact with each of them.</p></div><h2><a
<p> name="exercises">Exercises</a></h2><div
Tip: Notice how you use the provided method <code>results.getClosestCollision().getContactPoint()</code> to determine the <em>closest</em> hit&#039;s location. If your game includes a “weapon” or “spell” that can hit multiple targets, you would instead loop over the list of results, and interact with each of them. class="level2"><p> After a hit was registered, the closest object is identified as target, and marked with a red dot.
</p> Modify the code sample to solve these exercises:</p></div><h3><a
name="magic_spell">Magic Spell</a></h3><div
</div> class="level3"><p> Change the color of the closest clicked target! <br/> Here are some tips:</p><ol><li
class="level1"><div
<h2><a>Exercises</a></h2> class="li"> Go to the line where the closest target is indentified, and add you changes after that.</div></li><li
<div> class="level1"><div
class="li"> To change an object&#039;s color, you must first know its node. Identify the node by identifying the target&#039;s name.</div><ul><li
<p> class="level2"><div
class="li"> Use <code>rootNode.getChild(closest.getGeometry().getName())</code></div></li></ul></li><li
After a hit was registered, the closest object is identified as target, and marked with a red dot. class="level1"><div
Modify the code sample to solve these exercises: class="li"> Create a new color material and set the node&#039;s Material to this color.</div><ul><li
</p> class="level2"><div
class="li"> Look inside the <code>makeCube()</code> method for an example of how to set random colors.</div></li></ul></li></ol></div><h3><a
</div> name="shoot_at_a_character">Shoot at a Character</a></h3><div
class="level3"><p> Shooting boxes isn&#039;t very exciting – can you add code that loads and positions a model in the scene, and shoot at it?</p><ul><li
<h3><a>Magic Spell</a></h3> class="level1"><div
<div> class="li"> Tip: You can use <code>Spatial golem = assetManager.loadModel(&quot;Models/Oto/Oto.mesh.xml&quot;);</code> from the engine&#039;s jme3-test-data.jar.</div></li></ul></div><h3><a
name="pick_up_into_inventory">Pick up into Inventory</a></h3><div
<p> class="level3"><p> Change the code as follows to simulate the player picking up objects into the inventory: When you click once, the closest target is identified and detached from the scene. When you click a second time, the target is reattached at the location that you have clicked. Here are some tips:</p><ol><li
class="level1"><div
Change the color of the closest clicked target! <br/> class="li"> Create an inventory node to store the detached nodes.</div></li><li
Here are some tips: class="level1"><div
</p> class="li"> The inventory node is not attached to the rootNode.</div></li><li
<ol> class="level1"><div
<li><div> Go to the line where the closest target is indentified, and add you changes after that.</div> class="li"> You can make the inventory visible by attaching the inventory node to the guiNode (which attaches it to the HUD). Note the following caveats:</div><ul><li
</li> class="level2"><div
<li><div> To change an object&#039;s color, you must first know its node. Identify the node by identifying the target&#039;s name.</div> class="li"> If your nodes use a lit Material (not &quot;Unshaded.j3md&quot;), also add a light to the guiNode.</div></li><li
<ul> class="level2"><div
<li><div> Use <code>rootNode.getChild(closest.getGeometry().getName())</code></div> class="li"> Size units are pixels in the HUD, therefor a 2-wu cube is displayed only 2 pixels wide. – Scale it.</div></li><li
</li> class="level2"><div
</ul> class="li"> Position the nodes: The bottom left corner of the HUD is (0f,0f), and the top right corner is at (settings.getWidth(),settings.getHeight()).</div></li></ul></li></ol></div><h2><a
</li> name="conclusion">Conclusion</a></h2><div
<li><div> Create a new color material and set the node&#039;s Material to this color.</div> class="level2"><p> You have learned how to use ray casting to solve the task of determining what object a user selected on the screen. You learned that this can be used for a variety of interactions, such as shooting, opening, picking up and dropping items, pressing a button or lever, etc. <br/> Use your imagination from here:</p><ul><li
<ul> class="level1"><div
<li><div> Look inside the <code>makeCube()</code> method for an example of how to set random colors.</div> class="li"> In your game, the click can trigger any action on the identified object: Detach it and put it into the inventory, attach something to it, trigger an animation or effect, open a door or crate, – etc.</div></li><li
</li> class="level1"><div
</ul> class="li"> In your game, you could replace the red mark with a particle emitter, add an explosion effect, play a sound, calculate the new score after each hit depending on what was hit – etc.</div></li></ul><p> Now, wouldn&#039;t it be nice if those targets and the floor were solid objects and you could walk among them? Let&#039;s continue with <a
</li> href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Collision Detection</a>.</p><div
</ol> class="tags"><span> <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</div> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<h3><a>Shoot at a Character</a></h3> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<div> href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>, <a
href="/wiki/doku.php/tag:ray?do=showtag&amp;tag=tag%3Aray">ray</a>, <a
<p> href="/wiki/doku.php/tag:click?do=showtag&amp;tag=tag%3Aclick">click</a>, <a
href="/wiki/doku.php/tag:collision?do=showtag&amp;tag=tag%3Acollision">collision</a>, <a
Shooting boxes isn&#039;t very exciting – can you add code that loads and positions a model in the scene, and shoot at it? href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>, <a
</p> href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a> </span></div></div>
<ul>
<li><div> Tip: You can use <code>Spatial golem = assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);</code> from the engine&#039;s jme3-test-data.jar.</div>
</li>
</ul>
</div>
<h3><a>Pick up into Inventory</a></h3>
<div>
<p>
Change the code as follows to simulate the player picking up objects into the inventory: When you click once, the closest target is identified and detached from the scene. When you click a second time, the target is reattached at the location that you have clicked. Here are some tips:
</p>
<ol>
<li><div> Create an inventory node to store the detached nodes. </div>
</li>
<li><div> The inventory node is not attached to the rootNode. </div>
</li>
<li><div> You can make the inventory visible by attaching the inventory node to the guiNode. </div>
</li>
</ol>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned how to use ray casting to solve the task of determining what object a user selected on the screen. You learned that this can be used for a variety of interactions, such as shooting, opening, picking up and dropping items, pressing a button or lever, etc.
</p>
<p>
Use your imagination from here:
</p>
<ul>
<li><div> In your game, the click can trigger any action on the identified object: Detach it and put it into the inventory, attach something to it, trigger an animation or effect, open a door or crate, – etc.</div>
</li>
<li><div> In your game, you could replace the red mark with a particle emitter, add an explosion effect, play a sound, calculate the new score after each hit depending on what was hit – etc. </div>
</li>
</ul>
<p>
Now, wouldn&#039;t it be nice if those targets and the floor were solid objects and you could walk among them? Let&#039;s continue with <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Collision Detection</a>.
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:node?do=showtag&amp;tag=tag%3Anode">node</a>,
<a href="/wiki/doku.php/tag:ray?do=showtag&amp;tag=tag%3Aray">ray</a>,
<a href="/wiki/doku.php/tag:click?do=showtag&amp;tag=tag%3Aclick">click</a>,
<a href="/wiki/doku.php/tag:collision?do=showtag&amp;tag=tag%3Acollision">collision</a>,
<a href="/wiki/doku.php/tag:keyinput?do=showtag&amp;tag=tag%3Akeyinput">keyinput</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_picking?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_picking?do=export_xhtmlbody">view online version</a></em></p>

@ -1,74 +1,36 @@
<h1><a
<h1><a>JME 3 Tutorial (1) - Hello SimpleApplication</a></h1> name="jme_3_tutorial_1_-_hello_simpleapplication">JME 3 Tutorial (1) - Hello SimpleApplication</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3#installing_jmonkeyengine_3.html">Installing JME3</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> <br/> <br/> This tutorial assumes that you have already <a
Previous: <a href="/com/jme3/gde/core/docs/jme3#installing_jmonkeyengine_3.html">Installing JME3</a>, href="/com/jme3/gde/core/docs/jme3#installing_jmonkeyengine_3.html">downloaded and set up jMonkeyEngine3</a> in an IDE of your choice, and are able to run the bundled samples. <br/> <br/> You are ready to create your first jMonkeyEngine3 game! You can generally use the tutorials in this introductory series with any integrated development environment (IDE), such as the jMonkeyPlatform, NetBeans, Eclipse, or run them straight from the commandline. <br/> <br/></p></div><h2><a
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> name="writing_a_simpleapplication">Writing a SimpleApplication</a></h2><div
</p> class="level2"><p> Create a <code>jme3test.helloworld</code> package and a file <code>HelloJME3.java</code> in it. <br/> <br/> In NetBeans, you would right-click the Source Packages node</p><ul><li
class="level1"><div
<p> class="li"> Select <code>New… &gt; Java Class</code> to create a new file.</div></li><li
class="level1"><div
This tutorial assumes that you have already <a href="/com/jme3/gde/core/docs/jme3#installing_jmonkeyengine_3.html">downloaded and set up jMonkeyEngine3</a> in an IDE of your choice, and are able to run the bundled samples. class="li"> Enter a class name: <code>HelloJME3</code></div></li><li
</p> class="level1"><div
class="li"> Enter a package: <code>jme3test.helloworld</code></div></li><li
<p> class="level1"><div
You are ready to create your first jMonkeyEngine3 game! You can generally use the tutorials in this introductory series with any integrated development environment (IDE), such as the jMonkeyPlatform, NetBeans, Eclipse, or run them straight from the commandline. class="li"> Click Finish.</div></li></ul></div><h3><a
</p> name="sample_code">Sample Code</a></h3><div
class="level3"><p> Replace the contents of the HelloJME3.java file with the following code:</p><pre>package jme3test.helloworld;
</div>
<h2><a>Writing a SimpleApplication</a></h2>
<div>
<p>
Create a <code>jme3test.helloworld</code> package and a file <code>HelloJME3.java</code> in it.
</p>
<p>
In NetBeans, you would right-click the Source Packages node
</p>
<ul>
<li><div> Select <code>New… &gt; Java Class</code> to create a new file.</div>
</li>
<li><div> Enter a class name: <code>HelloJME3</code></div>
</li>
<li><div> Enter a package: <code>jme3test.helloworld</code></div>
</li>
<li><div> Click Finish.</div>
</li>
</ul>
</div>
<h3><a>Sample Code</a></h3>
<div>
<p>
Replace the contents of the HelloJME3.java file with the following code:
</p>
<pre>package jme3test.helloworld;
&nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
&nbsp;
<span>/** Sample 1 - how to get started with the most simple JME 3 application. <span>/** Sample 1 - how to get started with the most simple JME 3 application.
* Display a blue 3D cube and view from all sides by * Display a blue 3D cube and view from all sides by
* moving the mouse and pressing the WASD keys. */</span> * moving the mouse and pressing the WASD keys. */</span>
public class HelloJME3 extends SimpleApplication &#123; public class HelloJME3 extends SimpleApplication &#123;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41;&#123; public static void main&#40;String&#91;&#93; args&#41;&#123;
HelloJME3 app = new HelloJME3&#40;&#41;; HelloJME3 app = new HelloJME3&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
Box&#40;Vector3f.ZERO, 1, 1, 1&#41;; Box&#40;Vector3f.ZERO, 1, 1, 1&#41;;
@ -78,69 +40,20 @@ public class HelloJME3 extends SimpleApplication &#123;
geom.setMaterial&#40;mat&#41;; geom.setMaterial&#40;mat&#41;;
rootNode.attachChild&#40;geom&#41;; rootNode.attachChild&#40;geom&#41;;
&#125; &#125;
&#125;</pre> &#125;</pre><p> Build and run the HelloJME3 class. If a jme settings dialog pops up, confirm the default settings.</p><ol><li
<p> class="level1"><div
class="li"> You should see a simple window displaying a 3-D cube.</div></li><li
Build and run the HelloJME3 class. If a jme settings dialog pops up, confirm the default settings. class="level1"><div
class="li"> Use the WASD keys and the mouse to navigate around.</div></li><li
</p> class="level1"><div
<ol> class="li"> Press Escape to close the application.</div></li></ol><p> Congratulations, it works! How did we do that?</p></div><h2><a
<li><div> You should see a simple window displaying a 3-D cube. </div> name="understanding_the_code">Understanding the Code</a></h2><div
</li> class="level2"><p> Here some basic rules that are valid for all JME3 games:</p></div><h3><a
<li><div> Use the WASD keys and the mouse to navigate around. </div> name="starting_the_game">Starting the Game</a></h3><div
</li> class="level3"><p> Note that the HelloJME3.java class extends <code>com.jme3.app.SimpleApplication</code>, which is a subclass of <code>com.jme3.app.Application</code>. Every JME3 game is an instance of <code>com.jme3.app.Application</code> (directly, or indirectly). <br/> <br/> To run a JME3 game, you first instantiate your <code>Application</code>-based class, and then call its <code>start()</code> method:</p><pre>HelloJME3 app = new HelloJME3&#40;&#41;;
<li><div> Press Escape to close the application. </div> app.start&#40;&#41;;</pre><p> Usually, you do that from your Java application&#039;s main method. <br/> <br/> <strong>Tip:</strong> Advanced Java developers may want to make a copy of <code>SimpleApplication</code> and use it as a template for a custom application class.</p></div><h3><a
</li> name="initializing_the_scene">Initializing the Scene</a></h3><div
</ol> class="level3"><p> This simple &quot;game&quot; consists of nothing but a cube. Here is how we create it, position it, give it a color, and attach it to the scene. (We will have a closer look at the details later.)</p><pre> public void simpleInitApp&#40;&#41; &#123;
<p>
Congratulations, it works! How did we do that?
</p>
</div>
<h2><a>Understanding the Code</a></h2>
<div>
<p>
Here some basic rules that are valid for all JME3 games:
</p>
</div>
<h3><a>Starting the Game</a></h3>
<div>
<p>
Note that the HelloJME3.java class extends <code>com.jme3.app.SimpleApplication</code>, which is a subclass of <code>com.jme3.app.Application</code>. Every JME3 game is an instance of <code>com.jme3.app.Application</code> (directly, or indirectly).
</p>
<p>
To run a JME3 game, you first instantiate your <code>Application</code>-based class, and then call its <code>start()</code> method:
</p>
<pre>HelloJME3 app = new HelloJME3&#40;&#41;;
app.start&#40;&#41;;</pre>
<p>
Usually, you do that from your Java application&#039;s main method.
</p>
<p>
<strong>Tip:</strong> Advanced Java developers may want to make a copy of <code>SimpleApplication</code> and use it as a template for a custom application class.
</p>
</div>
<h3><a>Initializing the Scene</a></h3>
<div>
<p>
This simple “game” consists of nothing but a cube. Here is how we create it, position it, give it a color, and attach it to the scene. (We will have a closer look at the details later.)
</p>
<pre> public void simpleInitApp&#40;&#41; &#123;
Box&#40;Vector3f.ZERO, 1, 1, 1&#41;; // create cube shape Box&#40;Vector3f.ZERO, 1, 1, 1&#41;; // create cube shape
Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;; // create cube geometry from the shape Geometry geom = new Geometry&#40;&quot;Box&quot;, b&#41;; // create cube geometry from the shape
Material mat = new Material&#40;assetManager, Material mat = new Material&#40;assetManager,
@ -148,106 +61,52 @@ This simple “game” consists of nothing but a cube. Here is how we create it,
mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; // set color of material mat.setColor&#40;&quot;Color&quot;, ColorRGBA.Blue&#41;; // set color of material
geom.setMaterial&#40;mat&#41;; // set the cube's material geom.setMaterial&#40;mat&#41;; // set the cube's material
rootNode.attachChild&#40;geom&#41;; // attach the cube to the scene rootNode.attachChild&#40;geom&#41;; // attach the cube to the scene
&#125;</pre> &#125;</pre><p> The <code>simpleInitApp()</code> method is automatically called once at the beginning of every JME3 game. In this method you create or load game objects before the game starts! Here is the usual process:</p><ol><li
<p> class="level1"><div
The <code>simpleInitApp()</code> method is automatically called once at the beginning of every JME3 game. In this method you create or load game objects before the game starts! Here is the usual process: class="li"> Initialize game objects:</div><ul><li
class="level2"><div
</p> class="li"> Create or load all objects, and position them.</div></li><li
<ol> class="level2"><div
<li><div> Initialize game objects:</div> class="li"> To make a geometry (like the box) appear in the scene, attach it to the <code>rootNode</code>.</div></li><li
<ul> class="level2"><div
<li><div> Create or load all objects, and position them.</div> class="li"> Examples: Load player, terrain, sky, enemies, obstacles, and place them in their start positions.</div></li></ul></li><li
</li> class="level1"><div
<li><div> To make a geometry (like the box) appear in the scene, attach it to the <code>rootNode</code>.</div> class="li"> Initialize game variables</div><ul><li
</li> class="level2"><div
<li><div> Examples: Load player, terrain, sky, enemies, obstacles, and place them in their start positions. </div> class="li"> Game variables track the game state. Set them to their start values.</div></li><li
</li> class="level2"><div
</ul> class="li"> Examples: Here you set the <code>score</code> to 0, and <code>health</code> to 100%, and so on.</div></li></ul></li><li
</li> class="level1"><div
<li><div> Initialize game variables</div> class="li"> Initialize navigation</div><ul><li
<ul> class="level2"><div
<li><div> Game variables track the game state. Set them to their start values.</div> class="li"> The following key bindings are pre-configured by default:</div><ul><li
</li> class="level3"><div
<li><div> Examples: Here you set the <code>score</code> to 0, and <code>health</code> to 100%, and so on.</div> class="li"> W,A,S,D keys – Move around</div></li><li
</li> class="level3"><div
</ul> class="li"> Mouse and arrow keys – Turn the camera</div></li><li
</li> class="level3"><div
<li><div> Initialize navigation</div> class="li"> Escape key - Quit game</div></li></ul></li></ul></li></ol><p> The important part is: The JME3 Application has a <code>rootNode</code> object. Your game automatically inherits the rootNode. Everything attached to the rootNode appears in the scene. Or in other words: An object that has been created, but is not attached to the rootNode, remains invisible.</p></div><h2><a
<ul> name="conclusion">Conclusion</a></h2><div
<li><div> The following key bindings are pre-configured by default:</div> class="level2"><p> These few lines of code do nothing but display a static object in 3-D, but they already allow you to navigate around in 3D. You have learned that a SimpleApplication is a good starting point because it provides you with:</p><ul><li
<ul> class="level1"><div
<li><div> W,A,S,D keys – Move around</div> class="li"> a <code>simpleInitApp()</code> method to initialize the game objects</div></li><li
</li> class="level1"><div
<li><div> Mouse and arrow keys – Turn the camera</div> class="li"> a <code>rootNode</code> where you attach geometries to make them appear in the scene</div></li><li
</li> class="level1"><div
<li><div> Escape key - Quit game</div> class="li"> useful default navigation settings</div></li></ul><p> In a real game, you will want to:</p><ol><li
</li> class="level1"><div
</ul> class="li"> Initialize the game world,</div></li><li
</li> class="level1"><div
</ul> class="li"> Trigger actions in the event loop,</div></li><li
</li> class="level1"><div
</ol> class="li"> Respond to user input.</div></li></ol><p> In the following tutorials you will learn how these tasks are accomplished with the jMonkeyEngine 3! <br/> <br/> Continue with the <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> tutorial, where we will first show you more details about how to initialize the game world, also known as the scene graph.</p><hr
<p> /><p> See also: <a
href="/com/jme3/gde/core/docs/jme3/simpleapplication_from_the_commandline.html">SimpleApplication from the commandline</a></p><div
The important part is: The JME3 Application has a <code>rootNode</code> object. Your game automatically inherits the rootNode. Everything attached to the rootNode appears in the scene. Or in other words: An object that has been created, but is not attached to the rootNode, remains invisible. class="tags"><span> <a
</p> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</div> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<h2><a>Conclusion</a></h2> href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a> </span></div></div>
<div>
<p>
These few lines of code do nothing but display a static object in 3-D, but they already allow you to navigate around in 3D. You have learned that a SimpleApplication is a good starting point because it provides you with:
</p>
<ul>
<li><div> a <code>simpleInitApp()</code> method to initialize the game objects</div>
</li>
<li><div> a <code>rootNode</code> where you attach geometries to make them appear in the scene</div>
</li>
<li><div> useful default navigation settings </div>
</li>
</ul>
<p>
In a real game, you will want to:
</p>
<ol>
<li><div> Inititialize the game world,</div>
</li>
<li><div> Trigger actions in the event loop,</div>
</li>
<li><div> Respond to user input.</div>
</li>
</ol>
<p>
In the following tutorials you will learn how these tasks are accomplished with the jMonkeyEngine 3!
</p>
<p>
Continue with the <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> tutorial, where we will first show you more details about how to initialize the game world, also known as the scene graph.
</p>
<hr />
<p>
See also: <a href="/com/jme3/gde/core/docs/jme3/simpleapplication_from_the_commandline.html">SimpleApplication from the commandline</a>
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_simpleapplication?do=export_xhtmlbody">view online version</a></em></p>

@ -1,30 +1,13 @@
<h1><a
<h1><a>JME 3 Tutorial (10) - Hello Terrain</a></h1> name="jme_3_tutorial_10_-_hello_terrain">JME 3 Tutorial (10) - Hello Terrain</a></h1><div
<div> class="level1"><p> Previous: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a>,
<p> Next: <a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a></p><p> One way to create a 3D landscape is to sculpt a huge terrain model. This will give you a lot of artistic freedom – but rendering such a huge model can be quite slow. jME supports heightmaps to solve this common performance issue of terrains.</p><p> This tutorial explains how to create terrains from heightmaps and how to use splat textures to make the terrain look good.</p><p> <a
Previous: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a>, href="/wiki/lib/exe/detail.php/jme3:beginner:beginner-terrain.png?id=jme3%3Abeginner%3Ahello_terrain"><img
Next: <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a> src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-terrain.png?w=360&amp;h=291" class="mediacenter" alt="" width="360" height="291" /></a></p></div><h2><a
</p> name="sample_code">Sample Code</a></h2><div
class="level2"><pre>package jme3test.helloworld;
<p>
One way to create a 3D landscape is to sculpt a huge terrain model. This will give you a lot of artistic freedom – but rendering such a huge model can be quite slow. jME supports heightmaps to solve this common performance issue of terrains.
</p>
<p>
This tutorial explains how to create terrains from heightmaps and how to use splat textures to make the terrain look good.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/beginner/beginner-terrain.png">
</p>
</div>
<h2><a>Sample Code</a></h2>
<div>
<pre>package jme3test.helloworld;
&nbsp; &nbsp;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.material.Material; import com.jme3.material.Material;
@ -110,205 +93,95 @@ public class HelloTerrain extends SimpleApplication &#123;
terrain.addControl&#40;control&#41;; terrain.addControl&#40;control&#41;;
&nbsp; &nbsp;
&#125; &#125;
&#125;</pre> &#125;</pre><p> When you run this sample you should see a landscape with dirt mountains, grass plains, plus some winding roads in between.</p></div><h2><a
<p> name="what_is_a_heightmap">What is a Heightmap?</a></h2><div
When you run this sample you should see a landscape with dirt mountains, grass plains, plus some winding roads in between. class="level2"><p> Heightmaps are an efficient way of representing the shape of a hilly landscape. Picture a heightmap as a float array containing height values between 0f and 255f. Here is a very simple example of a heightmap with 25 height values.</p><p> <a
</p> href="/wiki/lib/exe/detail.php/jme2:terrain-from-float-array.png?id=jme3%3Abeginner%3Ahello_terrain"><img
src="nbdocs:/com/jme3/gde/core/docs/jme2/terrain-from-float-array.png?w=350&amp;h=220" class="media" alt="" width="350" height="220" /></a></p><p> Important things to note:</p><ul><li
</div> class="level1"><div
class="li"> Low values (e.g. 0 or 50) are valeys.</div></li><li
<h2><a>What is a Heightmap?</a></h2> class="level1"><div
<div> class="li"> High values (e.g. 200, 255) are hills.</div></li><li
class="level1"><div
<p> class="li"> We only specified a few points, and the engine interpolates the rest. Interpolation is more efficient than creating a model with several millions of vertices.</div></li></ul><p> Now when looking at Java data types to hold an array of floats between 0 and 255, the Image class comes to mind. Storing a terrain&#039;s height values as a grayscale image has one big advantage: The outcome is a very userfriendly, almost topographical, representation of a landscape:</p><ul><li
class="level1"><div
Heightmaps are an efficient way of representing the shape of a hilly landscape. Picture a heightmap as a float array containing height values between 0f and 255f. Here is a very simple example of a heightmap with 25 height values. class="li"> Low values (e.g. 0 or 50) are dark gray – these are valleys.</div></li><li
</p> class="level1"><div
class="li"> High values (e.g. 200, 255) are light grays – these are hills.</div></li></ul><p> Look at the next screenshot: In the top left you see the 128x128 grayscale image (heightmap) that was used as a base to generate the depicted terrain. To make the hilly shape better visible, the mountain tops are colored white, valleys brown, and the areas inbetween green:</p><p> <a
<p> href="/wiki/lib/exe/detail.php/jme2:terrain-from-heightmap.png?id=jme3%3Abeginner%3Ahello_terrain"><img
<img src="nbdocs:/com/jme3/gde/core/docs/jme2/terrain-from-float-array.png"> src="nbdocs:/com/jme3/gde/core/docs/jme2/terrain-from-heightmap.png" class="media" alt="" /></a>}</p><p> In a real game, you will want to use more complex and smoother terrains than the simple heightmaps shown here. Heightmaps typically have square sizes of 512x512 or 1024x1024, and contain hundred thousands to 1 million height values. No matter which size, the concept is the same as described here.</p></div><h3><a
</p> name="looking_at_the_heightmap_code">Looking at the Heightmap Code</a></h3><div
class="level3"><p> <a
<p> href="/wiki/lib/exe/fetch.php?hash=e15227&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png"><img
Important things to note: src="/wiki/lib/exe/fetch.php?hash=e15227&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png" class="mediaright" align="right" alt="" width="128" height="128" /></a></p><p> The first step is always to create the heightmap. You can create it yourself in any standard graphic application. Make sure it has the following properties:</p><ul><li
</p> class="level1"><div
<ul> class="li"> The size must be square and a power of two</div><ul><li
<li><div> Low values (e.g. 0 or 50) are valeys.</div> class="level2"><div
</li> class="li"> Examples: 128x128, 256x256, 512x512, 1024x1024</div></li></ul></li><li
<li><div> High values (e.g. 200, 255) are hills. </div> class="level1"><div
</li> class="li"> Color mode: 255 grayscales.</div><ul><li
<li><div> We only specified a few points, and the engine interpolates the rest. Interpolation is more efficient than creating a model with several millions of vertices.</div> class="level2"><div
</li> class="li"> If you supply a color image, it will be converted to grayscale (with possibly weird results).</div></li></ul></li><li
</ul> class="level1"><div
class="li"> Save it as a normal .jpg or .png file</div></li></ul><p> The file <code>mountains512.png</code> that you see here is a typical example of a heightmap.</p><p> Here is how you create the heightmap object in your jME code:</p><ol><li
<p> class="level1"><div
class="li"> Create a Texture object</div></li><li
Now when looking at Java data types to hold an array of floats between 0 and 255, the Image class comes to mind. Storing a terrain&#039;s height values as a grayscale image has one big advantage: The outcome is a very userfriendly, almost topographical, representation of a landscape: class="level1"><div
</p> class="li"> Load your prepared heightmap texture into the texture object</div></li><li
<ul> class="level1"><div
<li><div> Low values (e.g. 0 or 50) are dark gray – these are valleys. </div> class="li"> Create an AbstractHeightmap object from an ImageBasedHeightMap. <br/> ImageBasedHeightMap expects the following parameters:</div><ol><li
</li> class="level2"><div
<li><div> High values (e.g. 200, 255) are light grays – these are hills.</div> class="li"> An <code>ImageToAwt.convert()</code>ed image file</div></li><li
</li> class="level2"><div
</ul> class="li"> A boolean whether you are using 16 bit – here false.</div></li><li
class="level2"><div
<p> class="li"> A boolean whether you are using an alphamap – here true.</div></li></ol></li><li
class="level1"><div
Look at the next screenshot: In the top left you see the 128&times;128 grayscale image (heightmap) that was used as a base to generate the depicted terrain. To make the hilly shape better visible, the mountain tops are colored white, valleys brown, and the areas inbetween green: class="li"> Load the heightmap.</div></li></ol><pre> final Texture heightMapImage = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/mountains512.png&quot;&#41;;
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme2/terrain-from-heightmap.png">}
</p>
<p>
In a real game, you will want to use more complex and smoother terrains than the simple heightmaps shown here. Heightmaps typically have square sizes of 512&times;512 or 1024&times;1024, and contain hundred thousands to 1 million height values. No matter which size, the concept is the same as described here.
</p>
</div>
<h3><a>Looking at the Heightmap Code</a></h3>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
The first step is always to create the heightmap. You can create it yourself in any standard graphic application. Make sure it has the following properties:
</p>
<ul>
<li><div> The size must be square and a power of two</div>
<ul>
<li><div> Examples: 128&times;128, 256&times;256, 512&times;512, 1024&times;1024</div>
</li>
</ul>
</li>
<li><div> Color mode: 255 grayscales. </div>
<ul>
<li><div> If you supply a color image, it will be converted to grayscale (with possibly weird results).</div>
</li>
</ul>
</li>
<li><div> Save it as a normal .jpg or .png file</div>
</li>
</ul>
<p>
The file <code>mountains512.png</code> that you see here is a typical example of a heightmap.
</p>
<p>
Here is how you create the heightmap object in your jME code:
</p>
<ol>
<li><div> Create a Texture object</div>
</li>
<li><div> Load your prepared heightmap texture into the texture object</div>
</li>
<li><div> Create an AbstractHeightmap object from an ImageBasedHeightMap. <br/>
ImageBasedHeightMap expects the following parameters:</div>
<ol>
<li><div> An <code>ImageToAwt.convert()</code>ed image file</div>
</li>
<li><div> A boolean whether you are using 16 bit – here false.</div>
</li>
<li><div> A boolean whether you are using an alphamap – here true.</div>
</li>
</ol>
</li>
<li><div> Load the heightmap.</div>
</li>
</ol>
<pre> final Texture heightMapImage = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/mountains512.png&quot;&#41;;
final AbstractHeightMap heightmap = final AbstractHeightMap heightmap =
new ImageBasedHeightMap&#40; new ImageBasedHeightMap&#40;
ImageToAwt.convert&#40; ImageToAwt.convert&#40;
heightMapImage.getImage&#40;&#41;, false, true, 0&#41;&#41;; heightMapImage.getImage&#40;&#41;, false, true, 0&#41;&#41;;
heightmap.load&#40;&#41;;</pre> heightmap.load&#40;&#41;;</pre></div><h2><a
</div> name="what_is_texture_splatting">What is Texture Splatting?</a></h2><div
class="level2"><p> Texture splatting allows you create a custom textured material and &quot;paint&quot; on it. This is very useful for terrains: As you see in the example here, you can paint a grass texture into the valleys, a dirt texture onto the mountains, and free-form roads inbetween.</p><p> How is it done? We have three texture layers to paint on, <code>m_Tex1</code>, <code>m_Tex2</code> and <code>m_Tex3</code> (these names are found by opening the Terrain.j3md file, under the Material Parameters section; they may be changed) . before we start we have to make a few decisions:</p><ol><li
<h2><a>What is Texture Splatting?</a></h2> class="level1"><div
<div> class="li"> You choose three textures. For example grass.jpg, dirt.jpg, and road.jpg. <a
href="/wiki/lib/exe/fetch.php?hash=b4d15a&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Froad.jpg"><img
<p> src="/wiki/lib/exe/fetch.php?hash=b4d15a&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Froad.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_road.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_road.jpg" width="64" height="64" /></a> <a
href="/wiki/lib/exe/fetch.php?hash=dc84f0&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fdirt.jpg"><img
Texture splatting allows you create a custom textured material and “paint” on it. This is very useful for terrains: As you see in the example here, you can paint a grass texture into the valleys, a dirt texture onto the mountains, and free-form roads inbetween. src="/wiki/lib/exe/fetch.php?hash=dc84f0&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fdirt.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_dirt.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_dirt.jpg" width="64" height="64" /></a> <a
</p> href="/wiki/lib/exe/fetch.php?hash=544a35&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fgrass.jpg"><img
src="/wiki/lib/exe/fetch.php?hash=544a35&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fgrass.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_grass.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_grass.jpg" width="64" height="64" /></a></div></li><li
<p> class="level1"><div
How is it done? We have three texture layers to paint on, <code>m_Tex1</code>, <code>m_Tex2</code> and <code>m_Tex3</code> (these names are found by opening the Terrain.j3md file, under the Material Parameters section; they may be changed) . before we start we have to make a few decisions: class="li"> You will &quot;paint&quot; three texture layers with three colors: Red, blue and, green. We arbitrarily chose that…</div><ol><li
class="level2"><div
</p> class="li"> … everything red will be grass – this goes into layer <code>m_Tex1</code></div></li><li
<ol> class="level2"><div
<li><div> You choose three textures. For example grass.jpg, dirt.jpg, and road.jpg. <img src="/wiki/lib/exe/fetch.php"> <img src="/wiki/lib/exe/fetch.php"> <img src="/wiki/lib/exe/fetch.php"></div> class="li"> … everything green will be dirt – this goes into layer <code>m_Tex2</code></div></li><li
</li> class="level2"><div
<li><div> You will “paint” three texture layers with three colors: Red, blue and, green. We arbitrarily chose that… </div> class="li"> … everything blue will be roads – this goes into layer <code>m_Tex3</code></div></li></ol></li></ol><p> Now we start painting the texture:</p><ol><li
<ol> class="level1"><div
<li><div> … everything red will be grass – this goes into layer <code>m_Tex1</code></div> class="li"> Make a copy of your terrains heightmap, <code>mountains512.png</code>, so you know the shape of the landscape.</div></li><li
</li> class="level1"><div
<li><div> … everything green will be dirt – this goes into layer <code>m_Tex2</code></div> class="li"> Name the copy <code>alphamap.png</code>.</div></li><li
</li> class="level1"><div
<li><div> … everything blue will be roads – this goes into layer <code>m_Tex3</code> </div> class="li"> Open <code>alphamap.png</code> in a graphic editor and switch the image mode to color image.</div><ol><li
</li> class="level2"><div
</ol> class="li"> Paint the black valleys in the image red – this will be the grass.</div></li><li
</li> class="level2"><div
</ol> class="li"> Paint the white hills in shades of green – this will be the dirt of the mountains.</div></li><li
class="level2"><div
<p> class="li"> Paint blue lines where you want roads to cross the landscape.</div></li></ol></li><li
class="level1"><div
Now we start painting the texture: class="li"> The end result should look similar to this:</div></li></ol><p> <a
href="/wiki/lib/exe/fetch.php?hash=e15227&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png"><img
</p> src="/wiki/lib/exe/fetch.php?hash=e15227&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png" class="media" alt="" width="64" height="64" /></a><a
<ol> href="/wiki/lib/exe/fetch.php?hash=7668cb&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Falphamap.png"><img
<li><div> Make a copy of your terrains heightmap, <code>mountains512.png</code>, so you know the shape of the landscape. </div> src="/wiki/lib/exe/fetch.php?hash=7668cb&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Falphamap.png" class="media" alt="" width="64" height="64" /></a></p><p> <em>Note: In the future, the jMonkeyPlatform will take over some of these steps so you don&#039;t have to worry about the details.</em></p></div><h3><a
</li> name="looking_at_the_texturing_code">Looking at the Texturing Code</a></h3><div
<li><div> Name the copy <code>alphamap.png</code>.</div> class="level3"><p> As usual, we create a Material object. We base it on the Material Definition <code>Terrain.j3md</code> that is included in the jME3 framework.</p><pre>Material mat_terrain = new Material&#40;assetManager, &quot;Common/MatDefs/Terrain/Terrain.j3md&quot;&#41;;</pre><p> Now we load four textures into this material. The first one, <code>m_Alpha</code>, is the alphamap that we just created.</p><pre>mat_terrain.setTexture&#40;&quot;m_Alpha&quot;,
</li> assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/alphamap.png&quot;&#41;&#41;;</pre><p> Three other textures are the layers that we have previously decided to paint: grass, dirt, and road. We create texture objects and load the three textures as usual. Note how we assign them to their respective texture layers (m_Tex1, m_Tex2, and m_Tex3) inside the Material!</p><pre> /** 1.2) Add GRASS texture into the red layer (m_Tex1). */
<li><div> Open <code>alphamap.png</code> in a graphic editor and switch the image mode to color image.</div>
<ol>
<li><div> Paint the black valleys in the image red – this will be the grass.</div>
</li>
<li><div> Paint the white hills in shades of green – this will be the dirt of the mountains.</div>
</li>
<li><div> Paint blue lines where you want roads to cross the landscape. </div>
</li>
</ol>
</li>
<li><div> The end result should look similar to this:</div>
</li>
</ol>
<p>
<img src="/wiki/lib/exe/fetch.php"><img src="/wiki/lib/exe/fetch.php">
</p>
<p>
<em>Note: In the future, the jMonkeyPlatform will take over some of these steps so you don&#039;t have to worry about the details.</em>
</p>
</div>
<h3><a>Looking at the Texturing Code</a></h3>
<div>
<p>
As usual, we create a Material object. We base it on the Material Definition <code>Terrain.j3md</code> that is included in the jME3 framework.
</p>
<pre>Material mat_terrain = new Material&#40;assetManager, &quot;Common/MatDefs/Terrain/Terrain.j3md&quot;&#41;;</pre>
<p>
Now we load four textures into this material. The first one, <code>m_Alpha</code>, is the alphamap that we just created.
</p>
<pre>mat_terrain.setTexture&#40;&quot;m_Alpha&quot;,
assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/alphamap.png&quot;&#41;&#41;;</pre>
<p>
Three other textures are the layers that we have previously decided to paint: grass, dirt, and road. We create texture objects and load the three textures as usual. Note how we assign them to their respective texture layers (m_Tex1, m_Tex2, and m_Tex3) inside the Material!
</p>
<pre> /** 1.2) Add GRASS texture into the red layer (m_Tex1). */
Texture grass = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/grass.jpg&quot;&#41;; Texture grass = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/grass.jpg&quot;&#41;;
grass.setWrap&#40;WrapMode.Repeat&#41;; grass.setWrap&#40;WrapMode.Repeat&#41;;
mat_terrain.setTexture&#40;&quot;m_Tex1&quot;, grass&#41;; mat_terrain.setTexture&#40;&quot;m_Tex1&quot;, grass&#41;;
@ -324,200 +197,77 @@ Three other textures are the layers that we have previously decided to paint: gr
Texture rock = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/road.jpg&quot;&#41;; Texture rock = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/road.jpg&quot;&#41;;
rock.setWrap&#40;WrapMode.Repeat&#41;; rock.setWrap&#40;WrapMode.Repeat&#41;;
mat_terrain.setTexture&#40;&quot;m_Tex3&quot;, rock&#41;; mat_terrain.setTexture&#40;&quot;m_Tex3&quot;, rock&#41;;
mat_terrain.setFloat&#40;&quot;m_Tex3Scale&quot;, 128f&#41;;</pre> mat_terrain.setFloat&#40;&quot;m_Tex3Scale&quot;, 128f&#41;;</pre><p> The individual texture scales (e.g. <code>mat_terrain.setFloat(&quot;m_Tex3Scale&quot;, 128f);</code>) depend on the size of the textures you use. You can tell you picked a too small scale if, for example, your road tiles appear like tiny grains of sand, or to big if the blades of grass look like twigs.</p><p> We use <code>setWrap(WrapMode.Repeat)</code> to make the small texture fill the wide area. If the repetition is too visible, try adjusting the Tex*Scale value.</p><p> Later, after we have created the actual terrain object, we must not forgot to set the material on it:</p><pre>terrain.setMaterial&#40;mat_terrain&#41;;</pre></div><h2><a
<p> name="looking_at_the_terrain_generation_code">Looking at the Terrain Generation Code</a></h2><div
The individual texture scales (e.g. <code>mat_terrain.setFloat(“m_Tex3Scale”, 128f);</code>) depend on the size of the textures you use. You can tell you picked a too small scale if, for example, your road tiles appear like tiny grains of sand, or to big if the blades of grass look like twigs. class="level2"><p> Internally, the generated terrain mesh is broken down into tiles and blocks. This is an optimization for culling. You do not need to worry about tiles and blocks too much, just use recommended values for now.</p><p> Let&#039;s assume we want to generate a small 512x512 terrain. We already have created the heightmap object. Here are the steps that we perform everytime we create a new terrain.</p><p> We create a TerrainQuad with the following arguments:</p><ol><li
</p> class="level1"><div
class="li"> Name: E.g. <code>my terrain</code>.</div></li><li
<p> class="level1"><div
We use <code>setWrap(WrapMode.Repeat)</code> to make the small texture fill the wide area. If the repetition is too visible, try adjusting the Tex*Scale value. class="li"> Tile size: We want to create terrain tiles of size 64x64, so we supply 64+1 = 65.</div><ul><li
</p> class="level2"><div
class="li"> In general, 64 is a good value for terrain tiles.</div></li></ul></li><li
<p> class="level1"><div
Later, after we have created the actual terrain object, we must not forgot to set the material on it: class="li"> Block size: Since we prepared a heightmap of size 512x512, we supply 512+1 = 513.</div><ul><li
</p> class="level2"><div
<pre>terrain.setMaterial&#40;mat_terrain&#41;;</pre> class="li"> If the the block size is double the heightmap size (1024+1=1025), you get a stretched out, wider, flatter terrain.</div></li><li
</div> class="level2"><div
class="li"> If the the block size is half the heightmap size (256+1=257), you get a smaller, more detailed terrain.</div></li></ul></li><li
<h2><a>Looking at the Terrain Generation Code</a></h2> class="level1"><div
<div> class="li"> Finally, we supply the 512x512 heightmap object that we have previously created.</div></li></ol><p> Here&#039;s the code:</p><pre>terrain = new TerrainQuad(
<p>
Internally, the generated terrain mesh is broken down into tiles and blocks. This is an optimization for culling. You do not need to worry about tiles and blocks too much, just use recommended values for now.
</p>
<p>
Let&#039;s assume we want to generate a small 512&times;512 terrain. We already have created the heightmap object. Here are the steps that we perform everytime we create a new terrain.
</p>
<p>
We create a TerrainQuad with the following arguments:
</p>
<ol>
<li><div> Name: E.g. <code>my terrain</code>.</div>
</li>
<li><div> Tile size: We want to create terrain tiles of size 64&times;64, so we supply 64+1 = 65.</div>
<ul>
<li><div> In general, 64 is a good value for terrain tiles. </div>
</li>
</ul>
</li>
<li><div> Block size: Since we prepared a heightmap of size 512&times;512, we supply 512+1 = 513.</div>
<ul>
<li><div> If the the block size is double the heightmap size (1024+1=1025), you get a stretched out, wider, flatter terrain.</div>
</li>
<li><div> If the the block size is half the heightmap size (256+1=257), you get a smaller, more detailed terrain.</div>
</li>
</ul>
</li>
<li><div> Finally, we supply the 512&times;512 heightmap object that we have previously created.</div>
</li>
</ol>
<p>
Here&#039;s the code:
</p>
<pre>terrain = new TerrainQuad(
&quot;my terrain&quot;, // name &quot;my terrain&quot;, // name
65, // tile size 65, // tile size
513, // block size 513, // block size
heightmap.getHeightMap()); // heightmap heightmap.getHeightMap()); // heightmap</pre><p> Don&#039;t forget to attach the terrain to the rootNode. You can scale and translate the terrain just like any other Spatial.</p></div><h2><a
</pre> name="looking_at_the_level_of_detail_code">Looking at the Level of Detail Code</a></h2><div
class="level2"><p> jME3 includes an optimization that adjusts the level of detail of the rendered terrain depending on how close or far the camera is.</p><pre> List&lt;Camera&gt; cameras = new ArrayList&lt;Camera&gt;&#40;&#41;;
<p>
Don&#039;t forget to attach the terrain to the rootNode. You can scale and translate the terrain just like any other Spatial.
</p>
</div>
<h2><a>Looking at the Level of Detail Code</a></h2>
<div>
<p>
jME3 includes an optimization that adjusts the level of detail of the rendered terrain depending on how close or far the camera is.
</p>
<pre> List&lt;Camera&gt; cameras = new ArrayList&lt;Camera&gt;&#40;&#41;;
cameras.add&#40;getCamera&#40;&#41;&#41;; cameras.add&#40;getCamera&#40;&#41;&#41;;
TerrainLodControl control = new TerrainLodControl&#40;terrain, cameras&#41;; TerrainLodControl control = new TerrainLodControl&#40;terrain, cameras&#41;;
terrain.addControl&#40;control&#41;;</pre> terrain.addControl&#40;control&#41;;</pre><p> Close parts of the terrain are rendered in full detail. Terrain parts that are further away are not clearly visible anyway, and jME improves performance by rendering them less detailed. This way you can afford to load huge terrains with no penalty caused by invisible details.</p></div><h2><a
<p> name="exercises">Exercises</a></h2><div
Close parts of the terrain are rendered in full detail. Terrain parts that are further away are not clearly visible anyway, and jME improves performance by rendering them less detailed. This way you can afford to load huge terrains with no penalty caused by invisible details. class="level2"></div><h3><a
</p> name="exercise_1texture_layers">Exercise 1: Texture Layers</a></h3><div
class="level3"><p> What happens if you swap two layers, for example <code>m_Tex1</code> and <code>m_Tex2</code>?</p><pre>...
</div>
<h2><a>Exercises</a></h2>
<div>
</div>
<h3><a>Exercise 1: Texture Layers</a></h3>
<div>
<p>
What happens if you swap two layers, for example <code>m_Tex1</code> and <code>m_Tex2</code>?
</p>
<pre>...
mat_terrain.setTexture&#40;&quot;m_Tex2&quot;, grass&#41;; mat_terrain.setTexture&#40;&quot;m_Tex2&quot;, grass&#41;;
... ...
mat_terrain.setTexture&#40;&quot;m_Tex1&quot;, dirt&#41;;</pre> mat_terrain.setTexture&#40;&quot;m_Tex1&quot;, dirt&#41;;</pre><p> It&#039;s easier to swap layers in the code than to change the color in the alphamap.</p></div><h3><a
<p> name="exercise_2randomized_terrains">Exercise 2: Randomized Terrains</a></h3><div
It&#039;s easier to swap layers in the code than to change the color in the alphamap. class="level3"><p> These two lines generate the hightmap from a user defined image:</p><pre>Texture heightMapImage = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/mountains512.png&quot;&#41;;
</p>
</div>
<h3><a>Exercise 2: Randomized Terrains</a></h3>
<div>
<p>
These two lines generate the hightmap from a user defined image:
</p>
<pre>Texture heightMapImage = assetManager.loadTexture&#40;&quot;Textures/Terrain/splat/mountains512.png&quot;&#41;;
heightmap = new ImageBasedHeightMap&#40; heightmap = new ImageBasedHeightMap&#40;
ImageToAwt.convert&#40;heightMapImage.getImage&#40;&#41;, false, true, 0&#41;, 1f&#41;;</pre> ImageToAwt.convert&#40;heightMapImage.getImage&#40;&#41;, false, true, 0&#41;, 1f&#41;;</pre><p> You can also let jME create a random landscape.</p><ol><li
<p> class="level1"><div
class="li"> What result do you get when you replace the two heightmap lines by the following lines and run the sample?</div></li></ol><pre>HillHeightMap heightmap = null;
You can also let jME create a random landscape.
</p>
<ol>
<li><div> What result do you get when you replace the two heightmap lines by the following lines and run the sample?</div>
</li>
</ol>
<pre>HillHeightMap heightmap = null;
&nbsp; &nbsp;
try &#123; try &#123;
heightmap = new HillHeightMap&#40;513, 1000, 50, 100, &#40;byte&#41; 3&#41;; heightmap = new HillHeightMap&#40;513, 1000, 50, 100, &#40;byte&#41; 3&#41;;
&#125; catch &#40;Exception ex&#41; &#123; &#125; catch &#40;Exception ex&#41; &#123;
ex.printStackTrace&#40;&#41;; ex.printStackTrace&#40;&#41;;
&#125;</pre><ol> &#125;</pre><ol><li
<li><div> Change one value at a time and the run the sample again. Note the differences. Can you find out which of the values has which effect on the generated terrain?</div> class="level1"><div
<ul> class="li"> Change one value at a time and the run the sample again. Note the differences. Can you find out which of the values has which effect on the generated terrain?</div><ul><li
<li><div> Which value controls the size? </div> class="level2"><div
<ul> class="li"> Which value controls the size?</div><ul><li
<li><div> What happens if the size is not a square number +1 ?</div> class="level3"><div
</li> class="li"> What happens if the size is not a square number +1 ?</div></li></ul></li><li
</ul> class="level2"><div
</li> class="li"> Which value controls the number of hills generated?</div></li><li
<li><div> Which value controls the number of hills generated?</div> class="level2"><div
</li> class="li"> Which values control the minimum and maximum radius of the hills?</div><ul><li
<li><div> Which values control the minimum and maximum radius of the hills?</div> class="level3"><div
<ul> class="li"> What happens if the minimum is bigger than the maximum?</div></li></ul></li><li
<li><div> What happens if the minimum is bigger than the maximum?</div> class="level2"><div
</li> class="li"> Which value controls the flattening of the hills?</div><ul><li
</ul> class="level3"><div
</li> class="li"> What happens if this value is 1 ?</div></li></ul></li></ul></li></ol><p> Tip: You can keep using the splatted texture from the sample code above. Just don&#039;t be surprised that the textures do not automatically adjust to the randomized landscape.</p></div><h2><a
<li><div> Which value controls the flattening of the hills? </div> name="conclusion">Conclusion</a></h2><div
<ul> class="level2"><p> You have learned how to create terrains that are more efficient as loading a giant model. You are now also able to texture a terrain.</p><p> In the next chapter, you will learn how to add <a
<li><div> What happens if this value is 1 ?</div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">sounds</a> to your game.</p><hr
</li> /><p> See also: <a
</ul> href="/com/jme3/gde/core/docs/jme3/intermediate/terrain_collision.html">Terrain Collision</a></p><div
</li> class="tags"><span> <a
</ul> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>, <a
</li> href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>, <a
</ol> href="/wiki/doku.php/tag:heightmap?do=showtag&amp;tag=tag%3Aheightmap">heightmap</a>, <a
href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
<p> href="/wiki/doku.php/tag:terrain?do=showtag&amp;tag=tag%3Aterrain">terrain</a>, <a
href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a> </span></div></div>
Tip: You can keep using the splatted texture from the sample code above. Just don&#039;t be surprised that the textures do not automatically adjust to the randomized landscape.
</p>
</div>
<h2><a>Conclusion</a></h2>
<div>
<p>
You have learned how to create terrains that are more efficient as loading a giant model. You are now also able to texture a terrain.
</p>
<p>
In the next chapter, you will learn how to add <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">sounds</a> to your game.
</p>
<hr />
<p>
See also: <a href="/com/jme3/gde/core/docs/jme3/intermediate/terrain_collision.html">Terrain Collision</a>
</p>
<div><span>
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner</a>,
<a href="/wiki/doku.php/tag:beginner?do=showtag&amp;tag=tag%3Abeginner">beginner,</a>,
<a href="/wiki/doku.php/tag:heightmap?do=showtag&amp;tag=tag%3Aheightmap">heightmap</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:terrain?do=showtag&amp;tag=tag%3Aterrain">terrain</a>,
<a href="/wiki/doku.php/tag:texture?do=showtag&amp;tag=tag%3Atexture">texture</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_terrain?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_terrain?do=export_xhtmlbody">view online version</a></em></p>

@ -1,187 +1,85 @@
<h1><a
<h1><a>Setting up JME3 in Netbeans 6.x</a></h1> name="setting_up_jme3_in_netbeans_6x">Setting up JME3 in Netbeans 6.x</a></h1><div
<div> class="level1"><p> You are welcome to try out the new jME3, and contribute patches and features! This document shows how to download, set up, build, and run the latest development version from the sources. (As of Spring 2010, we are in alpha.) These instructions work in NetBeans IDE 6 or better.</p><p> Note: In the following, always replace &quot;~&quot; with the path to your home directory.</p></div><h2><a
name="downloading_the_sources">Downloading the Sources</a></h2><div
<p> class="level2"><p> Check out the sources from the repository. (The following NetBeans instructions are equivalent to executing <code>cd ~/NetBeansProjects; svn checkout <a
href="http://jmonkeyengine.googlecode.com/svn/trunk/engine">http://jmonkeyengine.googlecode.com/svn/trunk/engine</a> jme3</code> on the commandline.)</p><ol><li
You are welcome to try out the new jME3, and contribute patches and features! This document shows how to download, set up, build, and run the latest development version from the sources. (As of Spring 2010, we are in alpha.) These instructions work in NetBeans IDE 6 or better. class="level1"><div
</p> class="li"> In NetBeans go to Team &gt; Subversion &gt; Checkout</div><ol><li
class="level2"><div
<p> class="li"> Repository <acronym
Note: In the following, always replace ”~” with the path to your home directory. title="Uniform Resource Locator">URL</acronym>: <code><a
</p> href="https://jmonkeyengine.googlecode.com/svn">https://jmonkeyengine.googlecode.com/svn</a></code></div></li><li
class="level2"><div
</div> class="li"> You can leave user/pw blank for anonymous access.</div></li></ol></li><li
class="level1"><div
<h2><a>Downloading the Sources</a></h2> class="li"> Click Next</div><ol><li
<div> class="level2"><div
class="li"> Repository Folders: <code>trunk/engine</code></div></li><li
<p> class="level2"><div
class="li"> Enable the checkbox to Skip &quot;engine&quot; and only checkout its contents.</div></li><li
Check out the sources from the repository. (The following NetBeans instructions are equivalent to executing <code>cd ~/NetBeansProjects; svn checkout <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine"><param name="text" value="<html><u>http://jmonkeyengine.googlecode.com/svn/trunk/engine</u></html>"><param name="textColor" value="blue"></object> jme3</code> on the commandline.) class="level2"><div
class="li"> Local Folder: <code>~/NetBeansProjects/jme3</code></div></li></ol></li><li
</p> class="level1"><div
<ol> class="li"> Click Finish and wait.</div></li></ol><p> The jme3 project opens in the Project window. It already includes a working ANT build script for building and running.</p><p> Look into the Libraries node and confirm that the project depends on the following libraries in the classpath:</p><pre>jME3-natives-joal.jar lwjgl.jar gluegen-rt.jar
<li><div> In NetBeans go to Team &gt; Subversion &gt; Checkout</div>
<ol>
<li><div> Repository <acronym title="Uniform Resource Locator">URL</acronym>: <code><object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://jmonkeyengine.googlecode.com/svn"><param name="text" value="<html><u>https://jmonkeyengine.googlecode.com/svn</u></html>"><param name="textColor" value="blue"></object></code></div>
</li>
<li><div> You can leave user/pw blank for anonymous access. </div>
</li>
</ol>
</li>
<li><div> Click Next</div>
<ol>
<li><div> Repository Folders: <code>trunk/engine</code></div>
</li>
<li><div> Enable the checkbox to Skip “engine” and only checkout its contents.</div>
</li>
<li><div> Local Folder: <code>~/NetBeansProjects/jme3</code></div>
</li>
</ol>
</li>
<li><div> Click Finish and wait.</div>
</li>
</ol>
<p>
The jme3 project opens in the Project window. It already includes a working ANT build script for building and running.
</p>
<p>
Look into the Libraries node and confirm that the project depends on the following libraries in the classpath:
</p>
<pre>
jME3-natives-joal.jar lwjgl.jar gluegen-rt.jar
jME3-lwjgl-natives.jar jinput.jar swing-layout-1.0.4.jar jME3-lwjgl-natives.jar jinput.jar swing-layout-1.0.4.jar
j-ogg-oggd.jar vecmath.jar stack-alloc.jar j-ogg-oggd.jar vecmath.jar stack-alloc.jar
j-ogg-vorbisd.jar asm-all-3.1.jar jbullet.jar j-ogg-vorbisd.jar asm-all-3.1.jar jbullet.jar
jheora-jst-debug-0.6.0.jar xmlpull.xpp3-1.1.4c.jar jheora-jst-debug-0.6.0.jar xmlpull.xpp3-1.1.4c.jar
nifty*.jar eventbus-1.4.jar nifty*.jar eventbus-1.4.jar</pre></div><h3><a
</pre> name="optionalsetting_up_android_support">Optional: Setting up Android Support</a></h3><div
class="level3"><p> Work in progress …</p><p> A jme3 application can either be deployed to the desktop (as Java Swing application) and web browser (as JNLP/WebStart or Applet), or to an Android phone. While the former is the default, switching to Android deployment can be done in a few steps.</p><ol><li
</div> class="level1"><div
class="li"> Open Project Properties, go to Sources category.</div></li><li
<h3><a>Optional: Setting up Android Support</a></h3> class="level1"><div
<div> class="li"> At Source Packages Folders, click &quot;Add Folder&quot;.</div><ul><li
class="level2"><div
<p> class="li"> Add <code>src/android/</code></div></li><li
class="level2"><div
Work in progress … class="li"> Remove <code>src/desktop</code></div></li><li
</p> class="level2"><div
class="li"> Remove <code>src/desktop_fx</code></div></li></ul></li><li
<p> class="level1"><div
A jme3 application can either be deployed to the desktop (as Java Swing application) and web browser (as JNLP/WebStart or Applet), or to an Android phone. While the former is the default, switching to Android deployment can be done in a few steps. class="li"> build.xml…</div></li></ol></div><h2><a
name="build_and_run">Build and Run</a></h2><div
</p> class="level2"><p> That&#039;s it!</p><ol><li
<ol> class="level1"><div
<li><div> Open Project Properties, go to Sources category.</div> class="li"> Right-click the jme3 project node and &quot;Clean and Build&quot; the project.</div></li><li
</li> class="level1"><div
<li><div> At Source Packages Folders, click “Add Folder”. </div> class="li"> In the Projects window, browse to the <code>src/test/jme3test</code> folder.</div></li><li
<ul> class="level1"><div
<li><div> Add <code>src/android/</code></div> class="li"> Right-click e.g. the file <code>src/test/jme3test/model/TestHoverTank.java</code> and choose &quot;Run&quot; to run a sample.</div><ol><li
</li> class="level2"><div
<li><div> Remove <code>src/desktop</code></div> class="li"> In the sample application, use the mouse and the AWSD keys to move around the test object.</div></li><li
</li> class="level2"><div
<li><div> Remove <code>src/desktop_fx</code></div> class="li"> Press escape to quit the sample application.</div></li></ol></li></ol><p> Sample code for cool features is in the <code>src/test/jme3test</code> folder. A sample game can be found in <code>src/games/jme3game/cubefield/CubeField.java</code>.</p><p> Tips:</p><ul><li
</li> class="level1"><div
</ul> class="li"> To run runnable classes from the Projects window, right-click and choose Run.</div></li><li
</li> class="level1"><div
<li><div> build.xml…</div> class="li"> To run any runnable class that is open in the editor, press shift-F6.</div></li></ul></div><h2><a
</li> name="optionaljavadoc_popups_and_source_navigation_in_netbeans">Optional: Javadoc Popups and Source Navigation in NetBeans</a></h2><div
</ol> class="level2"><p> If you are working on the jme3 sources:</p><ol><li
class="level1"><div
</div> class="li"> In the Projects window, right-click the jme3 project and choose Generate Javadoc. Wait.</div></li><li
class="level1"><div
<h2><a>Build and Run</a></h2> class="li"> Confirm in the Files window that the javadoc has been created in <code>~/NetBeansProjects/jme3/dist/javadoc</code></div></li><li
<div> class="level1"><div
class="li"> In the editor, place the caret in a jme class and press ctrl-space to view javadoc.</div></li></ol><p> If you are working on a game project that depends on jme3:</p><ol><li
<p> class="level1"><div
class="li"> First follow the previous tip. (In the future, we may offer jme javadoc as download instead.)</div></li><li
That&#039;s it! class="level1"><div
</p> class="li"> In your game project, right-click the Libraries node and choose &quot;Properties&quot;.</div></li><li
<ol> class="level1"><div
<li><div> Right-click the jme3 project node and “Clean and Build” the project.</div> class="li"> In the Library properties, select jme3.jar and click the Edit button.</div><ol><li
</li> class="level2"><div
<li><div> In the Projects window, browse to the <code>src/test/jme3test</code> folder. </div> class="li"> For the Javadoc field, browse to <code>~/NetBeansProjects/jme3/dist/javadoc</code>. Check &quot;as relative path&quot; and click select.</div></li><li
</li> class="level2"><div
<li><div> Right-click e.g. the file <code>src/test/jme3test/model/TestHoverTank.java</code> and choose “Run” to run a sample. </div> class="li"> For the Sources field, browse to <code>~/NetBeansProjects/jme3/src</code>. Check &quot;as relative path&quot; and click select.</div></li><li
<ol> class="level2"><div
<li><div> In the sample application, use the mouse and the AWSD keys to move around the test object.</div> class="li"> Click OK.</div></li></ol></li><li
</li> class="level1"><div
<li><div> Press escape to quit the sample application.</div> class="li"> In the editor, place the caret in a jme class and press ctrl-space to view javadoc. Ctrl-click any jme3 method to jump to its definition in the sources.</div></li></ol><p> This tip works for any third-party JAR library that you use. (You may have to download the javadoc/sources from their home page separately).</p><hr
</li> /><p> Sources used: <a
</ol> href="http://code.google.com/p/jmonkeyengine/wiki/BuildJme3">BuildJme3</a>, <a
</li> href="http://www.jmonkeyengine.com/forum/index.php?topic=13108.0">netbeans tutorial from forum</a></p></div>
</ol>
<p>
Sample code for cool features is in the <code>src/test/jme3test</code> folder. A sample game can be found in <code>src/games/jme3game/cubefield/CubeField.java</code>.
</p>
<p>
Tips:
</p>
<ul>
<li><div> To run runnable classes from the Projects window, right-click and choose Run.</div>
</li>
<li><div> To run any runnable class that is open in the editor, press shift-F6.</div>
</li>
</ul>
</div>
<h2><a>Optional: Javadoc Popups and Source Navigation in NetBeans</a></h2>
<div>
<p>
If you are working on the jme3 sources:
</p>
<ol>
<li><div> In the Projects window, right-click the jme3 project and choose Generate Javadoc. Wait.</div>
</li>
<li><div> Confirm in the Files window that the javadoc has been created in <code>~/NetBeansProjects/jme3/dist/javadoc</code></div>
</li>
<li><div> In the editor, place the caret in a jme class and press ctrl-space to view javadoc.</div>
</li>
</ol>
<p>
If you are working on a game project that depends on jme3:
</p>
<ol>
<li><div> First follow the previous tip. (In the future, we may offer jme javadoc as download instead.)</div>
</li>
<li><div> In your game project, right-click the Libraries node and choose “Properties”.</div>
</li>
<li><div> In the Library properties, select jme3.jar and click the Edit button.</div>
<ol>
<li><div> For the Javadoc field, browse to <code>~/NetBeansProjects/jme3/dist/javadoc</code>. Check “as relative path” and click select.</div>
</li>
<li><div> For the Sources field, browse to <code>~/NetBeansProjects/jme3/src</code>. Check “as relative path” and click select.</div>
</li>
<li><div> Click OK.</div>
</li>
</ol>
</li>
<li><div> In the editor, place the caret in a jme class and press ctrl-space to view javadoc. Ctrl-click any jme3 method to jump to its definition in the sources. </div>
</li>
</ol>
<p>
This tip works for any third-party JAR library that you use. (You may have to download the javadoc/sources from their home page separately).
</p>
<hr />
<p>
Sources used: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/wiki/BuildJme3"><param name="text" value="<html><u>BuildJme3</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/forum/index.php?topic=13108.0"><param name="text" value="<html><u>netbeans tutorial from forum</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:build_jme3_sources_with_netbeans?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:build_jme3_sources_with_netbeans?do=export_xhtmlbody">view online version</a></em></p>

@ -1,41 +1,10 @@
<h1><a
<h1><a>Multithreading Bullet Physics in jme3</a></h1> name="multithreading_bullet_physics_in_jme3">Multithreading Bullet Physics in jme3</a></h1><div
<div> class="level1"></div><h2><a
name="introduction">Introduction</a></h2><div
</div> class="level2"><p> Since bullet is not (yet) multithreaded or GPU accelerated the jME3 implementation allows to run each physics space on a separate thread that is executed in parallel to rendering.</p></div><h2><a
name="how_is_it_handled_in_jme3_and_bullet">How is it handled in jme3 and bullet?</a></h2><div
<h2><a>Introduction</a></h2> class="level2"><p> A SimpleApplication with a BulletAppState allows setting the threading type via</p><pre>setThreadingType(ThreadingType type);</pre><p> where ThreadingType can be either SEQUENTIAL or PARALLEL.</p><p> In the simpleInitApp() method:</p><pre>bulletAppState = new BulletAppState&#40;&#41;;
<div>
<p>
Since bullet is not (yet) multithreaded or GPU accelerated the jME3 implementation allows to run each physics space on a separate thread that is executed in parallel to rendering.
</p>
</div>
<h2><a>How is it handled in jme3 and bullet?</a></h2>
<div>
<p>
A SimpleApplication with a BulletAppState allows setting the threading type via
</p>
<pre>setThreadingType(ThreadingType type);</pre>
<p>
where ThreadingType can be either SEQUENTIAL or PARALLEL.
</p>
<p>
In the simpleInitApp() method:
</p>
<pre>bulletAppState = new BulletAppState&#40;&#41;;
bulletAppState.setThreadingType&#40;BulletAppState.ThreadingType.PARALLEL&#41;; bulletAppState.setThreadingType&#40;BulletAppState.ThreadingType.PARALLEL&#41;;
stateManager.attach&#40;bulletAppState&#41;;</pre> stateManager.attach&#40;bulletAppState&#41;;</pre><p> The physics update happens in parallel to rendering, after the users changes have been made in the update() call. This way the loop logic is still maintained: the user can set and change values in physics and scenegraph objects before render() and physicsUpdate() are called in parallel.</p></div>
<p>
The physics update happens in parallel to rendering, after the users changes have been made in the update() call. This way the loop logic is still maintained: the user can set and change values in physics and scenegraph objects before render() and physicsUpdate() are called in parallel.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:bullet_multithreading?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:bullet_multithreading?do=export_xhtmlbody">view online version</a></em></p>

@ -1,277 +1,334 @@
<h1><a
<h1><a>JME 3 - API / Feature Mapping</a></h1> name="jme_3_-_api_feature_mapping">JME 3 - API / Feature Mapping</a></h1><div
<div> class="level1"><p> This page provides a quick answer to the questions <strong>&quot;I want my game to do <em>X</em>, where do I find that in jME 3 ??&quot;</strong> <br/> <br/> Knowing exactly what you are looking for allows you to search more efficiently, find documentation more quickly, and ask clearer questions on the <a
href="http://www.jmonkeyengine.com/forum/">support forum</a>. This intermediate page assumes that you already went through the beginner tutorials. Feel free to add APIs, tutorials and javadoc links that helped you understand and use a feature!</p></div><h2><a
<p> name="applications_and_scenegraph">Applications and SceneGraph</a></h2><div
class="level2"><div
This page provides a quick answer to the questions <strong>“I want my game to do <em>X</em>, where do I find that in jME 3 ??”</strong> class="table sectionedit1"><table
</p> class="inline"><tr
class="row0"><th
<p> class="col0">How do I…?</th><th
Knowing exactly what you are looking for allows you to search more efficiently, find documentation more quickly, and ask clearer questions on the <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.jmonkeyengine.com/forum/"><param name="text" value="<html><u>support forum</u></html>"><param name="textColor" value="blue"></object>. This intermediate page assumes that you already went through the beginner tutorials. Feel free to add APIs, tutorials and javadoc links that helped you understand and use a feature! class="col1">Use this JME 3 Feature!</th><th
</p> class="col2">Learn more here…</th></tr><tr
class="row1"><th
</div> class="col0">Start with a preconfigured game</th><td
class="col1">com.jme3.app.SimpleApplication</td><td
<h2><a>Applications and SceneGraph</a></h2> class="col2"><a
<div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html">Hello SimpleApplication</a></td></tr><tr
<table> class="row2"><th
<tr> class="col0">Make an object appear in the scene</th><td
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> class="col1">Attach nodes and geometries to the rootNode: rootNode.attachChild(geo); <br/> com.jme3.scene.Node, com.jme3.scene.Geometry <br/> node.setCullHint(CullHint.Never);</td><td
</tr> class="col2"><a
<tr> href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/> <a
<th>Start with a preconfigured game </th><td>com.jme3.app.SimpleApplication </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html">Hello SimpleApplication</a> </td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a></td></tr><tr
<tr> class="row3"><th
<th>Make an object appear in the scene</th><td>Attach nodes and geometries to the rootNode: rootNode.attachChild(geo); <br/> class="col0">Make an object disappear from the scene</th><td
com.jme3.scene.Node, com.jme3.scene.Geometry <br/> class="col1">Detach nodes and geometries from the rootNode: rootNode.detachChild(geo); <br/> node.setCullHint(CullHint.Always);</td><td
node.setCullHint(CullHint.Never); </td><td><a href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/> <a
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> </td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a></td></tr><tr
<tr> class="row4"><th
<th>Make an object disappear from the scene</th><td>Detach nodes and geometries from the rootNode: rootNode.detachChild(geo); <br/> class="col0">Use third-person view</th><td
node.setCullHint(CullHint.Always);</td><td><a href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/> class="col1">Use default camera <code>cam</code> <br/> com.jme3.renderer.Camera</td><td
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> class="col2"> ChaseCam WIP</td></tr><tr
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> </td> class="row5"><th
</tr> class="col0">Use first-person view</th><td
<tr> class="col1">Use camera <code>flyCam</code> <br/> com.jme3.input.FlyByCamera</td><td
<th>Use third-person view </th><td>Use default camera <code>cam</code> <br/> class="col2"><a
com.jme3.renderer.Camera </td><td> ChaseCam WIP </td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a></td></tr><tr
</tr> class="row6"><th
<tr> class="col0">Increase camera speed</th><td
<th>Use first-person view </th><td>Use camera <code>flyCam</code> <br/> class="col1"><code>flyCam.setMoveSpeed(50f);</code></td><td
com.jme3.input.FlyByCamera </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a> </td> class="col2"> –</td></tr><tr
</tr> class="row7"><th
<tr> class="col0">Only draw outline of the scene</th><td
<th>Increase camera speed </th><td><code>flyCam.setMoveSpeed(50f);</code> </td><td></td> class="col1">Use a wireframe material, e.g. for debugging.</td><td
</tr> class="col2"> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/debugging.html">Debugging</a></td></tr><tr
<th>Only draw outline of the scene </th><td>Use a wireframe material, e.g. for debugging. </td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/debugging.html">Debugging</a> </td> class="row8"><th
</tr> class="col0">Change the background color</th><td
<tr> class="col1">Call viewPort.setBackgroundColor(ColorRGBA.Blue);</td><td
<th>Change the background color </th><td>Call viewPort.setBackgroundColor(ColorRGBA.Blue); </td><td>N/A </td> class="col2">N/A</td></tr><tr
</tr> class="row9"><th
<tr> class="col0">Customize the applicaton class</th><td
<th>Customize the applicaton class </th><td>Extend com.jme3.app.SimpleApplication (or com.jme3.app.Application) and set Application Settings </td><td><a href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> <br/> class="col1">Extend com.jme3.app.SimpleApplication (or com.jme3.app.Application) and set Application Settings</td><td
<a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> </td> class="col2"><a
</tr> href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a></td></tr><tr
<th>Disable the logger output</th><td>Logger.getLogger(””).setLevel(Level.SEVERE); <br/> class="row10"><th
java.util.logging.*</td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">Logging</a> </td> class="col0">Disable the logger output</th><td
</tr> class="col1">Logger.getLogger(&quot;&quot;).setLevel(Level.SEVERE); <br/> java.util.logging.*</td><td
</table> class="col2"> <a
href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">Logging</a></td></tr></table></div></div><h2><a
</div> name="creation_and_manipulation_of_objects">Creation and Manipulation of Objects</a></h2><div
class="level2"><div
<h2><a>Creation and Manipulation of Objects</a></h2> class="table sectionedit2"><table
<div> class="inline"><tr
<table> class="row0"><th
<tr> class="col0">How do I…?</th><th
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> class="col1">Use this JME 3 Feature!</th><th
</tr> class="col2">Learn more here…</th></tr><tr
<tr> class="row1"><th
<th>Make simple shapes like cubes, spheres </th><td>com.jme3.scene.Geometry, com.jme3.scene.shape.* </td><td> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>, <a href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a> <br/> class="col0">Make simple shapes like cubes, spheres</th><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestCylinder.java"><param name="text" value="<html><u>TestCylinder.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestBox.java"><param name="text" value="<html><u>TestBox.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestSphere.java"><param name="text" value="<html><u>TestSphere.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col1">com.jme3.scene.Geometry, com.jme3.scene.shape.*</td><td
</tr> class="col2"> <a
<tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a>, <a
<th>Create a 3-D model </th><td>Create the model in a 3-D mesh editor (for example Blender) and export it as Ogre <acronym title="Extensible Markup Language">XML</acronym> mesh. </td><td><object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://blender.org"><param name="text" value="<html><u>Download Blender</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro"><param name="text" value="<html><u>Blender tutorial</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.ogre3d.org/wiki/index.php/Blender_Exporter"><param name="text" value="<html><u>Blender-to-Ogre plugin</u></html>"><param name="textColor" value="blue"></object> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a> <br/> <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D Models</a> </td> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestCylinder.java">TestCylinder.java</a>, <a
</tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestBox.java">TestBox.java</a>, <a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/shape/TestSphere.java">TestSphere.java</a></td></tr><tr
<th>Load a 3-D model </th><td>Import asset as Ogre <acronym title="Extensible Markup Language">XML</acronym> mesh. <br/> class="row2"><th
jMonkeyPlatform: Converting Ogre to j3o binary format speeds up model loading. <br/> class="col0">Create a 3-D model</th><td
AssetManager, com.jme3.scene.plugins.ogre.*, com.jme3.scene.Geometry </td><td> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> class="col1">Create the model in a 3-D mesh editor (for example Blender) and export it as Ogre <acronym
<a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">jMonkeyPlatform j3o converter</a> <br/> title="Extensible Markup Language">XML</acronym> mesh.</td><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestOgreLoading.java"><param name="text" value="<html><u>TestOgreLoading.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/export/TestOgreConvert.java"><param name="text" value="<html><u>TestOgreConvert.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col2"><a
</tr> href="http://blender.org">Download Blender</a>, <a
<tr> href="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro">Blender tutorial</a>, <a
<th>Move or turn or resize an object </th><td>Use transformations: geo.setLocalTranslation(), geo.rotate(), geo.scale() <br/> href="http://www.ogre3d.org/wiki/index.php/Blender_Exporter">Blender-to-Ogre plugin</a> <br/> <a
geo.updateGeometricState(); </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/3d_models.html">3D Models</a></td></tr><tr
<a href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a> </td> class="row3"><th
</tr> class="col0">Load a 3-D model</th><td
<tr> class="col1">Import asset as Ogre <acronym
<th>Concatenate transformations (e.g. rotations around several axes in one step) </th><td>com.jme3.math.Quaternion, slerp() <br/> title="Extensible Markup Language">XML</acronym> mesh. <br/> jMonkeyPlatform: Converting Ogre to j3o binary format speeds up model loading. <br/> AssetManager, com.jme3.scene.plugins.ogre.*, com.jme3.scene.Geometry</td><td
com.jme3.math.Transform, interpolateTransforms() </td><td><a href="/com/jme3/gde/core/docs/jme2/rotate.html">rotate</a>, <a href="/com/jme3/gde/core/docs/jme2/rotate_about_a_point.html">rotate_about_a_point</a>, <a href="/com/jme3/gde/core/docs/jme2/quaternion.html">quaternion</a>, <a href="/com/jme3/gde/core/docs/jme3/math_for_dummies.html">math_for_dummies</a> </td> class="col2"> <a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">jMonkeyPlatform j3o converter</a> <br/> <a
<th>Make an object move by itself </th><td>Change the geo&#039;s translation in the update phase of the main loop. Or remote-control the motion using cinematics. <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestOgreLoading.java">TestOgreLoading.java</a>, <a
com.jme3.scene.Geometry, setLocalTranslation(), setWalkDirection() for physical objects. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Loop</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/export/TestOgreConvert.java">TestOgreConvert.java</a></td></tr><tr
<a href="/com/jme3/gde/core/docs/jme3/advanced/update_loop.html">Update Loop</a> <br/> class="row4"><th
<a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> <br/> class="col0">Move or turn or resize an object</th><td
<a href="/com/jme3/gde/core/docs/jme3/advanced/cinematics.html">Cinematics</a> <br/> class="col1">Use transformations: geo.setLocalTranslation(), geo.rotate(), geo.scale() <br/> geo.updateGeometricState();</td><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/material/TestBumpModel.java"><param name="text" value="<html><u>TestBumpModel.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestOgreLoading.java"><param name="text" value="<html><u>TestOgreLoading.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col2"><a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a></td></tr><tr
<th>Manipulate the color or shininess of an object </th><td>Materials, AssetManager </td><td> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> class="row5"><th
<a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <br/> class="col0">Concatenate transformations (e.g. rotations around several axes in one step)</th><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestNormalMapping.java"><param name="text" value="<html><u>TestNormalMapping.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestSphere.java"><param name="text" value="<html><u>TestSphere.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col1">com.jme3.math.Quaternion, slerp() <br/> com.jme3.math.Transform, interpolateTransforms()</td><td
</tr> class="col2"><a
<tr> href="/com/jme3/gde/core/docs/jme2/rotate.html">rotate</a>, <a
<th>Manipulate the surface of an object (wood vs stone vs metal etc) </th><td>Textures, AssetManager. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> href="/com/jme3/gde/core/docs/jme2/rotate_about_a_point.html">rotate_about_a_point</a>, <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <br/> href="/com/jme3/gde/core/docs/jme2/quaternion.html">quaternion</a>, <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/material/TestSimpleBumps.java"><param name="text" value="<html><u>TestSimpleBumps.java</u></html>"><param name="textColor" value="blue"></object> <br/> href="/com/jme3/gde/core/docs/jme3/math_for_dummies.html">math_for_dummies</a></td></tr><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://wiki.blender.org/index.php/Doc:Manual/Textures/Maps/Bump_and_Normal_Maps"><param name="text" value="<html><u>Blender: Creating Bump Maps and Normal maps</u></html>"><param name="textColor" value="blue"></object> </td> class="row6"><th
</tr> class="col0">Make an object move by itself</th><td
<tr> class="col1">Change the geo&#039;s translation in the update phase of the main loop. Or remote-control the motion using cinematics. <br/> com.jme3.scene.Geometry, setLocalTranslation(), setWalkDirection() for physical objects.</td><td
<th>Make objects cast a shadow </th><td>com.jme3.shadow.BasicShadowRenderer, com.jme3.light.DirectionalLight <br/> class="col2"><a
setShadowMode() </td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/light_and_shadow.html">Light and Shadow</a> <br/> href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Loop</a> <br/> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/jme3test/fx/TestEverything.java"><param name="text" value="<html><u>TestEverything.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/jme3test/light/TestShadow.java"><param name="text" value="<html><u>TestShadow.java</u></html>"><param name="textColor" value="blue"></object> </td> href="/com/jme3/gde/core/docs/jme3/advanced/update_loop.html">Update Loop</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/cinematics.html">Cinematics</a> <br/> <a
<th>Render transparent objects (glass, window panes, water, tree leaves) </th><td>Assign a transparent texture to the Material and set material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/material/TestBumpModel.java">TestBumpModel.java</a>, <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> </td> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestOgreLoading.java">TestOgreLoading.java</a></td></tr><tr
</tr> class="row7"><th
<tr> class="col0">Manipulate the color or shininess of an object</th><td
<th>Force or disable Backface culling </th><td>com.jme3.material.RenderState.FaceCullMode: Back, Front, FrontAndBack, Off <br/> class="col1">Materials, AssetManager</td><td
e.g. material.getAdditionalRenderState(). setFaceCullMode(FaceCullMode.FrontAndBack);</td><td>N/A </td> class="col2"> <a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <br/> <a
<th>Make procedural or custom shapes </th><td>com.jme3.scene.Mesh </td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">Custom Meshes</a> </td> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/light/TestNormalMapping.java">TestNormalMapping.java</a>, <a
</tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/TestSphere.java">TestSphere.java</a></td></tr><tr
<tr> class="row8"><th
<th>Keep my models, textures, sound files in order </th><td>Put all assets in subdirectories of a project directory named <code>assets</code> and use the assetManager to load them. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>, <a href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a> </td> class="col0">Manipulate the surface of an object (wood vs stone vs metal etc)</th><td
</tr> class="col1 leftalign">Textures, AssetManager.</td><td
<tr> class="col2"><a
<th>Identify Named Sub-Mesh in Model</th><td>Geometry result = spatial.getName().startsWith(name);</td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a></td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <br/> <a
</table> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/material/TestSimpleBumps.java">TestSimpleBumps.java</a> <br/> <a
href="http://wiki.blender.org/index.php/Doc:Manual/Textures/Maps/Bump_and_Normal_Maps">Blender: Creating Bump Maps and Normal maps</a></td></tr><tr
</div> class="row9"><th
class="col0">Make objects cast a shadow</th><td
<h2><a>Actions, Interactions, Physics</a></h2> class="col1">com.jme3.shadow.BasicShadowRenderer, com.jme3.light.DirectionalLight <br/> setShadowMode()</td><td
<div> class="col2"> <a
<table> href="/com/jme3/gde/core/docs/jme3/advanced/light_and_shadow.html">Light and Shadow</a> <br/> <a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/jme3test/fx/TestEverything.java">TestEverything.java</a>, <a
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/jme3test/light/TestShadow.java">TestShadow.java</a></td></tr><tr
</tr> class="row10"><th
<tr> class="col0">Render transparent objects (glass, window panes, water, tree leaves)</th><td
<th>Implement the game logic and game mechanics </th><td> Use Controls to define behaviours of types of Spatials. Use Application States to implement global behaviours. Use the <code>simpleUpdate()</code> loop for the remaining tests and interactions. Use Cinematics to remote-control objects in scenes. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Loop</a> <br/> class="col1">Assign a transparent texture to the Material and set material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);</td><td
<a href="/com/jme3/gde/core/docs/jme3/advanced/update_loop.html">Update Loop</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> <br/> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a> <br/> <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></td></tr><tr
<a href="/com/jme3/gde/core/docs/jme3/advanced/cinematics.html">Cinematics</a> </td> class="row11"><th
</tr> class="col0">Force or disable Backface culling</th><td
<tr> class="col1">com.jme3.material.RenderState.FaceCullMode: Back, Front, FrontAndBack, Off <br/> e.g. material.getAdditionalRenderState(). setFaceCullMode(FaceCullMode.FrontAndBack);</td><td
<th>Let players interact by pressing keyboard keys </th><td>com.jme3.input.KeyInput, com.jme3.input.binding.BindingListener </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> <br/> class="col2">N/A</td></tr><tr
<a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input Handling</a> </td> class="row12"><th
</tr> class="col0">Make procedural or custom shapes</th><td
<tr> class="col1">com.jme3.scene.Mesh</td><td
<th>Let players interact by clicking, e.g. picking up objects, opening doors, shooting </th><td>Intersect a Ray from the player with the Bounding Volume of the target: com.jme3.bounding.*, com.jme3.math.Ray, com.jme3.collision.CollisionResults. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/advanced/collision_and_intersection.html">Collision and Intersection</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html">Custom Meshes</a></td></tr><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bounding/TestRayCollision.java"><param name="text" value="<html><u>TestRayCollision.java</u></html>"><param name="textColor" value="blue"></object> </td> class="row13"><th
</tr> class="col0">Keep my models, textures, sound files in order</th><td
<tr> class="col1">Put all assets in subdirectories of a project directory named <code>assets</code> and use the assetManager to load them.</td><td
<th>Animate objects and characters </th><td>Create an animated OgreMesh model with Bones in a 3-D editor (e.g. Blender). <br/> class="col2"><a
com.jme3.animation.* </td><td> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a> <br/> href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a>, <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/animation.html">Animation</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a></td></tr><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/anim/"><param name="text" value="<html><u>animation</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://wiki.blender.org/index.php/Doc:Tutorials/Animation/BSoD/Character_Animation"><param name="text" value="<html><u>Blender animation tutorial</u></html>"><param name="textColor" value="blue"></object> </td> class="row14"><th
</tr> class="col0">Identify Named Sub-Mesh in Model</th><td
<tr> class="col1">Geometry result = spatial.getName().startsWith(name);</td><td
<th>Keep players walking on floors of scenes </th><td>Collision detection – raycasting or physics. </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a> </td> href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a></td></tr></table></div></div><h2><a
</tr> name="actions_interactions_physics">Actions, Interactions, Physics</a></h2><div
<tr> class="level2"><div
<th>Prevent players from walking through walls in scenes </th><td>Collision detection using physics and bounding volumes. <br/> class="table sectionedit3"><table
com.jme3.bullet.*, CapsuleCollisionShape / CompoundCollisionShape, PhysicsCharacterNode / PhysicsNode <br/> class="inline"><tr
geo.setModelBound(); geo.updateModelBound(); </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a> <br/> class="row0"><th
<a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a> </td> class="col0">How do I…?</th><th
</tr> class="col1">Use this JME 3 Feature!</th><th
<tr> class="col2">Learn more here…</th></tr><tr
<th>Let balls, cars, etc bounce off obstacles and roll on floors </th><td>Use physics nodes and bounding volumes: com.jme3.bounding.*, com.jme3.bullet.collisions, com.jme3.bullet.nodes.PhysicsNode etc <br/> class="row1"><th
geo.setModelBound(); geo.updateModelBound(); </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a> <br/> class="col0">Implement the game logic and game mechanics</th><td
<a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a> <br/> class="col1"> Use Controls to define behaviours of types of Spatials. Use Application States to implement global behaviours. Use the <code>simpleUpdate()</code> loop for the remaining tests and interactions. Use Cinematics to remote-control objects in scenes.</td><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestSimplePhysics.java"><param name="text" value="<html><u>TestSimplePhysics.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet"><param name="text" value="<html><u>more samples</u></html>"><param name="textColor" value="blue"></object> </td> class="col2"><a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_main_event_loop.html">Hello Loop</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/update_loop.html">Update Loop</a> <br/> <a
<th>Steer cars, motorcycles, etc </th><td>Use physics characters and vehicles: com.jme3.bullet.*, PhysicsCharacterNode, PhysicsVehicleNode </td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/vehicles.html">Vehicles</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> <br/> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java"><param name="text" value="<html><u>TestFancyCar.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCharacter.java"><param name="text" value="<html><u>TestPhysicsCharacter.java</u></html>"><param name="textColor" value="blue"></object> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> <br/> <a
(Press HUJK keys to steer, spacebar to jump.) </td> href="/com/jme3/gde/core/docs/jme3/advanced/cinematics.html">Cinematics</a></td></tr><tr
</tr> class="row2"><th
<tr> class="col0">Let players interact by pressing keyboard keys</th><td
<th>Let an object swing like a pendulum or chain links </th><td>Use physics joints: com.jme3.bullet.joints.PhysicsHingeJoint </td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">Hinges and Joints</a> <br/> class="col1">com.jme3.input.KeyInput, com.jme3.input.binding.BindingListener</td><td
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsHingeJoint.java"><param name="text" value="<html><u>TestPhysicsHingeJoint.java</u></html>"><param name="textColor" value="blue"></object> <br/> class="col2"><a
(Press HK keys to turn, spacebar to swing.) </td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">Input Handling</a></td></tr><tr
</table> class="row3"><th
class="col0">Let players interact by clicking, e.g. picking up objects, opening doors, shooting</th><td
</div> class="col1">Intersect a Ray from the player with the Bounding Volume of the target: com.jme3.bounding.*, com.jme3.math.Ray, com.jme3.collision.CollisionResults.</td><td
class="col2"><a
<h2><a>GUI Display</a></h2> href="/com/jme3/gde/core/docs/jme3/beginner/hello_picking.html">Hello Picking</a> <br/> <a
<div> href="/com/jme3/gde/core/docs/jme3/advanced/collision_and_intersection.html">Collision and Intersection</a> <br/> <a
<table> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bounding/TestRayCollision.java">TestRayCollision.java</a></td></tr><tr
<tr> class="row4"><th
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> class="col0">Animate objects and characters</th><td
</tr> class="col1">Create an animated OgreMesh model with Bones in a 3-D editor (e.g. Blender). <br/> com.jme3.animation.*</td><td
<tr> class="col2"> <a
<th>Get rid of default debug display (fps etc) in SimpleApplication </th><td>guiNode.detachAllChildren(); </td><td>N/A </td> href="/com/jme3/gde/core/docs/jme3/beginner/hello_animation.html">Hello Animation</a> <br/> <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/animation.html">Animation</a> <br/> <a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/model/anim/">animation</a>, <a
<th>Display text (score, health), flat mini-maps or status icons </th><td>Attach a picture to the orthogonal <code>guiNode</code> to create a heads-up display (<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikipedia.org/wiki/HUD_%28video_gaming%29"><param name="text" value="<html><u>HUD</u></html>"><param name="textColor" value="blue"></object>). <br/> href="http://wiki.blender.org/index.php/Doc:Tutorials/Animation/BSoD/Character_Animation">Blender animation tutorial</a></td></tr><tr
com.jme3.font.*, com.jme3.ui.Picture. guiNode.attachChild() </td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a> <br/> class="row5"><th
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/gui/TestOrtho.java"><param name="text" value="<html><u>TestOrtho.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/gui/TestBitmapFont.java"><param name="text" value="<html><u>TestBitmapFont.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col0">Keep players walking on floors of scenes</th><td
</tr> class="col1">Collision detection – raycasting or physics.</td><td
<tr> class="col2"><a
<th>Display buttons to let the player switch between the game/settings/score screens </th><td>Nifty <acronym title="Graphical User Interface">GUI</acronym> </td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a> <br/> href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a> <br/> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java"><param name="text" value="<html><u>TestNiftyGui.java</u></html>"><param name="textColor" value="blue"></object> </td> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a></td></tr><tr
</tr> class="row6"><th
</table> class="col0">Prevent players from walking through walls in scenes</th><td
class="col1">Collision detection using physics and bounding volumes. <br/> com.jme3.bullet.*, CapsuleCollisionShape / CompoundCollisionShape, PhysicsCharacterNode / PhysicsNode <br/> geo.setModelBound(); geo.updateModelBound();</td><td
</div> class="col2"><a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_collision.html">Hello Collision</a> <br/> <a
<h2><a>Environment Effects: Sound, Landscape</a></h2> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a></td></tr><tr
<div> class="row7"><th
<table> class="col0">Let balls, cars, etc bounce off obstacles and roll on floors</th><td
<tr> class="col1">Use physics nodes and bounding volumes: com.jme3.bounding.*, com.jme3.bullet.collisions, com.jme3.bullet.nodes.PhysicsNode etc <br/> geo.setModelBound(); geo.updateModelBound();</td><td
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> class="col2"><a
</tr> href="/com/jme3/gde/core/docs/jme3/beginner/hello_physics.html">Hello Physics</a> <br/> <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">Physics</a> <br/> <a
<th>Play sounds and noises </th><td>AudioRenderer, Listener, and AudioNode from com.jme3.audio.* </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestSimplePhysics.java">TestSimplePhysics.java</a>, <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">Audio</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet">more samples</a></td></tr><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/audio"><param name="text" value="<html><u>audio</u></html>"><param name="textColor" value="blue"></object> </td> class="row8"><th
</tr> class="col0">Steer cars, motorcycles, etc</th><td
<tr> class="col1">Use physics characters and vehicles: com.jme3.bullet.*, PhysicsCharacterNode, PhysicsVehicleNode</td><td
<th>Simulate fire, flames, smoke, explosions, swarms, dust, magic spells </th><td>Use particle emitters: com.jme3.effect.EmitterSphereShape, com.jme3.effect.ParticleEmitter </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/vehicles.html">Vehicles</a> <br/> <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestFancyCar.java">TestFancyCar.java</a>, <a
<a href="/com/jme3/gde/core/docs/jme3/advanced/effects_overview.html">Effects Overview</a> <br/> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsCharacter.java">TestPhysicsCharacter.java</a> <br/> (Press HUJK keys to steer, spacebar to jump.)</td></tr><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/fx/TestExplosionEffect.java"><param name="text" value="<html><u>TestExplosionEffect.java</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/fx/TestParticleEmitter.java"><param name="text" value="<html><u>TestParticleEmitter.java</u></html>"><param name="textColor" value="blue"></object> </td> class="row9"><th
</tr> class="col0">Let an object swing like a pendulum or chain links</th><td
<tr> class="col1">Use physics joints: com.jme3.bullet.joints.PhysicsHingeJoint</td><td
<th>Simulate water, waves, reflections </th><td>com.jme3.water.* </td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/water.html">Water</a> <br/> class="col2"><a
<a href="/com/jme3/gde/core/docs/jme3/advanced/post-processor_water.html">Post-Processor Water</a> <br/> href="/com/jme3/gde/core/docs/jme3/advanced/hinges_and_joints.html">Hinges and Joints</a> <br/> <a
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSceneWater.java"><param name="text" value="<html><u>TestSceneWater.java</u></html>"><param name="textColor" value="blue"></object> </td> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/bullet/TestPhysicsHingeJoint.java">TestPhysicsHingeJoint.java</a> <br/> (Press HK keys to turn, spacebar to swing.)</td></tr></table></div></div><h2><a
</tr> name="gui_display">GUI Display</a></h2><div
<tr> class="level2"><div
<th>Generate a terrain </th><td>com.jme3.terrain.* </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a> <br/> class="table sectionedit4"><table
<a href="/com/jme3/gde/core/docs/jme3/advanced/terrain.html">Terrain</a> <br/> class="inline"><tr
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/terrain/TestTerrain.java"><param name="text" value="<html><u>TestTerrain.java</u></html>"><param name="textColor" value="blue"></object> </td> class="row0"><th
</tr> class="col0">How do I…?</th><th
<tr> class="col1">Use this JME 3 Feature!</th><th
<th>Simulate a sky </th><td>rootNode.attachChild(SkyFactory.createSky( assetManager, “Textures/Sky/Bright/BrightSky.dds”, false)); <br/> class="col2">Learn more here…</th></tr><tr
skyGeo.setQueueBucket(Bucket.Sky) </td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">Sky</a> <br/> class="row1"><th
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestCubeMap.java"><param name="text" value="<html><u>TestCubeMap.java</u></html>"><param name="textColor" value="blue"></object> </td> class="col0">Get rid of default debug display (fps, stats etc) in SimpleApplication</th><td
</tr> class="col1"> app.setDisplayFps(false); <br/> app.setDisplayStatView(false);</td><td
</table> class="col2"> N/A</td></tr><tr
class="row2"><th
</div> class="col0">Display text (score, health), flat mini-maps or status icons</th><td
class="col1">Attach a picture to the orthogonal <code>guiNode</code> to create a heads-up display (<a
<h2><a>Back-End Properties</a></h2> href="http://en.wikipedia.org/wiki/HUD_%28video_gaming%29">HUD</a>). <br/> com.jme3.font.*, com.jme3.ui.Picture. guiNode.attachChild()</td><td
<div> class="col2"> <a
<table> href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a> <br/> <a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/gui/TestOrtho.java">TestOrtho.java</a>, <a
<th>How do I…? </th><th>Use this JME 3 Feature! </th><th>Learn more here… </th> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/gui/TestBitmapFont.java">TestBitmapFont.java</a></td></tr><tr
</tr> class="row3"><th
<tr> class="col0">Display buttons to let the player switch between the game/settings/score screens</th><td
<th>Check graphic card capabilities</th><td>com.jme3.renderer.Caps <br/> class="col1">Nifty <acronym
Collection&lt;Caps&gt; caps = renderer.getCaps(); <br/> title="Graphical User Interface">GUI</acronym></td><td
Logger.getLogger(HelloJME3.class.getName()).log(Level.INFO, “Caps: {0}” + caps.toString()); </td><td> N/A </td> class="col2"><a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/nifty_gui.html">Nifty GUI</a> <br/> <a
<tr> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/niftygui/TestNiftyGui.java">TestNiftyGui.java</a></td></tr></table></div></div><h2><a
<th>Optimize the heck out of the scenegraph</th><td>jme3tools.optimize.GeometryBatchFactory <br/> name="environment_effectssound_landscape">Environment Effects: Sound, Landscape</a></h2><div
GeometryBatchFactory.optimize(rootNode); </td><td> N/A </td> class="level2"><div
</tr> class="table sectionedit5"><table
</table> class="inline"><tr
class="row0"><th
</div> class="col0">How do I…?</th><th
class="col1">Use this JME 3 Feature!</th><th
class="col2">Learn more here…</th></tr><tr
class="row1"><th
class="col0">Play sounds and noises</th><td
class="col1 leftalign">AudioRenderer, Listener, and AudioNode from com.jme3.audio.*</td><td
class="col2"><a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_audio.html">Hello Audio</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">Audio</a> <br/> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/audio">audio</a></td></tr><tr
class="row2"><th
class="col0">Simulate fire, flames, smoke, explosions, swarms, dust, magic spells</th><td
class="col1">Use particle emitters: <br/> com.jme3.effect.EmitterSphereShape, <br/> com.jme3.effect.ParticleEmitter</td><td
class="col2"><a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_effects.html">Hello Effects</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters.html">Particle Emitters</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.html">Bloom and Glow</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/effects_overview.html">Effects Overview</a> <br/> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/fx/TestExplosionEffect.java">TestExplosionEffect.java</a>, <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/fx/TestParticleEmitter.java">TestParticleEmitter.java</a></td></tr><tr
class="row3"><th
class="col0">Simulate water, waves, reflections</th><td
class="col1">com.jme3.water.*</td><td
class="col2"> <a
href="/com/jme3/gde/core/docs/jme3/advanced/water.html">Water</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/post-processor_water.html">Post-Processor Water</a> <br/> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestSceneWater.java">TestSceneWater.java</a></td></tr><tr
class="row4"><th
class="col0">Generate a terrain</th><td
class="col1">com.jme3.terrain.*</td><td
class="col2"><a
href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a> <br/> <a
href="/com/jme3/gde/core/docs/jme3/advanced/terrain.html">Terrain</a> <br/> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/terrain/TestTerrain.java">TestTerrain.java</a></td></tr><tr
class="row5"><th
class="col0">Simulate a sky</th><td
class="col1"><pre>rootNode.attachChild&#40;SkyFactory.createSky&#40; assetManager,
&quot;Textures/Sky/Bright/BrightSky.dds&quot;, false&#41;&#41;;
skyGeo.setQueueBucket&#40;Bucket.Sky&#41; </pre></td><td
class="col2"><a
href="/com/jme3/gde/core/docs/jme3/advanced/sky.html">Sky</a> <br/> <a
href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestCubeMap.java">TestCubeMap.java</a></td></tr></table></div></div><h2><a
name="back-end_properties">Back-End Properties</a></h2><div
class="level2"><div
class="table sectionedit6"><table
class="inline"><tr
class="row0"><th
class="col0">How do I…?</th><th
class="col1">Use this JME 3 Feature!</th><th
class="col2">Learn more here…</th></tr><tr
class="row1"><th
class="col0">Check graphic card capabilities</th><td
class="col1">com.jme3.renderer.Caps <br/> Collection&lt;Caps&gt; caps = renderer.getCaps(); <br/> Logger.getLogger(HelloJME3.class.getName()).log(Level.INFO, &quot;Caps: {0}&quot; + caps.toString());</td><td
class="col2"> N/A</td></tr><tr
class="row2"><th
class="col0">Optimize the heck out of the scenegraph</th><td
class="col1">jme3tools.optimize.GeometryBatchFactory <br/> GeometryBatchFactory.optimize(rootNode);</td><td
class="col2"> N/A</td></tr></table></div></div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:api_feature_mapping?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:api_feature_mapping?do=export_xhtmlbody">view online version</a></em></p>

@ -1,106 +1,77 @@
<h1><a
<h1><a>jME3 Application Display Settings</a></h1> name="jme3_application_display_settings">jME3 Application Display Settings</a></h1><div
<div> class="level1"><p> Every class that extends jme3.app.Application (or jme3.app.SimpleApplication) has properties that can be configured by customizing a <code>com.jme3.system.AppSettings</code> object. Configure the settings before you call <code>app.start()</code> on the application object. If you change display settings during runtime, call <code>app.restart()</code> to make them take effect.</p><p> <strong>Note:</strong> Other runtime settings are covered in <a
href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a>.</p></div><h2><a
<p> name="code_sample">Code Sample</a></h2><div
class="level2"><pre>AppSettings settings = new AppSettings&#40;true&#41;;
Every class that extends jme3.app.Application (or jme3.app.SimpleApplication) has properties that can be configured by customizing a <code>com.jme3.system.AppSettings</code> object. Configure the settings before you call <code>app.start()</code> on the application object. If you change display settings during runtime, call <code>app.restart()</code> to make them take effect.
</p>
<p>
<strong>Note:</strong> Other runtime settings are covered in <a href="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a>.
</p>
</div>
<h2><a>Code Sample</a></h2>
<div>
<pre>AppSettings settings = new AppSettings&#40;true&#41;;
settings.setRenderer&#40;AppSettings.LWJGL_OPENGL3&#41;; settings.setRenderer&#40;AppSettings.LWJGL_OPENGL3&#41;;
Application app = new Application&#40;&#41;; Application app = new Application&#40;&#41;;
app.setSettings&#40;settings&#41;; app.setSettings&#40;settings&#41;;
app.start&#40;&#41;;</pre> app.start&#40;&#41;;</pre><p> Set the boolean in the AppSettings contructor to true if you want to keep the default settings for everything that you do not specify. Set this parameter to false if you want to specify each property yourself (you&#039;ll get an exception if you missed one).</p><p> Use <code>app.setShowSettings(false);</code> to disable the default settings-window at startup.</p></div><h2><a
<p> name="properties">Properties</a></h2><div
Set the boolean in the AppSettings contructor to true if you want to keep the default settings for everything that you do not specify. Set this parameter to false if you want to specify each property yourself (you&#039;ll get an exception if you missed one). class="level2"><div
</p> class="table sectionedit1"><table
class="inline"><tr
<p> class="row0"><th
Use <code>app.setShowSettings(false);</code> to disable the default settings-window at startup. class="col0">Property</th><th
</p> class="col1">Dscription</th><th
class="col2">Default</th></tr><tr
</div> class="row1"><td
class="col0">setRenderer(AppSettings.LWJGL_OPENGL2) <br/> setRenderer(AppSettings.LWJGL_OPENGL3)</td><td
<h2><a>Properties</a></h2> class="col1">Switch Video Renderer</td><td
<div> class="col2">OpenGL 2</td></tr><tr
<table> class="row2"><td
<tr> class="col0">setAudioRenderer(AppSettings.LWJGL_OPENAL) <br/> setAudioRenderer(AppSettings.LWJGL_JOAL)</td><td
<th>Property</th><th>Dscription</th><th>Default</th> class="col1">Switch Audio Renderer</td><td
</tr> class="col2">OpenAL</td></tr><tr
<tr> class="row3"><td
<td>setRenderer(AppSettings.LWJGL_OPENGL2) <br/> class="col0">setBitsPerPixel(8)</td><td
setRenderer(AppSettings.LWJGL_OPENGL3)</td><td>Switch Video Renderer</td><td>OpenGL 2</td> class="col1">Set color depth. <br/> 1 = black and white, 2 bit = gray, <br/> 4 = 16 colors, 8 = 256 colors, 24 or 32 = &quot;truecolor&quot;.</td><td
</tr> class="col2">24</td></tr><tr
<tr> class="row4"><td
<td>setAudioRenderer(AppSettings.LWJGL_OPENAL) <br/> class="col0">setFrequency(60)</td><td
setAudioRenderer(AppSettings.LWJGL_JOAL)</td><td>Switch Audio Renderer</td><td>OpenAL</td> class="col1">The screen frequency (refresh rate of the graphics card), usually 60 or 75 fps.</td><td
</tr> class="col2">60 fps</td></tr><tr
<tr> class="row5"><td
<td>setBitsPerPixel(8)</td><td>Set color depth. <br/> class="col0">setFramerate(60)</td><td
1 = black and white, 2 bit = gray, <br/> class="col1">How often per second the engine should try to refresh the frame. For the release, usually 60 fps. Can be lower (59-30) for FX-intensive games. Do not set to a higher value than the screen frequency.</td><td
4 = 16 colors, 8 = 256 colors, 24 or 32 = “truecolor”.</td><td>24</td> class="col2">-1 (auto)</td></tr><tr
</tr> class="row6"><td
<tr> class="col0">setFullscreen(true)</td><td
<td>setFrequency(60)</td><td>The screen frequency (refresh rate of the graphics card), usually 60 or 75 fps.</td><td>60 fps</td> class="col1">Set this to true to make the display fill the whole screen; you need to provide a key that calls app.stop() to exit the fullscreen view gracefully (default: escape). <br/> Set it to false to play the game in a normal window of its own.</td><td
</tr> class="col2">False (windowed)</td></tr><tr
<tr> class="row7"><td
<td>setFramerate(60)</td><td>How often per second the engine should try to refresh the frame. For the release, usually 60 fps. Can be lower (59-30) for FX-intensive games. Do not set to a higher value than the screen frequency.</td><td>-1 (auto)</td> class="col0">setHeight(480), setWidth(640) <br/> setResolution(640,480)</td><td
</tr> class="col1">Two equivalent ways of setting the display resolution.</td><td
<tr> class="col2">640x480 pixels</td></tr><tr
<td>setFullscreen(true)</td><td>Set this to true to make the display fill the whole screen; you need to provide a key that calls app.stop() to exit the fullscreen view gracefully (default: escape). <br/> class="row8"><td
Set it to false to play the game in a normal window of its own.</td><td>False (windowed)</td> class="col0">setSamples(4)</td><td
</tr> class="col1">Set multisampling to 0 to switch antialiasing off (harder edges, faster.) <br/> Set multisampling to 2 or 4 to activate antialising (softer edges, may be slower.) <br/> Depending on your graphic card, you may be able to go set multisampling to 8, 16, or 32 samples.</td><td
<tr> class="col2">0</td></tr><tr
<td>setHeight(480), setWidth(640) <br/> class="row9"><td
setResolution(640,480)</td><td>Two equivalent ways of setting the display resolution.</td><td>640&times;480 pixels</td> class="col0">setVSync(true)</td><td
</tr> class="col1">Set vertical syncing to true to time the frame buffer to coincide with the refresh interval of the screen: Prevents page tearing, but slower; recommened for release. <br/> Set to false to deactivate vertical syncing (faster, but possible page tearing artifacts); can be deactivated during development.</td><td
<tr> class="col2">false</td></tr><tr
<td>setSamples(4)</td><td>Set multisampling to 0 to switch antialiasing off (harder edges, faster.) <br/> class="row10"><td
Set multisampling to 2 or 4 to activate antialising (softer edges, may be slower.) <br/> class="col0">useInput(false)</td><td
Depending on your graphic card, you may be able to go set multisampling to 8, 16, or 32 samples.</td><td>0</td> class="col1">Respond to user input by mouse and keyboard. Can be deactivated for use cases where you only display a 3D scene on the canvas without any interaction.</td><td
</tr> class="col2">true</td></tr><tr
<tr> class="row11"><td
<td>setVSync(true)</td><td>Set vertical syncing to true to time the frame buffer to coincide with the refresh interval of the screen: Prevents page tearing, but slower; recommened for release. <br/> class="col0">useJoysticks(true)</td><td
Set to false to deactivate vertical syncing (faster, but possible page tearing artifacts); can be deactivated during development.</td><td>false</td> class="col1">Activate optional joystick support</td><td
</tr> class="col2">false</td></tr><tr
<tr> class="row12"><td
<td>useInput(false)</td><td>Respond to user input by mouse and keyboard. Can be deactivated for use cases where you only display a 3D scene on the canvas without any interaction.</td><td>true</td> class="col0">setSettingsDialogImage(&quot;/path/in/assets.png&quot;)</td><td
</tr> class="col1">A custom image to display when the settings dialog is shown.</td><td
<tr> class="col2">&quot;/com/jme3/app/Monkey.png&quot;</td></tr><tr
<td>useJoysticks(true)</td><td>Activate optional joystick support</td><td>false</td> class="row13"><td
</tr> class="col0">setTitle(&quot;My Game&quot;)</td><td
<tr> class="col1">This string will be visible in the titlebar, unless the window is fullscreen.</td><td
<td>setSettingsDialogImage(”/path/in/assets.png”)</td><td>A custom image to display when the settings dialog is shown.</td><td>”/com/jme3/app/Monkey.png”</td> class="col2">&quot;jMonkey Engine 3.0&quot;</td></tr></table></div></div><h2><a
</tr> name="methods">Methods</a></h2><div
<tr> class="level2"><p> An AppSettings object also supports the following methods:</p><ul><li
<td>setTitle(“My Game”)</td><td>This string will be visible in the titlebar, unless the window is fullscreen.</td><td>“jMonkey Engine 3.0”</td> class="level1"><div
</tr> class="li"> Use <code>settings.save(outstream)</code> and <code>settings.load(instream)</code> to save and load your settings via standard java.io serialization.</div></li><li
</table> class="level1"><div
class="li"> Use <code>newSettings.copyFrom(oldSettings)</code> to copy a settings object.</div></li></ul></div>
</div>
<h2><a>Methods</a></h2>
<div>
<p>
An AppSettings object also supports the following methods:
</p>
<ul>
<li><div> Use <code>settings.save(outstream)</code> and <code>settings.load(instream)</code> to save and load your settings via standard java.io serialization.</div>
</li>
<li><div> Use <code>newSettings.copyFrom(oldSettings)</code> to copy a settings object.</div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:appsettings?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:appsettings?do=export_xhtmlbody">view online version</a></em></p>

@ -1,508 +1,271 @@
<h1><a
<h1><a>Best Practices For jME3 Developers</a></h1> name="best_practices_for_jme3_developers">Best Practices For jME3 Developers</a></h1><div
<div> class="level1"><p> A collection of recommendations and expert tips. Feel free to add your own!</p><p> If you are a beginner, you should first <a
href="http://www.gamedevlessons.com/?page=free">read some</a> <a
<p> href="http://gamasutra.com/">articles about</a> <a
href="http://www.google.com/search?q=3d+game+development">game development</a>. We cannot cover all general tips here.</p></div><h2><a
A collection of recommendations and expert tips. Feel free to add your own! name="requirements_gathering">Requirements Gathering</a></h2><div
</p> class="level2"><p> As a quick overview, answer yourself the following questions:</p><ul><li
class="level1"><div
<p> class="li"> Motivation</div><ul><li
If you are a beginner, you should first <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.gamedevlessons.com/?page=free"><param name="text" value="<html><u>read some</u></html>"><param name="textColor" value="blue"></object> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://gamasutra.com/"><param name="text" value="<html><u>articles about</u></html>"><param name="textColor" value="blue"></object> game development. We cannot cover all general tips here. class="level2"><div
</p> class="li"> Sum up your game idea in one sentence. If you can&#039;t, it&#039;s too complicated.</div></li><li
class="level2"><div
</div> class="li"> Who&#039;s the target group? Why would they choose your game over the million others that exist?</div></li></ul></li><li
class="level1"><div
<h2><a>Requirements Gathering</a></h2> class="li"> Game type</div><ul><li
<div> class="level2"><div
class="li"> Point of view (camera)? What character(s) does the player control (if any)?</div></li><li
<p> class="level2"><div
class="li"> Time- or turn-based?</div></li><li
As a quick overview, answer yourself the following questions: class="level2"><div
class="li"> Genre, setting, background story? (If applicable)</div></li></ul></li><li
</p> class="level1"><div
<ul> class="li"> Gameplay</div><ul><li
<li><div> Motivation</div> class="level2"><div
<ul> class="li"> What is the start state, what is the end state?</div></li><li
<li><div> Sum up your game idea in one sentence. If you can&#039;t, it&#039;s too complicated.</div> class="level2"><div
</li> class="li"> What resources does the player manage? How are resources gained, transformed, spent? E.g. speed, gold, health, &quot;points&quot;.</div></li><li
<li><div> Who&#039;s the target group? Why would they choose your game over the million others that exist? </div> class="level2"><div
</li> class="li"> How does the player interact? I.e. rules, challenges, game mechanics.</div></li><li
</ul> class="level2"><div
</li> class="li"> What state is considered winning, and what losing?</div></li></ul></li><li
<li><div> Game type</div> class="level1"><div
<ul> class="li"> Media assets</div><ul><li
<li><div> Point of view (camera)? What character(s) does the player control (if any)? </div> class="level2"><div
</li> class="li"> Which media will you need? How will you get this content? <br/> models, terrains; materials, textures; audio, sound, music; video; spoken/written dialog; levels, quests, stories; AI scripts</div></li></ul></li><li
<li><div> Time- or turn-based? </div> class="level1"><div
</li> class="li"> Interface</div><ul><li
<li><div> Genre, setting, background story? (If applicable)</div> class="level2"><div
</li> class="li"> Can you achieve a high degree of input control? Even minor navigation and interaction glitches make the game unsolvable.</div></li><li
</ul> class="level2"><div
</li> class="li"> Clearly reflect current status, and changes in game states. E.g. health/damage.</div></li><li
<li><div> Gameplay</div> class="level2"><div
<ul> class="li"> Clearly reward good moves and discourage bad ones.</div></li></ul></li></ul></div><h2><a
<li><div> What is the start state, what is the end state? </div> name="planning_development_milestones">Planning Development Milestones</a></h2><div
</li> class="level2"><ol><li
<li><div> What resources does the player manage? How are resources gained, transformed, spent? E.g. speed, gold, health, “points”.</div> class="level1"><div
</li> class="li"> Pre-Alpha</div><ol><li
<li><div> How does the player interact? I.e. rules, challenges, game mechanics.</div> class="level2"><div
</li> class="li"> Lay out the overall application flow using mock-ups or stock art. E.g. switching between intro screen / options screen / game screen.</div></li><li
<li><div> What state is considered winning, and what losing?</div> class="level2"><div
</li> class="li"> Get one typical level working. E.g. if it&#039;s a &quot;Jump&#039;n&#039;Run&quot;, jumping and running must work before you can call it an Alpha.</div></li></ol></li><li
</ul> class="level1"><div
</li> class="li"> Alpha</div><ol><li
<li><div> Media assets</div> class="level2"><div
<ul> class="li"> Run internal tests, debug, optimize (issue tracker).</div></li><li
<li><div> Which media will you need? How will you get this content? <br/> class="level2"><div
models, terrains; materials, textures; audio, sound, music; video; spoken/written dialog; levels, quests, stories; AI scripts </div> class="li"> Replace all mock-ups with first drafts of real media and levels.</div></li><li
</li> class="level2"><div
</ul> class="li"> Feature Freeze: Avoid a bottomless pit of side effects causing new issues.</div></li></ol></li><li
</li> class="level1"><div
<li><div> Interface </div> class="li"> Beta</div><ol><li
<ul> class="level2"><div
<li><div> Can you achieve a high degree of input control? Even minor navigation and interaction glitches make the game unsolvable.</div> class="li"> Have external people review and &quot;beta test&quot; it (issue tracker).</div></li><li
</li> class="level2"><div
<li><div> Clearly reflect current status, and changes in game states. E.g. health/damage.</div> class="li"> Even out the kinks in the code – don&#039;t add any more new features.</div></li><li
</li> class="level2"><div
<li><div> Clearly reward good moves and discourage bad ones.</div> class="li"> Fill in all final content.</div></li></ol></li><li
</li> class="level1"><div
</ul> class="li"> Gamma, Delta = Release Candidates</div><ol><li
</li> class="level2"><div
</ul> class="li"> Last chance to find a horrible bug.</div></li></ol></li><li
class="level1"><div
</div> class="li"> Omega = Final Release</div></li></ol><p> How you actually name or number these milestones is up to you. People use the words &quot;milestone&quot;, Greek letters, version numbers, or combinations thereof.</p><p> Every milestone is made up of a development phase and a test phase. Here are some best practices:</p></div><h2><a
name="development_phase">Development Phase</a></h2><div
<h2><a>Planning Development Milestones</a></h2> class="level2"></div><h3><a
<div> name="where_to_start">Where to Start?</a></h3><div
<ol> class="level3"><p> You have a list of features that you want in game, but which one do you implement first? You will keep adding features to a project that grows more and more complex, how can you minimize the amount of rewriting required?</p><ol><li
<li><div> Pre-Alpha</div> class="level1"><div
<ol> class="li"> Start with implementing the most complex game feature first – the one that imposes most constraints on the structure of your project (for instance, networking.)</div></li><li
<li><div> Lay out the overall application flow using mock-ups or stock art. E.g. switching between intro screen / options screen / game screen.</div> class="level1"><div
</li> class="li"> Make sure the game&#039;s high-level frame (screen switching, networking, physics, loading/saving) is sound and solid before you implement low-level details of gameplay.</div></li><li
<li><div> Get one typical level working. E.g. if it&#039;s a “Jump&#039;n&#039;Run”, jumping and running must work before you can call it an Alpha.</div> class="level1"><div
</li> class="li"> Only add one larger feature at a time. If there are complex interactions (such as &quot;networking + physics&quot;), start with a small test case (&quot;one cube&quot;) and work your way up, don&#039;t start with a whole scene.</div></li><li
</ol> class="level1"><div
</li> class="li"> Test for side-effects on existing code before you add the next feature.</div></li></ol><p> Acknowledge whether you want a feature because it is necessary for gameplay, or simply because &quot;everyone else has it&quot;. Successful high-performance games are the ones where someone made smart decisions what to keep and what to drop.</p><ul><li
<li><div> Alpha</div> class="level1"><div
<ol> class="li"> Example: Everybody wants &quot;full physics, AI, post-rendering effects, and multi-player networking&quot;… Make certain you truly understand what that requires (e.g. client-server synchonization)! Your goal should be to bring out the essence of your game idea, don&#039;t water down gameplay but attempting to make it &quot;do everything, but better&quot;.</div></li></ul></div><h3><a
<li><div> Run internal tests, debug, optimize (issue tracker).</div> name="extend_simpleapplication">Extend SimpleApplication</a></h3><div
</li> class="level3"><p> Typically, developers extend a custom class off of jME3&#039;s com.jme3.app.SimpleApplication (or even com.jme3.app.Application). For a racing game you would create a different base game class than for a space game or a shooter.</p><ol><li
<li><div> Replace all mock-ups with first drafts of real media and levels.</div> class="level1"><div
</li> class="li"> Create a generic game class for your custom game:</div><ol><li
<li><div> Feature Freeze: Avoid a bottomless pit of side effects causing new issues.</div> class="level3"><div
</li> class="li"> Create a jME3-based project with all necessary JARs on the classpath.</div></li><li
</ol> class="level3"><div
</li> class="li"> Create a class in this package that extends SimpleApplication, name it something like <code>my.company.MyBaseGame.java</code>.</div></li><li
<li><div> Beta</div> class="level3"><div
<ol> class="li"> Implement all generic features that the game type needs in the MyBaseGame class. For example methods for loading and saving scenes, physics, networking and multi-player logon screen, switching to settings screen, etc.</div></li><li
<li><div> Have external people review and “beta test” it (issue tracker).</div> class="level3"><div
</li> class="li"> Include generic assets (company logo, reusable <acronym
<li><div> Even out the kinks in the code – don&#039;t add any more new features.</div> title="Graphical User Interface">GUI</acronym> elements in your company style, etc) in the MyBaseGame&#039;s assets directory.</div></li></ol></li><li
</li> class="level2"><div
<li><div> Fill in all final content.</div> class="li"> Create your actual game, e.g. a shooter:</div><ol><li
</li> class="level3"><div
</ol> class="li"> Create another jME3-based project, and a new package for the game itself, e.g. <code>my.company.zombieshooter.MyGame.java</code>.</div></li><li
</li> class="level3"><div
<li><div> Gamma, Delta = Release Candidates</div> class="li"> Add MyBaseGame.jar to the classpath of MyGame.java.</div></li><li
<ol> class="level3"><div
<li><div> Last chance to find a horrible bug.</div> class="li"> Make MyGame.java&#039;s main class extend MyBaseGame.</div></li><li
</li> class="level3"><div
</ol> class="li"> The specific assets (scenes, models) of this game go into MyGame&#039;s own assets folder.</div></li><li
</li> class="level3"><div
<li><div> Omega = Final Release</div> class="li"> Now implement this game&#039;s mechanics and levels – without having to worry about logon&amp;settings screens and all the other features that you already dealt with in MyBaseGame.</div></li></ol></li></ol></div><h3><a
</li> name="controls_and_appstates_--_the_smart_way_to_implement_game_logic">Controls and AppStates -- The Smart Way to Implement Game Logic</a></h3><div
</ol> class="level3"><p> As your jME3-based application grows more advanced, you may find yourself putting more and more tests in the simpleUpdate() loop, and passing around lots of object references. Don&#039;t implement game behaviour by copying and pasting boilerplate code! It is a best practice to move game behaviour into classes of their own. In jME3 these classes are Controls and AppStates.</p><ul><li
class="level1"><div
<p> class="li"> Use Controls to implement the behaviour of types of game entities. A character control that defines how this type of Spatials moves, an animation control that plays animations in this type of Spatial&#039;s model, etc.</div></li><li
class="level1"><div
How you actually name or number these milestones is up to you. People use the words “milestone”, Greek letters, version numbers, or combinations thereof. class="li"> Use AppStates to implement global game behaviour: A physics manager, a custom artificial intelligence manager, etc.</div></li><li
</p> class="level1"><div
class="li"> Use the simpleUpdate() loop for the remaining &quot;one-off&quot; tests and interactions.</div></li></ul><p> Both classes automatically hook into the main update loop. Instead of remote controlling game entities via simpleUpdate(), you define the desired behaviour in the update methods of custom Controls and AppStates. You then add Controls to Spatials, and AppStates to the application, and jME3 will automatically trigger the update methods. This cleans up your simpleUpdate() loop code considerably.</p><p> Learn more about <a
<p> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> and <a
Every milestone is made up of a development phase and a test phase. Here are some best practices: href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a>.</p></div><h3><a
</p> name="optimize_application_performance">Optimize Application Performance</a></h3><div
class="level3"><ul><li
</div> class="level1"><div
class="li"> <a
<h2><a>Development Phase</a></h2> href="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a></div></li><li
<div> class="level1"><div
class="li"> <a
</div> href="/com/jme3/gde/core/docs/jme3/advanced/multithreading.html">Multithreading</a></div></li></ul></div><h3><a
name="use_an_assets_folder">Use an Assets Folder</a></h3><div
<h3><a>Where to Start?</a></h3> class="level3"><p> Put your assets into subfolders of your project&#039;s <code>assets</code> directory. This is the default path where the assetManager looks for files.</p><pre>jMonkeyProjects/Pong/assets/ # Store assets here
<div>
<p>
You have a list of features that you want in game, but which one do you implement first? You will keep adding features to a project that grows more and more complex, how can you minimize the amount of rewriting required?
</p>
<ol>
<li><div> Start with implementing the most complex game feature first – the one that imposes most constraints on the structure of your project (for instance, networking.)</div>
</li>
<li><div> Make sure the game&#039;s high-level frame (screen switching, networking, physics, loading/saving) is sound and solid before you implement low-level details of gameplay. </div>
</li>
<li><div> Only add one larger feature at a time. If there are complex interactions (such as “networking + physics”), start with a small test case (“one cube”) and work your way up, don&#039;t start with a whole scene.</div>
</li>
<li><div> Test for side-effects on existing code before you add the next feature.</div>
</li>
</ol>
<p>
Acknowledge whether you want a feature because it is necessary for gameplay, or simply because “everyone else has it”. Successful high-performance games are the ones where someone made smart decisions what to keep and what to drop.
</p>
<ul>
<li><div> Example: Everybody wants “full physics, AI, post-rendering effects, and multi-player networking”… Make certain you truly understand what that requires (e.g. client-server synchonization)! Your goal should be to bring out the essence of your game idea, don&#039;t water down gameplay but attempting to make it “do everything, but better”. </div>
</li>
</ul>
</div>
<h3><a>Extend SimpleApplication</a></h3>
<div>
<p>
Typically, developers extend a custom class off of jME3&#039;s com.jme3.app.SimpleApplication (or even com.jme3.app.Application). For a racing game you would create a different base game class than for a space game or a shooter.
</p>
<ol>
<li><div> Create a generic game class for your custom game:</div>
<ol>
<li><div> Create a jME3-based project with all necessary JARs on the classpath. </div>
</li>
<li><div> Create a class in this package that extends SimpleApplication, name it something like <code>my.company.MyBaseGame.java</code>.</div>
</li>
<li><div> Implement all generic features that the game type needs in the MyBaseGame class. For example methods for loading and saving scenes, physics, networking and multi-player logon screen, switching to settings screen, etc. </div>
</li>
<li><div> Include generic assets (company logo, reusable <acronym title="Graphical User Interface">GUI</acronym> elements in your company style, etc) in the MyBaseGame&#039;s assets directory.</div>
</li>
</ol>
</li>
<li><div> Create your actual game, e.g. a shooter: </div>
<ol>
<li><div> Create another jME3-based project, and a new package for the game itself, e.g. <code>my.company.zombieshooter.MyGame.java</code>. </div>
</li>
<li><div> Add MyBaseGame.jar to the classpath of MyGame.java.</div>
</li>
<li><div> Make MyGame.java&#039;s main class extend MyBaseGame. </div>
</li>
<li><div> The specific assets (scenes, models) of this game go into MyGame&#039;s own assets folder.</div>
</li>
<li><div> Now implement this game&#039;s mechanics and levels – without having to worry about logon&amp;settings screens and all the other features that you already dealt with in MyBaseGame.</div>
</li>
</ol>
</li>
</ol>
</div>
<h3><a>Controls and AppStates -- The Smart Way to Implement Game Logic</a></h3>
<div>
<p>
As your jME3-based application grows more advanced, you may find yourself putting more and more tests in the simpleUpdate() loop, and passing around lots of object references. Don&#039;t implement game behaviour by copying and pasting boilerplate code! It is a best practice to move game behaviour into classes of their own. In jME3 these classes are Controls and AppStates.
</p>
<ul>
<li><div> Use Controls to implement the behaviour of types of game entities. A character control that defines how this type of Spatials moves, an animation control that plays animations in this type of Spatial&#039;s model, etc.</div>
</li>
<li><div> Use AppStates to implement global game behaviour: A physics manager, a custom artificial intelligence manager, etc.</div>
</li>
<li><div> Use the simpleUpdate() loop for the remaining “one-off” tests and interactions.</div>
</li>
</ul>
<p>
Both classes automatically hook into the main update loop. Instead of remote controlling game entities via simpleUpdate(), you define the desired behaviour in the update methods of custom Controls and AppStates. You then add Controls to Spatials, and AppStates to the application, and jME3 will automatically trigger the update methods. This cleans up your simpleUpdate() loop code considerably.
</p>
<p>
Learn more about <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> and <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a>.
</p>
</div>
<h3><a>Optimize Application Performance</a></h3>
<div>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a></div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/multithreading.html">Multithreading</a></div>
</li>
</ul>
</div>
<h3><a>Use an Assets Folder</a></h3>
<div>
<p>
Put your assets into subfolders of your project&#039;s <code>assets</code> directory. This is the default path where the assetManager looks for files.
</p>
<pre>
jMonkeyProjects/Pong/assets/ # Store assets here
jMonkeyProjects/Pong/build/ # jMP generates built classes here * jMonkeyProjects/Pong/build/ # jMP generates built classes here *
jMonkeyProjects/Pong/build.xml # Customize Ant build script here jMonkeyProjects/Pong/build.xml # Customize Ant build script here
jMonkeyProjects/Pong/nbproject/ # jMP stores default build.xml and meta data * jMonkeyProjects/Pong/nbproject/ # jMP stores default build.xml and meta data *
jMonkeyProjects/Pong/dist/ # jMP generates executables here * jMonkeyProjects/Pong/dist/ # jMP generates executables here *
jMonkeyProjects/Pong/src/ # Store Java sources here jMonkeyProjects/Pong/src/ # Store Java sources here
jMonkeyProjects/Pong/test/ # Store test classes here (optional) jMonkeyProjects/Pong/test/ # Store test classes here (optional)
(*) managed by jMonkeyPlatform, don&#039;t edit (*) managed by jMonkeyPlatform, don&#039;t edit</pre><ul><li
</pre> class="level1"><div
<ul> class="li"> Agree on a file and directory naming scheme with the designers.</div><ul><li
<li><div> Agree on a file and directory naming scheme with the designers.</div> class="level2"><div
<ul> class="li"> Are there assets (models, sound files, …) that will be used interchangeably? Then name or number them in a way so that the developer can swap the assets by swapping part of the path string.</div></li><li
<li><div> Are there assets (models, sound files, …) that will be used interchangeably? Then name or number them in a way so that the developer can swap the assets by swapping part of the path string.</div> class="level2"><div
</li> class="li"> Decide on naming standards for naming interactive parts of models (e.g. arms/legs in an animation).</div></li></ul></li><li
<li><div> Decide on naming standards for naming interactive parts of models (e.g. arms/legs in an animation).</div> class="level1"><div
</li> class="li"> Structure the subfolders of <code>assets</code> in any way that suits the project – but stick with one system.</div><ul><li
</ul> class="level2"><div
</li> class="li"> Either keep all Textures together with their Ogre meshes in the Model directory.</div></li><li
<li><div> Structure the subfolders of <code>assets</code> in any way that suits the project – but stick with one system. </div> class="level2"><div
<ul> class="li"> Or keep the Ogre meshes with their Textures in the Textures directory. (Recommended.)</div></li></ul></li><li
<li><div> Either keep all Textures together with their Ogre meshes in the Model directory.</div> class="level1"><div
</li> class="li"> Place reusable Textures and Materials (the ones that you set programmatically) into the Textures and Materials directory, respectively.</div></li><li
<li><div> Or keep the Ogre meshes with their Textures in the Textures directory. (Recommended.)</div> class="level1"><div
</li> class="li"> If different types of assets (materials, textures, models) belong together, create a parallel subdirectory structure for them: <code>Textures/vehicles/car/</code>, <code>Materials/vehicles/car/</code>, <code>Models/vehicles/car/</code></div></li></ul><p> Here is an example of a commonly used directory structure:</p><pre>jMonkeyProjects/Pong/assets/Interface/ # .font, .jpg, .png, .xml
</ul>
</li>
<li><div> Place reusable Textures and Materials (the ones that you set programmatically) into the Textures and Materials directory, respectively.</div>
</li>
<li><div> If different types of assets (materials, textures, models) belong together, create a parallel subdirectory structure for them: <code>Textures/vehicles/car/</code>, <code>Materials/vehicles/car/</code>, <code>Models/vehicles/car/</code></div>
</li>
</ul>
<p>
Here is an example of a commonly used directory structure:
</p>
<pre>
jMonkeyProjects/Pong/assets/Interface/ # .font, .jpg, .png, .xml
jMonkeyProjects/Pong/assets/MatDefs/ # .j3md jMonkeyProjects/Pong/assets/MatDefs/ # .j3md
jMonkeyProjects/Pong/assets/Materials/ # .j3m jMonkeyProjects/Pong/assets/Materials/ # .j3m
jMonkeyProjects/Pong/assets/Models/ # .j3o jMonkeyProjects/Pong/assets/Models/ # .j3o
jMonkeyProjects/Pong/assets/Scenes/ # .j3o jMonkeyProjects/Pong/assets/Scenes/ # .j3o
jMonkeyProjects/Pong/assets/Shaders/ # .vert, .frag jMonkeyProjects/Pong/assets/Shaders/ # .vert, .frag
jMonkeyProjects/Pong/assets/Sounds/ # .ogg, .wav jMonkeyProjects/Pong/assets/Sounds/ # .ogg, .wav
jMonkeyProjects/Pong/assets/Textures/ # .mesh.xml+.material, .mtl+.obj, .jpg, .png jMonkeyProjects/Pong/assets/Textures/ # .mesh.xml+.material, .mtl+.obj, .jpg, .png</pre><p> See also: <a
</pre> href="/com/jme3/gde/core/docs/sdk/asset_packs.html">Asset Packs</a></p></div><h3><a
name="don_t_mess_with_geometric_state">Don&#039;t Mess With Geometric State</a></h3><div
<p> class="level3"><p> Here are some tips especially for users who already know jME2. Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to <em>not</em> mess with it.</p><ul><li
See also: <a href="/com/jme3/gde/core/docs/sdk/asset_packs.html">Asset Packs</a> class="level1"><div
</p> class="li"> Do not call updateGeometricState() on anything but the root node!</div></li><li
class="level1"><div
</div> class="li"> Do not override or mess with updateGeometricState() at all.</div></li><li
class="level1"><div
<h3><a>Don&#039;t Mess With Geometric State</a></h3> class="li"> Do not use getLocalTranslation().set() to move a spatial, always use setLocalTranslation().</div></li></ul></div><h3><a
<div> name="maintain_internal_documentation">Maintain Internal Documentation</a></h3><div
class="level3"><p> It&#039;s unlikely you will be willing to fully document every class you write. You should at minimum javadoc all crucial methods/parameters in a meaningful way.</p><ul><li
<p> class="level1"><div
class="li"> Answer three questions for every crucial method/parameter:</div><ul><li
Here are some tips especially for users who already know jME2. Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to <em>not</em> mess with it. class="level2"><div
class="li"> What is this?</div></li><li
</p> class="level2"><div
<ul> class="li"> How does it solve its task? (e.g. algorithm used)</div></li><li
<li><div> Do not call updateGeometricState() on anything but the root node!</div> class="level2"><div
</li> class="li"> In which situation do I want to use this?</div></li></ul></li><li
<li><div> Do not override or mess with updateGeometricState() at all.</div> class="level1"><div
</li> class="li"> Write down limits (e.g. min/max values) and defaults while you still remember.</div></li><li
<li><div> Do not use getLocalTranslation().set() to move a spatial, always use setLocalTranslation().</div> class="level1"><div
</li> class="li"> Is this optional or required? What are the alternatives?</div></li><li
</ul> class="level1"><div
class="li"> Treat javadoc as messages to your future self. &quot;genNextVal() generates the next value&quot; and &quot;@param float factor A factor influencing the result&quot; do <em>not</em> count as documentation.</div></li></ul></div><h3><a
</div> name="use_version_control">Use Version Control</a></h3><div
class="level3"><p> Whether you work in a team or alone, keeping a version controlled repository of your code will help you roll-back buggy changes or recover that code that you or someone deleted and now is needed.</p><ul><li
<h3><a>Maintain Internal Documentation</a></h3> class="level1"><div
<div> class="li"> Treat commit messages as messages to your future self. &quot;Made some changes&quot; is <em>not</em> a commit message.</div></li><li
class="level1"><div
<p> class="li"> The jMonkeyPlatform supports Subversion, Mercurial, and <acronym
title="Concurrent Versions System">CVS</acronym>.</div><ul><li
It&#039;s unlikely you will be willing to fully document every class you write. You should at minimum javadoc all crucial methods/parameters in a meaningful way. class="level2"><div
class="li"> If you don&#039;t know which to choose, Subversion is a good choice for starters.</div></li><li
</p> class="level2"><div
<ul> class="li"> You can get free project hosting space from various open-source dev portals like <a
<li><div> Answer three questions for every crucial method/parameter:</div> href="http://sourceforge.net/">Sourceforge</a>, <a
<ul> href="https://github.com/">Github</a>, <a
<li><div> What is this? </div> href="https://bitbucket.org/">bitbucket</a> or <a
</li> href="https://code.google.com">Google Code</a>. <a
<li><div> How does it solve its task? (e.g. algorithm used)</div> href="https://bitbucket.org/">Bitbucket</a> support private projects.</div></li></ul></li></ul></div><h3><a
</li> name="convert_models_to_j3o_format">Convert Models to .j3o Format</a></h3><div
<li><div> In which situation do I want to use this? </div> class="level3"><p> From the beta on, convert all Ogre mesh models and scenes to the binary .j3o format. Use the jMonkeyPlatform for the conversion, and save the .j3o files into the Models directory.</p><ul><li
</li> class="level1"><div
</ul> class="li"> .j3o is an optimized format to store part of a jME3 scenegraph. <br/> It can contain an individual model or a whole scene. Optionally (using the jMonkeyEngine SceneComposer) you can include the model&#039;s physical properties, materials, lights, particle emitters, and audio nodes.</div></li><li
</li> class="level1"><div
<li><div> Write down limits (e.g. min/max values) and defaults while you still remember. </div> class="li"> If you kept the Ogre mesh together with the textures in the Textures directory during the conversion, the paths are recorded in a way so that you can move the .j3o to another directory, and it will still find its textures.</div></li><li
</li> class="level1"><div
<li><div> Is this optional or required? What are the alternatives?</div> class="li"> The default Ant build script copies .j3o / .j3m files and other assets into the distributable JAR automatically.</div></li><li
</li> class="level1"><div
<li><div> Treat javadoc as messages to your future self. “genNextVal() generates the next value” and ”@param float factor A factor influencing the result” do <em>not</em> count as documentation. </div> class="li"> Important: Other model files however (.mesh.xml, .material, .obj, .mat) are not bundled automatically. You will get a runtime error that a resource was not found if you try to run the JAR with code referring to these files.</div></li></ul></div><h2><a
</li> name="debugging_and_test_phase">Debugging and Test Phase</a></h2><div
</ul> class="level2"></div><h3><a
name="test">Test</a></h3><div
</div> class="level3"><p> Unit Tests (Java Assertions) have a different status in 3D graphics development than in other types of software. You cannot write any assertions that automatically test whether the rendered image looks correct, or whether interactions are intuitive. Still you should create simple test cases for separate game features such as loaders, content generators, effects. Run them now and then to see whether they still work as intended – or whether they are affected by side effects. Keep the test classes in a test directory in the project, but don&#039;t include them in the distribution.</p><p> Quality Assurance (QA) means maintaining a clear list of steps that must always work, and checking them. There can be bugs in software, but tasks such as installing and de-installing, saving and loading, starting/pausing/quitting the game, <em>must work</em>, no excuse. After every milestone, you go through the list again, on every supported operating system, and systematically look for regressions or bugs.</p><p> Alpha and Beta Testing means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure it out by themselves (you only can include the usual read-me and help docs). Provide the testers with an easy method to report back descriptions of their problems, e.g. why they gave up. Evaluate whether these problems are exceptions or must be fixed for the game to be playable.</p></div><h3><a
name="debug">Debug</a></h3><div
<h3><a>Use Version Control</a></h3> class="level3"><p> A Java Debugger is included in the jMonkeyPlatform. It allows you to set a break point in your code near the point where an exception happens. Then you step through the execution line by line and watch object and variable states to detect where the bug starts.</p><p> Use the <a
<div> href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">Logger</a> to print status messages during the development and debugging phase, instead of System.out.println().</p></div><h3><a
name="enhance_performance">Enhance Performance</a></h3><div
<p> class="level3"><p> A Java Profiler can be added to the jMonkeyPlatform via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often. If object creation and garbage collection counts keep increasing, you are looking at a memory leak.</p></div><h2><a
name="release_phase">Release Phase</a></h2><div
Whether you work in a team or alone, keeping a version controlled repository of your code will help you roll-back buggy changes or recover that code that you or someone deleted and now is needed. class="level2"><p> <strong>Pre-Release To-Do List</strong></p><ul><li
</p> class="level1"><div
<ul> class="li"> Verify that all assets are up-to-date and converted to .j3o.</div></li><li
<li><div> Treat commit messages as messages to your future self. “Made some changes” is <em>not</em> a commit message.</div> class="level1"><div
</li> class="li"> Prepare licenses of assets that you use for inclusion (you <em>did</em> obtain permission to use them, right…?)</div></li><li
<li><div> The jMonkeyPlatform supports Subversion, Mercurial, and <acronym title="Concurrent Versions System">CVS</acronym>. </div> class="level1"><div
<ul> class="li"> Switch off fine <a
<li><div> If you don&#039;t know which to choose, Subversion is a good choice for starters. </div> href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">logging</a> output.</div></li><li
</li> class="level1"><div
<li><div> You can get free project hosting space from various open-source dev portals like <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://sourceforge.net/"><param name="text" value="<html><u>Sourceforge</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://github.com/"><param name="text" value="<html><u>Github</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://bitbucket.org/"><param name="text" value="<html><u>bitbucket</u></html>"><param name="textColor" value="blue"></object> or <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://code.google.com"><param name="text" value="<html><u>Google Code</u></html>"><param name="textColor" value="blue"></object>. <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://bitbucket.org/"><param name="text" value="<html><u>Bitbucket</u></html>"><param name="textColor" value="blue"></object> support private projects.</div> class="li"> Prepare promotional art: Cool screenshots (in thumbnail, square, vertical, horizontal, and fullscreen formats) and video clips. Include name, contact info, slogan, etc so customers can find you.</div></li><li
</li> class="level1"><div
</ul> class="li"> Prepare a web page, start getting advertisment slots, etc</div></li><li
</li> class="level1"><div
</ul> class="li"> Prepare a readme.txt file, or installation guide, or handbook – if applicable.</div></li><li
class="level1"><div
</div> class="li"> Get a certificate if it is required for your distribution method (see below).</div></li><li
class="level1"><div
<h3><a>Convert Models to .j3o Format</a></h3> class="li"> Specify a classification rating.</div></li><li
<div> class="level1"><div
class="li"> …</div></li></ul><p> <strong>Distributable Executable</strong></p><p> The <a
<p> href="/com/jme3/gde/core/docs/sdk.html">SDK</a> can help you with deployment. Do you release your game as WebStart, Desktop JAR, or Applet? Each has its pros and cons.</p><div
class="table sectionedit1"><table
From the beta on, convert all Ogre mesh models and scenes to the binary .j3o format. Use the jMonkeyPlatform for the conversion, and save the .j3o files into the Models directory. class="inline"><tr
class="row0"><th
</p> class="col0">Distribution</th><th
<ul> class="col1">Pros</th><th
<li><div> .j3o is an optimized format to store part of a jME3 scenegraph. <br/> class="col2">Cons</th></tr><tr
It can contain an individual model or a whole scene. Optionally (using the jMonkeyEngine SceneComposer) you can include the model&#039;s physical properties, materials, lights, particle emitters, and audio nodes.</div> class="row1"><td
</li> class="col0">Desktop Launcher <br/> (.EXE, .app, .jar+.sh)</td><td
<li><div> If you kept the Ogre mesh together with the textures in the Textures directory during the conversion, the paths are recorded in a way so that you can move the .j3o to another directory, and it will still find its textures.</div> class="col1">This is the standard way of distributing desktop applications. The jMonkeyPlatform can be configured to automatically create zipped launchers for each operating system.</td><td
</li> class="col2">You need to offer three separate, platform-dependent downloads.</td></tr><tr
<li><div> The default Ant build script copies .j3o / .j3m files and other assets into the distributable JAR automatically. </div> class="row2"><td
</li> class="col0">Desktop Application <br/> (.JAR)</td><td
<li><div> Important: Other model files however (.mesh.xml, .material, .obj, .mat) are not bundled automatically. You will get a runtime error that a resource was not found if you try to run the JAR with code referring to these files. </div> class="col1">Platform independent desktop application.</td><td
</li> class="col2">User must have Java configured to run JARs when they are opened; or user must know how to run JARs from command line; or you must provide a custom JAR wrapper.</td></tr><tr
</ul> class="row3"><td
class="col0">Web Start <br/> (.JNLP)</td><td
</div> class="col1">The user accesses a <acronym
title="Uniform Resource Locator">URL</acronym>, saves the game as one executable file. Easy process, no installer required. You can allow the game to be played offline.</td><td
<h2><a>Debugging and Test Phase</a></h2> class="col2">Users need network connection to install the game. Downloading bigger games takes a while as opposed to running them from a CD.</td></tr><tr
<div> class="row4"><td
class="col0">Browser Applet <br/> (.<acronym
</div> title="HyperText Markup Language">HTML</acronym>+.JAR)</td><td
class="col1">Easy to access and play game via most web browsers. Userfriendly solution for quick small games.</td><td
<h3><a>Test</a></h3> class="col2">Game only runs in the browser. Game or settings cannot be saved to disk. Some restrictions in default camera navigation (jME cannot capture mouse.)</td></tr></table></div><p> Which ever method you choose, a Java-Application works on the three main operating systems: Windows, Mac <acronym
<div> title="Operating System">OS</acronym>, Linux.</p></div>
<p>
Unit Tests (Java Assertions) have a different status in 3D graphics development than in other types of software. You cannot write any assertions that automatically test whether the rendered image looks correct, or whether interactions are intuitive. Still you should create simple test cases for separate game features such as loaders, content generators, effects. Run them now and then to see whether they still work as intended – or whether they are affected by side effects. Keep the test classes in a test directory in the project, but don&#039;t include them in the distribution.
</p>
<p>
Quality Assurance (QA) means maintaining a clear list of steps that must always work, and checking them. There can be bugs in software, but tasks such as installing and de-installing, saving and loading, starting/pausing/quitting the game, <em>must work</em>, no excuse. After every milestone, you go through the list again, on every supported operating system, and systematically look for regressions or bugs.
</p>
<p>
Alpha and Beta Testing means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure it out by themselves (you only can include the usual read-me and help docs). Provide the testers with an easy method to report back descriptions of their problems, e.g. why they gave up. Evaluate whether these problems are exceptions or must be fixed for the game to be playable.
</p>
</div>
<h3><a>Debug</a></h3>
<div>
<p>
A Java Debugger is included in the jMonkeyPlatform. It allows you to set a break point in your code near the point where an exception happens. Then you step through the execution line by line and watch object and variable states to detect where the bug starts.
</p>
<p>
Use the <a href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">Logger</a> to print status messages during the development and debugging phase, instead of System.out.println().
</p>
</div>
<h3><a>Enhance Performance</a></h3>
<div>
<p>
A Java Profiler can be added to the jMonkeyPlatform via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often. If object creation and garbage collection counts keep increasing, you are looking at a memory leak.
</p>
</div>
<h2><a>Release Phase</a></h2>
<div>
<p>
<strong>Pre-Release To-Do List</strong>
</p>
<ul>
<li><div> Verify that all assets are up-to-date and converted to .j3o.</div>
</li>
<li><div> Prepare licenses of assets that you use for inclusion (you <em>did</em> obtain permission to use them, right…?)</div>
</li>
<li><div> Switch off fine <a href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">logging</a> output.</div>
</li>
<li><div> Prepare promotional art: Cool screenshots (in thumbnail, square, vertical, horizontal, and fullscreen formats) and video clips. Include name, contact info, slogan, etc so customers can find you.</div>
</li>
<li><div> Prepare a web page, start getting advertisment slots, etc</div>
</li>
<li><div> Prepare a readme.txt file, or installation guide, or handbook – if applicable.</div>
</li>
<li><div> Get a certificate if it is required for your distribution method (see below).</div>
</li>
<li><div> Specify a classification rating.</div>
</li>
<li><div></div>
</li>
</ul>
<p>
<strong>Distributable Executable</strong>
</p>
<p>
The <a href="/com/jme3/gde/core/docs/sdk.html">SDK</a> can help you with deployment. Do you release your game as WebStart, Desktop JAR, or Applet? Each has its pros and cons.
</p>
<table>
<tr>
<th>Distribution</th><th>Pros</th><th>Cons</th>
</tr>
<tr>
<td>Desktop Launcher <br/>
(.EXE, .app, .jar+.sh)</td><td>This is the standard way of distributing desktop applications. The jMonkeyPlatform can be configured to automatically create zipped launchers for each operating system. </td><td>You need to offer three separate, platform-dependent downloads.</td>
</tr>
<tr>
<td>Desktop Application <br/>
(.JAR)</td><td>Platform independent desktop application. </td><td>User must have Java configured to run JARs when they are opened; or user must know how to run JARs from command line; or you must provide a custom JAR wrapper.</td>
</tr>
<tr>
<td>Web Start <br/>
(.JNLP)</td><td>The user accesses a <acronym title="Uniform Resource Locator">URL</acronym>, saves the game as one executable file. Easy process, no installer required. You can allow the game to be played offline.</td><td>Users need network connection to install the game. Downloading bigger games takes a while as opposed to running them from a CD. </td>
</tr>
<tr>
<td>Browser Applet <br/>
(.<acronym title="HyperText Markup Language">HTML</acronym>+.JAR)</td><td>Easy to access and play game via most web browsers. Userfriendly solution for quick small games.</td><td>Game only runs in the browser. Game or settings cannot be saved to disk. Some restrictions in default camera navigation (jME cannot capture mouse.)</td>
</tr>
</table>
<p>
Which ever method you choose, a Java-Application works on the three main operating systems: Windows, Mac <acronym title="Operating System">OS</acronym>, Linux.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:best_practices?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:best_practices?do=export_xhtmlbody">view online version</a></em></p>

@ -1,56 +1,60 @@
<h1><a
<h1><a>jMonkeyEngine3 Supported File Types</a></h1> name="jmonkeyengine3_supported_file_types">jMonkeyEngine3 Supported File Types</a></h1><div
<div> class="level1"></div><h2><a
name="jmonkeyengine3_file_formats">jMonkeyEngine3 File Formats</a></h2><div
</div> class="level2"><div
class="table sectionedit1"><table
<h2><a>jMonkeyEngine3 File Formats</a></h2> class="inline"><tr
<div> class="row0"><th
<table> class="col0">Suffix</th><th
<tr> class="col1">Usage</th><th
<th>Suffix</th><th>Usage</th><th>Learn more</th> class="col2">Learn more</th></tr><tr
</tr> class="row1"><td
<tr> class="col0">.j3o</td><td
<td>.j3o</td><td>Binary 3D model or scene. From the Beta release of your game on, you should convert all models to .j3o format. During alpha and earlier development phases (when models still change a lot) you can alternatively load OgreXML/OBJ models directly.</td><td><a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">Model Loader and Viewer</a> </td> class="col1">Binary 3D model or scene. From the Beta release of your game on, you should convert all models to .j3o format. During alpha and earlier development phases (when models still change a lot) you can alternatively load OgreXML/OBJ models directly.</td><td
</tr> class="col2"><a
<tr> href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">Model Loader and Viewer</a></td></tr><tr
<td>.j3m</td><td>A custom Material. You create these Material objects to store Material configurations for your 3D models.</td><td><a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <a href="/com/jme3/gde/core/docs/sdk/material_editing.html">Material Editing</a> </td> class="row2"><td
</tr> class="col0">.j3m</td><td
<tr> class="col1">A custom Material. You create these Material objects to store Material configurations for your 3D models.</td><td
<td>.j3md</td><td>A Material definition. These are templates for advanced shader-based Materials. Each custom .j3m Material is based on a .j3md Material Definition. </td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> </td> class="col2 leftalign"><a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> <a
</table> href="/com/jme3/gde/core/docs/sdk/material_editing.html">Material Editing</a></td></tr><tr
class="row3"><td
</div> class="col0">.j3md</td><td
class="col1">A Material definition. These are templates for advanced shader-based Materials. Each custom .j3m Material is based on a .j3md Material Definition.</td><td
<h2><a>Supported External File Types</a></h2> class="col2"> <a
<div> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></td></tr></table></div></div><h2><a
<table> name="supported_external_file_types">Supported External File Types</a></h2><div
<tr> class="level2"><div
<th>File Suffix</th><th>Description</th> class="table sectionedit2"><table
</tr> class="inline"><tr
<tr> class="row0"><th
<td>.mesh.xml, .meshxml, .scene</td><td>Ogre Mesh <acronym title="Extensible Markup Language">XML</acronym> for 3D models, Ogre DotScene for 3D scenes </td> class="col0">File Suffix</th><th
</tr> class="col1">Description</th></tr><tr
<tr> class="row1"><td
<td>.OBJ, .MTL</td><td>Wavefront, 3D model format</td> class="col0">.mesh.xml, .meshxml, .scene</td><td
</tr> class="col1">Ogre Mesh <acronym
<tr> title="Extensible Markup Language">XML</acronym> for 3D models, Ogre DotScene for 3D scenes</td></tr><tr
<td>.<acronym title="Joint Photographics Experts Group">JPG</acronym>, .<acronym title="Portable Network Graphics">PNG</acronym>, .<acronym title="Graphics Interchange Format">GIF</acronym></td><td>2D Images, textures</td> class="row2"><td
</tr> class="col0">.OBJ, .MTL</td><td
<tr> class="col1">Wavefront, 3D model format</td></tr><tr
<td>.DDS, .HDR, .PFM, .TGA</td><td>Textures</td> class="row3"><td
</tr> class="col0">.<acronym
<tr> title="Joint Photographics Experts Group">JPG</acronym>, .<acronym
<td>.fnt</td><td>Bitmap fonts</td> title="Portable Network Graphics">PNG</acronym>, .<acronym
</tr> title="Graphics Interchange Format">GIF</acronym></td><td
<tr> class="col1">2D Images, textures</td></tr><tr
<td>.WAV, .OGG</td><td>Wave and OGG Vorbis audio</td> class="row4"><td
</tr> class="col0">.DDS, .HDR, .PFM, .TGA</td><td
<tr> class="col1">Textures</td></tr><tr
<td>.OGV</td><td>Ogg Theora video</td> class="row5"><td
</tr> class="col0">.fnt</td><td
</table> class="col1">Bitmap fonts</td></tr><tr
class="row6"><td
</div> class="col0">.WAV, .OGG</td><td
class="col1">Wave and OGG Vorbis audio</td></tr><tr
class="row7"><td
class="col0">.OGV</td><td
class="col1">Ogg Theora video</td></tr></table></div></div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:file_types?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:file_types?do=export_xhtmlbody">view online version</a></em></p>

@ -1,78 +1,37 @@
<h1><a
<h1><a>jME3 Headless Server</a></h1> name="jme3_headless_server">jME3 Headless Server</a></h1><div
<div> class="level1"><p> When adding multiplayer to your game, you may find that your server needs to know about game state (e.g. where are players, objects? Was that a direct hit? etc.) You can code all this up yourself, but there&#039;s an easier way.</p><p> It&#039;s very easy to change your current (client) game to function as a server as well.</p></div><h2><a
name="client_code">Client Code</a></h2><div
<p> class="level2"><p> First, let&#039;s take a look at the default way of creating a new game (in its simplest form):</p><pre>public static void main&#40;String&#91;&#93; args&#41; &#123;
When adding multiplayer to your game, you may find that your server needs to know about game state (e.g. where are players, objects? Was that a direct hit? etc.) You can code all this up yourself, but there&#039;s an easier way.
</p>
<p>
It&#039;s very easy to change your current (client) game to function as a server as well.
</p>
</div>
<h2><a>Client Code</a></h2>
<div>
<p>
First, let&#039;s take a look at the default way of creating a new game (in its simplest form):
</p>
<pre>public static void main&#40;String&#91;&#93; args&#41; &#123;
Application app = new Main&#40;&#41;; Application app = new Main&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="headless_server_code">Headless Server Code</a></h2><div
class="level2"><p> Now, with a simple change you can start your game in Headless mode. This means that all input and audio/visual output will be ignored. That&#039;s a good thing for a server.</p><pre>import com.jme3.system.JmeContext;
<h2><a>Headless Server Code</a></h2>
<div>
<p>
Now, with a simple change you can start your game in Headless mode. This means that all input and audio/visual output will be ignored. That&#039;s a good thing for a server.
</p>
<pre>import com.jme3.system.JmeContext;
import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeContext.Type;
&nbsp; &nbsp;
public static void main&#40;String&#91;&#93; args&#41; &#123; public static void main&#40;String&#91;&#93; args&#41; &#123;
Application app = new Main&#40;&#41;; Application app = new Main&#40;&#41;;
app.start&#40;JmeContext.Type.Headless&#41;; app.start&#40;JmeContext.Type.Headless&#41;;
&#125;</pre> &#125;</pre><p><p><div
<p> class="noteclassic">Although all input/output is ignored, the server <em>does</em> keep game state and <em>does</em> call the <code>simpleUpdate()</code> as expected.</div></p></p></div><h2><a
<p><div>Although all input/output is ignored, the server <em>does</em> keep game state and <em>does</em> call the <code>simpleUpdate()</code> as expected. name="next_steps">Next steps</a></h2><div
</div></p> class="level2"><p> Okay, so you can now start your game in a headless &#039;server mode&#039;, where to go from here?</p><ul><li
</p> class="level1"><div
class="li"> Parse <code>String[] args</code> from the <code>main</code>-method to enable server mode on demand (e.g. start your server like <code>java -jar mygame.jar –server</code>.</div></li><li
</div> class="level1"><div
class="li"> Integrate <a
<h2><a>Next steps</a></h2> href="/com/jme3/gde/core/docs/spidermonkey.html">SpiderMonkey</a>, to provide game updates to the server over a network.</div></li><li
<div> class="level1"><div
class="li"> Only execute code that&#039;s needed. (E.g. place all rendering code inside an <code>if (servermode)</code>-block) (or <code>if (!servermode)</code> for the client).</div></li><li
<p> class="level1"><div
class="li"> Add decent <a
Okay, so you can now start your game in a headless &#039;server mode&#039;, where to go from here? href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">logging</a> so your server actually makes sense.</div></li></ul><div
class="tags"><span> <a
</p> href="/wiki/doku.php/tag:intermediate?do=showtag&amp;tag=tag%3Aintermediate">intermediate</a>, <a
<ul> href="/wiki/doku.php/tag:server?do=showtag&amp;tag=tag%3Aserver">server</a>, <a
<li><div> Parse <code>String[] args</code> from the <code>main</code>-method to enable server mode on demand (e.g. start your server like <code>java -jar mygame.jar –server</code>.</div> href="/wiki/doku.php/tag:spidermonkey?do=showtag&amp;tag=tag%3Aspidermonkey">spidermonkey</a>, <a
</li> href="/wiki/doku.php/tag:headless?do=showtag&amp;tag=tag%3Aheadless">headless</a>, <a
<li><div> Integrate <a href="/com/jme3/gde/core/docs/spidermonkey.html">SpiderMonkey</a>, to provide game updates to the server over a network.</div> href="/wiki/doku.php/tag:network?do=showtag&amp;tag=tag%3Anetwork">network</a>, <a
</li> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a> </span></div></div>
<li><div> Only execute code that&#039;s needed. (E.g. place all rendering code inside an <code>if (servermode)</code>-block) (or <code>if (!servermode)</code> for the client).</div>
</li>
<li><div> Add decent <a href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">logging</a> so your server actually makes sense.</div>
</li>
</ul>
<div><span>
<a href="/wiki/doku.php/tag:intermediate?do=showtag&amp;tag=tag%3Aintermediate">intermediate</a>,
<a href="/wiki/doku.php/tag:server?do=showtag&amp;tag=tag%3Aserver">server</a>,
<a href="/wiki/doku.php/tag:spidermonkey?do=showtag&amp;tag=tag%3Aspidermonkey">spidermonkey</a>,
<a href="/wiki/doku.php/tag:headless?do=showtag&amp;tag=tag%3Aheadless">headless</a>,
<a href="/wiki/doku.php/tag:network?do=showtag&amp;tag=tag%3Anetwork">network</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:headlessserver?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:headlessserver?do=export_xhtmlbody">view online version</a></em></p>

@ -1,51 +1,63 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html
xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"><head xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"><head
profile="http://gmpg.org/xfn/11"><link profile="http://gmpg.org/xfn/11"><link
rel='stylesheet' href='http://jmonkeyengine.org/wp-content/plugins/wp-minify/cache/683a1716f877612425a260cefd4af885.css?m=1308669071' type='text/css' media='screen' /> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/wp-minify/cache/e11b9aae590dd01c34e9dd350439909e.js?m=1308669071'></script> <link
rel="shortcut icon" href="http://jmonkeyengine.org/favicon.ico" /><meta rel="shortcut icon" href="http://jmonkeyengine.org/favicon.ico" /><meta
http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>jMonkeyEngine.org |</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>jMonkeyEngine.org |</title><meta
name="generator" content="WordPress 3.1" /><link name="generator" content="WordPress 3.1.3" /><link
rel="stylesheet" href="http://jmonkeyengine.org/wp-content/themes/bp-jme-1/style.css" type="text/css" media="screen" /><link
rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org | Site Wide Activity RSS Feed" href="http://jmonkeyengine.org/activity/feed/" /><link rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org | Site Wide Activity RSS Feed" href="http://jmonkeyengine.org/activity/feed/" /><link
rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org Blog Posts RSS Feed" href="http://jmonkeyengine.org/feed/" /><link rel="alternate" type="application/rss+xml" title="jMonkeyEngine.org Blog Posts RSS Feed" href="http://jmonkeyengine.org/feed/" /><link
rel="alternate" type="application/atom+xml" title="jMonkeyEngine.org Blog Posts Atom Feed" href="http://jmonkeyengine.org/feed/atom/" /><link rel="alternate" type="application/atom+xml" title="jMonkeyEngine.org Blog Posts Atom Feed" href="http://jmonkeyengine.org/feed/atom/" /><link
rel="pingback" href="http://jmonkeyengine.org/xmlrpc.php" /> <script type="text/javascript">var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-17652261-1']);_gaq.push(['_trackPageview']);(function(){var ga=document.createElement('script');ga.type='text/javascript';ga.async=true;ga.src=('https:'==document.location.protocol?'https://ssl':'http://www')+'.google-analytics.com/ga.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);})();</script> <link rel="pingback" href="http://jmonkeyengine.org/xmlrpc.php" /> <script type="text/javascript">//
rel='stylesheet' id='fancybox-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.css?ver=1.3.4' type='text/css' media='all' /><link // Google Analytics for WordPress by Yoast v4.1 | http://yoast.com/wordpress/google-analytics/
rel='stylesheet' id='fancybox-ie-fix-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.css-png-fix.php?ver=3.1' type='text/css' media='all' /><link var _gaq = _gaq || [];
rel='stylesheet' id='fancy-gallery-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancy-gallery.css?ver=3.1' type='text/css' media='all' /><link _gaq.push(['_setAccount','UA-17652261-1']);
rel='stylesheet' id='gsc_style-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/smoothness/jquery-ui-1.7.3.custom.css?ver=3.1' type='text/css' media='all' /><link _gaq.push(['_trackPageview'],['_trackPageLoadTime']);
rel='stylesheet' id='gsc_style_search_bar-css' href='http://www.google.com/cse/style/look/minimalist.css?ver=3.1' type='text/css' media='all' /><link (function() {
rel='stylesheet' id='gsc_style_search_bar_more-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/gsc.css?ver=3.1' type='text/css' media='all' /><link var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
rel='stylesheet' id='gsc_style_search_bar_even_more-css' href='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/css/gsc-no-search-button.css?ver=3.1' type='text/css' media='all' /><link ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
rel='stylesheet' id='toc_css-css' href='http://jmonkeyengine.org/wp-content/plugins/seo-friendly-table-of-contents/style.css?ver=3.1' type='text/css' media='all' /><link var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
rel='stylesheet' id='bpgc_screen-css' href='http://jmonkeyengine.org/wp-content/plugins/bp-group-control/css/screen.css?ver=3.1' type='text/css' media='all' /><link })();
rel='stylesheet' id='tabbed-widgets-css' href='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/css/tabbed-widgets.css?ver=3.1' type='text/css' media='all' /><link //</script> <link
rel='stylesheet' id='bp-post-buttons-css-css' href='http://jmonkeyengine.org/wp-content/plugins/bp-post-buttons/include/style/bp_post_buttons.css?ver=3.1' type='text/css' media='all' /><link rel='stylesheet' id='fancybox-ie-fix-css' href='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.css-png-fix.php?ver=3.1.3' type='text/css' media='all' /><link
rel='stylesheet' id='bubbleSheets-css' href='http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/css/css3/bubble-green.css?ver=3.1' type='text/css' media='all' /><link rel='stylesheet' id='gsc_style_search_bar-css' href='http://www.google.com/cse/style/look/minimalist.css?ver=3.1.3' type='text/css' media='all' /> <script type='text/javascript' src='http://www.google.com/jsapi?ver=3.1.3'></script> <script type='text/javascript'>/* */
rel='stylesheet' id='wp_dlmp_styles-css' href='http://jmonkeyengine.org/wp-content/plugins/download-monitor/page-addon/styles.css?ver=3.1' type='text/css' media='all' /><link var BP_DTheme = {
rel='stylesheet' id='activity-subscription-style-css' href='http://jmonkeyengine.org/wp-content/plugins/buddypress-group-email-subscription/css/bp-activity-subscription-css.css?ver=3.1' type='text/css' media='all' /> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/l10n.js?ver=20101110'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/emailprotect/EMAILProtect.js?ver=0.8'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/jquery.js?ver=1.4.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancybox/jquery.fancybox-1.3.4.pack.js?ver=1.3.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/jquery.easing.1.3.js?ver=1.3'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/jquery.mousewheel-3.0.4.pack.js?ver=3.0.4'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancy-js.php?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/google-custom-search/js/gsc.js?ver=3.1'></script> <script type='text/javascript' src='http://www.google.com/jsapi?ver=3.1'></script> <script type='text/javascript'>var BP_DTheme={my_favs:"My Favorites",accepted:"Accepted",rejected:"Rejected",show_all_comments:"Show all comments for this thread",show_all:"Show all",comments:"comments",close:"Close",mention_explain:"@ is a unique identifier for that you can type into any message on this site. will be sent a notification and a link to your message any time you use it."};</script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/buddypress/bp-themes/bp-default/_inc/global.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/bp-group-control/js/screen.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/bp-post-buttons/include/js/insert_tags.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/buddypress-group-tags/group-tags.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/bubble-click.js?ver=3.1'></script> <link my_favs: "My Favorites",
accepted: "Accepted",
rejected: "Rejected",
show_all_comments: "Show all comments for this thread",
show_all: "Show all",
comments: "comments",
close: "Close",
mention_explain: "@ is a unique identifier for that you can type into any message on this site. will be sent a notification and a link to your message any time you use it."
};
/* */</script> <link
rel="EditURI" type="application/rsd+xml" title="RSD" href="http://jmonkeyengine.org/xmlrpc.php?rsd" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://jmonkeyengine.org/xmlrpc.php?rsd" /><link
rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://jmonkeyengine.org/wp-includes/wlwmanifest.xml" /><link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://jmonkeyengine.org/wp-includes/wlwmanifest.xml" /><link
rel='index' title='jMonkeyEngine.org' href='http://jmonkeyengine.org/' /><meta rel='index' title='jMonkeyEngine.org' href='http://jmonkeyengine.org/' /><meta
name="generator" content="WordPress 3.1" /><link name="generator" content="WordPress 3.1.3" /> <script type="text/javascript">var ajaxurl = "http://jmonkeyengine.org/wp-load.php";</script> <script type="text/javascript">var ajax_url = "http://jmonkeyengine.org/wp-admin/admin-ajax.php";
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-better-pagination/pagination.css" media="screen" /><link var ajax_image = "http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/images";
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-group-tags/group-tags.css" media="screen" /><link var ajax_delay = "0";</script> <link
rel="stylesheet" type="text/css" href="http://jmonkeyengine.org/wp-content/plugins/buddypress-rate-forum-posts/css/rating.css" media="screen" /> <script type="text/javascript">var ajaxurl="http://jmonkeyengine.org/wp-load.php";</script> <script type="text/javascript">var ajax_url="http://jmonkeyengine.org/wp-admin/admin-ajax.php";var ajax_image="http://jmonkeyengine.org/wp-content/plugins/cd-bp-avatar-bubble/_inc/images";var ajax_delay="0";</script> <meta rel="stylesheet" href="http://jmonkeyengine.org/wp-content/plugins/explanatory-dictionary/css/explanatory-dictionary-style.php" type="text/css" /><meta
name="generator" content="DokuWiki Release 2009-02-14b" /><meta name="generator" content="DokuWiki" /><meta
name="robots" content="noindex,follow" /><meta name="robots" content="noindex,follow" /><meta
name="date" content="1970-01-01T00:00:00+0000" /><meta name="date" content="1970-01-01T00:00:00+0000" /><meta
name="keywords" content="jme3,intermediate,my_first_game" /><link name="keywords" content="jme3,intermediate,my_first_game" /><link
rel="search" type="application/opensearchdescription+xml" href="/wiki/lib/exe/opensearch.php" title="jMonkeyEngine.org" /><link rel="search" type="application/opensearchdescription+xml" href="/wiki/lib/exe/opensearch.php" title="jMonkeyEngine.org" /><link
rel="start" href="/wiki/" /><link rel="start" href="/wiki/" /><link
rel="contents" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=index" title="Index" /><link rel="contents" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=index" title="Sitemap" /><link
rel="alternate" type="application/rss+xml" title="Recent Changes" href="/wiki/feed.php" /><link rel="alternate" type="application/rss+xml" title="Recent Changes" href="/wiki/feed.php" /><link
rel="alternate" type="application/rss+xml" title="Current Namespace" href="/wiki/feed.php?mode=list&amp;ns=jme3:intermediate" /><link rel="alternate" type="application/rss+xml" title="Current Namespace" href="/wiki/feed.php?mode=list&amp;ns=jme3:intermediate" /><link
rel="alternate" type="text/html" title="Plain HTML" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtml" /><link rel="alternate" type="text/html" title="Plain HTML" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtml" /><link
rel="alternate" type="text/plain" title="Wiki Markup" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_raw" /><link rel="alternate" type="text/plain" title="Wiki Markup" href="/wiki/doku.php/jme3:intermediate:my_first_game?do=export_raw" /><link
rel="stylesheet" media="all" type="text/css" href="/wiki/lib/exe/css.php?s=all&amp;t=wp-integration" /><link rel="stylesheet" media="screen" type="text/css" href="/wiki/lib/exe/css.php?t=wp-integration&amp;tseed=1307630727" /><link
rel="stylesheet" media="screen" type="text/css" href="/wiki/lib/exe/css.php?t=wp-integration" /><link rel="stylesheet" media="all" type="text/css" href="/wiki/lib/exe/css.php?s=all&amp;t=wp-integration&amp;tseed=1307630727" /><link
rel="stylesheet" media="print" type="text/css" href="/wiki/lib/exe/css.php?s=print&amp;t=wp-integration" /> <script type="text/javascript" charset="utf-8" src="/wiki/lib/exe/js.php?edit=0&amp;write=0" ></script> <style type="text/css">#header{background-image:url(http://jmonkeyengine.org/wp-content/uploads/2010/09/header-new-31.gif)}#header h1, #header rel="stylesheet" media="print" type="text/css" href="/wiki/lib/exe/css.php?s=print&amp;t=wp-integration&amp;tseed=1307630727" /> <script type="text/javascript" >/*<![CDATA[*///-->//><!--
#desc{display:none}</style><meta var NS='jme3:intermediate';var JSINFO = {"id":"jme3:intermediate:my_first_game","namespace":"jme3:intermediate"};
id="syntaxhighlighteranchor" name="syntaxhighlighter-version" content="3.1.1" /> <script type="text/javascript">jQuery(document).ready(function(){jQuery("a.confirm").click(function(){if(confirm('Are you sure?'))return true;else return false;});});</script> </head><body //--><!/*]]>*/</script> <script type="text/javascript" charset="utf-8" src="/wiki/lib/exe/js.php?tseed=1307630727" ></script>
<style type="text/css">#header { background-image: url(http://jmonkeyengine.org/wp-content/uploads/2010/09/header-new-31.gif); }
#header h1, #header #desc { display: none; }</style><meta
id="syntaxhighlighteranchor" name="syntaxhighlighter-version" content="3.1.2" /> <script type="text/javascript">jQuery(document).ready( function() { jQuery("a.confirm").click( function() { if ( confirm( 'Are you sure?' ) ) return true; else return false; }); });</script> </head><body
class=""><div class=""><div
id="header"><h1><a id="header"><h1><a
href="http://jmonkeyengine.org" title="Home">jMonkeyEngine.org</a></h1><div href="http://jmonkeyengine.org" title="Home">jMonkeyEngine.org</a></h1><div
@ -61,7 +73,7 @@ value="groups">Groups</option><option
value="members">Members</option><option value="members">Members</option><option
value="links">Links</option></select> <input value="links">Links</option></select> <input
type="submit" name="search-submit" id="search-submit" value="Search" /> <input type="submit" name="search-submit" id="search-submit" value="Search" /> <input
type="hidden" id="_wpnonce" name="_wpnonce" value="9f69e1a059" /><input type="hidden" id="_wpnonce" name="_wpnonce" value="d54d232dd1" /><input
type="hidden" name="_wp_http_referer" value="/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html" /></form></div></div><div type="hidden" name="_wp_http_referer" value="/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html" /></form></div></div><div
id="access"><ul id="access"><ul
id="menu-mainmenu"><li id="menu-mainmenu"><li
@ -217,7 +229,7 @@ href="/wiki/doku.php/jme3:intermediate:documentation" title="jme3:intermediate:
href="/wiki/doku.php/jme3:intermediate:my_first_game" title="jme3:intermediate:my_first_game">my_first_game</a></div></div><div href="/wiki/doku.php/jme3:intermediate:my_first_game" title="jme3:intermediate:my_first_game">my_first_game</a></div></div><div
class="page"><h1><a class="page"><h1><a
name="this_topic_does_not_exist_yet">This topic does not exist yet</a></h1><div name="this_topic_does_not_exist_yet">This topic does not exist yet</a></h1><div
class="level1"><p>You&#039;ve followed a link to a topic that doesn&#039;t exist yet. If permissions allow, you may create it by using the <code>Create this page</code> button.</p></div></div><div class="level1"><p> You&#039;ve followed a link to a topic that doesn&#039;t exist yet. If permissions allow, you may create it by using the <code>Create this page</code> button.</p></div></div><div
class="clearer">&nbsp;</div><div class="clearer">&nbsp;</div><div
class="stylefoot"><div class="stylefoot"><div
class="license">Except where otherwise noted, content on this wiki is licensed under the following license:<a class="license">Except where otherwise noted, content on this wiki is licensed under the following license:<a
@ -241,11 +253,21 @@ href="#">Visit</a><ul
class="random-list"><li><a class="random-list"><li><a
href="http://jmonkeyengine.org/members/?random-member">Random Member</a></li><li href="http://jmonkeyengine.org/members/?random-member">Random Member</a></li><li
class="alt"><a class="alt"><a
href="http://jmonkeyengine.org/groups/?random-group">Random Group</a></li><li><a href="http://jmonkeyengine.org/groups/?random-group">Random Group</a></li></ul></li></ul></div></div> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/fancy-gallery/fancy-js.php?ver=1.3.30'></script> <script type="text/javascript">load_domtooltips();</script> <script type="text/javascript">//
href="http://jmonkeyengine.org/links/?random-link">Random Link</a></li></ul></li></ul></div></div> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.core.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.widget.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.mouse.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.resizable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.draggable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.button.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.position.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.dialog.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-ui-custom.min.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-cookie.min.js?ver=3.1'></script> <script type="text/javascript">var $rotateoptions=new Array();$rotateoptions[2]=new Array();$rotateoptions[2]["style"]="";$rotateoptions[2]["rotate"]=0;$rotateoptions[2]["random_start"]=0;$rotateoptions[2]["start_tab"]=0;$rotateoptions[2]["interval"]=10000;$rotateoptions[3]=new Array();$rotateoptions[3]["style"]="tabs";$rotateoptions[3]["rotate"]=0;$rotateoptions[3]["random_start"]=0;$rotateoptions[3]["start_tab"]=0;$rotateoptions[3]["interval"]=10000;</script> <script type="text/javascript" src="http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/init-plugin.js"></script> <script type="text/javascript">function wo_map_console(url){window.open(url,"wo_map_console","height=650,width=800,toolbar=no,statusbar=no,scrollbars=yes").focus();}</script> <script src="http://stats.wordpress.com/e-201114.js" type="text/javascript"></script> <script type="text/javascript">st_go({blog:'14883676',v:'ext',post:'0'});var load_cmc=function(){linktracker_init(14883676,0,2);};if(typeof addLoadEvent!='undefined')addLoadEvent(load_cmc);else load_cmc();</script> </body></html> function wo_map_console(url) {
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/ window.open(url,"wo_map_console","height=650,width=800,toolbar=no,statusbar=no,scrollbars=yes").focus();
}
//</script>
<!--Plugin WP Overview (lite) 2011.0101.1111 Active-->
<!--stats_footer_test--><script src="http://stats.wordpress.com/e-201125.js" type="text/javascript"></script>
<script type="text/javascript">
st_go({blog:'14883676',v:'ext',post:'0'});
var load_cmc = function(){linktracker_init(14883676,0,2);};
if ( typeof addLoadEvent != 'undefined' ) addLoadEvent(load_cmc);
else load_cmc();
</script>
Minified using apc </body>
Served from: jmonkeyengine.org @ 2011-04-05 22:34:18 --> </html>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtmlbody">view online version</a></em></p>

@ -1,54 +1,42 @@
<h1><a
<h1><a>Optimization reference</a></h1> name="optimization_reference">Optimization reference</a></h1><div
<div> class="level1"><p> This page is intended as a reference collection of optimization tricks that can be used to speed up JME3 applications.</p></div><h2><a
name="maintain_low_geometry_count">Maintain low Geometry count</a></h2><div
<p> class="level2"><p> The more Geometry objects are added to the scene, the harder it gets to handle them in a speedy fashion.
The reson for this is, that for every object a render command must be done, here is a bottleneck betwenn the CPU and the Graficcard. <strong>Possible optimization techniques</strong></p><ul><li
This page is intended as a reference collection of optimization tricks that can be used to speed up JME3 applications. class="level1"><div
</p> class="li"> Use GeometryBatchFactory.optimize(node) to merge the meshes of the geometries contained in the given node into fewer batches (based on common Material used).</div></li></ul><p> <strong>Side-effects</strong></p><ul><li
class="level1"><div
</div> class="li"> Using GeometryBatchFactory merges individual Geometries into a single mesh. Thereby it becomes hard to apply specific Materials or to remove a single Geometry. Therefore it should be used for static Geometry only that does not require frequent changes or individual materials/texturing.</div></li><li
class="level1"><div
<h2><a>Maintain low Geometry count</a></h2> class="li">Using Texture atlases might be a way to provide a limited individual texturing.</div></li></ul></div><h2><a
<div> name="avoid_creating_new_objects">Avoid creating new objects</a></h2><div
class="level2"><p> When you use math operations like vectorA.mult(vectorB); new objects are created that have to be garbage collected when you don&#039;t use them anymore. Check your math operations for opportunities to use the local version of the math operations, e.g. vectorA.multLocal(vectorB). This way the result is stored in vectorA and no new object needs to be created.</p></div><h2><a
<p> name="check_the_statistics">Check the Statistics</a></h2><div
class="level2"><p> SimpleApplication displays a HUD with statistics. Use <code>app.setDisplayStatView(true);</code> to activate it, and false to deactivate it.
The more Geometry objects are added to the scene, the harder it gets to handle them in a speedy fashion. It counts how many FrameBuffers, Textures, or Shaders…</p><ul><li
The reson for this is, that for every object a render command must be done, here is a bottleneck betwenn the CPU and the Graficcard. class="level1"><div
</p> class="li"> … were switched in the last frame (S)</div></li><li
class="level1"><div
<p> class="li"> … were used during the last frame (F)</div></li><li
<strong>Possible optimization techniques</strong> class="level1"><div
</p> class="li"> … exist in memory (M)</div></li></ul><p> Example:</p><ul><li
<ul> class="level1"><div
<li><div> Use GeometryBatchFactory.optimize(node) to merge the meshes of the geometries contained in the given node into fewer batches (based on common Material used).</div> class="li"> Textures (M) = how many textures are currently in the OpenGL driver</div></li><li
</li> class="level1"><div
</ul> class="li"> Textures(F) = how many textures were used in the last frame</div></li><li
class="level1"><div
<p> class="li"> Textures(S) = how many texture switches were done in the last frame.</div></li></ul><p> Genereally jME3 is well optimized and optimizes these things correctly. The normal state is that the (S/F/M) values should be in the same order of magnitude; (S) values can be lower than (F).</p><ul><li
class="level1"><div
<strong>Side-effects</strong> class="li"> If the (S) values are significantly higher than the (F) values, that means there are a lot of extra switches happening which can cause a performance loss. Switches happen for instance if you have many transparent materials in your scene. In that case this tells you that you should use fewer transparent materials.</div></li><li
</p> class="level1"><div
<ul> class="li"> If the (M) values are much higher than the (F) values, that means a lot more GL objects are in memory than are actually used. This can happen in rare cases, such as extremely large scenes (&gt; 2000 wu). In this case, you should can optimize performance by identifying spatials to cull or detach.</div></li><li
<li><div> Using GeometryBatchFactory merges individual Geometries into a single mesh. Thereby it becomes hard to apply specific Materials or to remove a single Geometry. Therefore it should be used for static Geometry only that does not require frequent changes or individual materials/texturing.</div> class="level1"><div
</li> class="li"> The Object Count (Batch Count) is a very important value that indicates how many geometries were rendered in the last frame. In general, try to keep the object count around 100-200 to keep your game fast and responsive. If the count is permanently higher, optimize your scene via GeometryBatchFactory or other means.</div></li><li
<li><div>Using Texture atlases might be a way to provide a limited individual texturing.</div> class="level1"><div
</li> class="li"> Same for Triangle Counts. If your game runs sluggishly and triangle count is high, then you are rendering too many too detailed meshes.</div></li><li
</ul> class="level1"><div
class="li"> FrameBuffers: If you don&#039;t use any post-processing effects (FilterPostProcessor), this count should be zero. The more effects you use, the more FrameBuffers are in use.</div></li></ul><div
</div> class="tags"><span> <a
href="/wiki/doku.php/tag:performance?do=showtag&amp;tag=tag%3Aperformance">performance</a> </span></div></div>
<h2><a>Avoid creating new objects</a></h2>
<div>
<p>
When you use math operations like vectorA.mult(vectorB); new objects are created that have to be garbage collected when you don&#039;t use them anymore. Check your math operations for opportunities to use the local version of the math operations, e.g. vectorA.multLocal(vectorB). This way the result is stored in vectorA and no new object needs to be created.
</p>
<div><span>
<a href="/wiki/doku.php/tag:performance?do=showtag&amp;tag=tag%3Aperformance">performance</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:optimization?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:optimization?do=export_xhtmlbody">view online version</a></em></p>

@ -1,284 +1,219 @@
<h1><a
<h1><a>Application and SimpleApplication</a></h1> name="application_and_simpleapplication">Application and SimpleApplication</a></h1><div
<div> class="level1"><p> The base classes of the jMonkeyEngine3 are <code>com.jme3.app.Application</code> and its subclass <code>com.jme3.app.SimpleApplication</code>. SimpleApplication extends Application, and offers everything that Application offers, plus pre-configured features such as a scene graph and a flyby cam.
Your game class typically extends com.jme3.app.SimpleApplication. You call app.start() and app.stop() on your game instance to start or quit the application. The following code sample shows the typical base structure of a jME3 game:</p><pre>import com.jme3.app.SimpleApplication;
<p>
The base classes of the jMonkeyEngine3 are <code>com.jme3.app.Application</code> and its subclass <code>com.jme3.app.SimpleApplication</code>. SimpleApplication extends Application, and offers everything that Application offers, plus pre-configured features such as a scene graph and a flyby cam.
</p>
<p>
Your game class typically extends com.jme3.app.SimpleApplication. You call app.start() and app.stop() on your game instance to start or quit the application. The following code sample shows the typical base structure of a jME3 game:
</p>
<pre>import com.jme3.app.SimpleApplication;
&nbsp;
public class HelloWorld extends SimpleApplication &#123; public class HelloWorld extends SimpleApplication &#123;
&nbsp;
public static void main&#40;String&#91;&#93; args&#41;&#123; public static void main&#40;String&#91;&#93; args&#41;&#123;
HelloWorld app = new HelloWorld&#40;&#41;; HelloWorld app = new HelloWorld&#40;&#41;;
app.start&#40;&#41;; app.start&#40;&#41;;
&#125; &#125;
&nbsp;
@Override @Override
public void simpleInitApp&#40;&#41; &#123; public void simpleInitApp&#40;&#41; &#123;
/* Initialize the game scene here */ /* Initialize the game scene here */
&#125; &#125;
&nbsp;
@Override @Override
public void simpleUpdate&#40;float tpf&#41; &#123; public void simpleUpdate&#40;float tpf&#41; &#123;
/* (optional) Interact with game events in the main loop */ /* (optional) Interact with game events in the main loop */
&#125; &#125;
&nbsp;
@Override @Override
public void simpleRender&#40;RenderManager rm&#41; &#123; public void simpleRender&#40;RenderManager rm&#41; &#123;
/* (optional) Make advanced modifications to frameBuffer and scene graph. */ /* (optional) Make advanced modifications to frameBuffer and scene graph. */
&#125; &#125;
&#125;</pre> &#125;</pre><p> Let&#039;s have a look at what the base classes have to offer.</p></div><h2><a
<p> name="application_class">Application Class</a></h2><div
Let&#039;s have a look at what the base classes have to offer. class="level2"><p> The com.jme3.app.Application class represents an instance of a real-time 3D rendering jME3 application. A com.jme3.app.Application provides all the tools that are commonly used in jME3 applications.</p><div
</p> class="table sectionedit1"><table
class="inline"><tr
</div> class="row0"><th
class="col0">Class field or method</th><th
<h2><a>Application Class</a></h2> class="col1">Purpose</th></tr><tr
<div> class="row1"><td
class="col0">context</td><td
<p> class="col1">The application context contains renderer, <a
href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a>, timer, etc. The context object is not usually directly accessed by users.</td></tr><tr
The com.jme3.app.Application class represents an instance of a real-time 3D rendering jME3 application. A com.jme3.app.Application provides all the tools that are commonly used in jME3 applications. class="row2"><td
class="col0">getRenderManager() <br/> getRenderer();</td><td
</p> class="col1">Low-level and high-level rendering interface.</td></tr><tr
<table> class="row3"><td
<tr> class="col0">getStateManager()</td><td
<th>Class field or method</th><th>Purpose</th> class="col1">The Application state manager is used to activate <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">physics</a>.</td></tr><tr
<tr> class="row4"><td
<td>context</td><td>The application context contains renderer, <a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a>, timer, etc. The context object is not usually directly accessed by users.</td> class="col0">viewPort</td><td
</tr> class="col1">The view object for the default camera.</td></tr><tr
<tr> class="row5"><td
<td>getRenderManager() <br/> class="col0">guiViewPort</td><td
getRenderer();</td><td>Low-level and high-level rendering interface.</td> class="col1">The view object for the orthogonal <acronym
</tr> title="Graphical User Interface">GUI</acronym> view. Used internally for <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a>s.</td></tr><tr
<td>getStateManager()</td><td>The Application state manager is used to activate <a href="/com/jme3/gde/core/docs/jme3/advanced/physics.html">physics</a>.</td> class="row6"><td
</tr> class="col0">settings <br/> setSettings()</td><td
<tr> class="col1">The <a
<td>viewPort</td><td>The view object for the default camera.</td> href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> let you specify the display width and height (by default 640x480), color bit depth, z-buffer bits, anti-aliasing samples, and update frequency, video and audio renderer, asset manager.</td></tr><tr
</tr> class="row7"><td
<tr> class="col0">timer</td><td
<td>guiViewPort</td><td>The view object for the orthogonal <acronym title="Graphical User Interface">GUI</acronym> view. Used internally for <a href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a>s. </td> class="col1">Internal update loop timer. Users have access to the tpf float variable in the simpleUpdate() loop to time actions.</td></tr><tr
</tr> class="row8"><td
<tr> class="col0">cam</td><td
<td>settings <br/> class="col1">The default <a
setSettings()</td><td>The <a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> let you specify the display width and height (by default 640&times;480), color bit depth, z-buffer bits, anti-aliasing samples, and update frequency, video and audio renderer, asset manager.</td> href="/com/jme3/gde/core/docs/jme3/advanced/camera.html">camera</a> with perspective projection, 45° field of view, near plane = 1 wu, far plane = 1000 wu.</td></tr><tr
</tr> class="row9"><td
<tr> class="col0">assetManager <br/> getAssetManager()</td><td
<td>timer</td><td>Internal update loop timer. Users have access to the tpf float variable in the simpleUpdate() loop to time actions.</td> class="col1">An object that manages paths for loading models, textures, materials, sounds, etc. By default the <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/assetmanager.html">AssetManager</a> paths are relative to your projects root directory.</td></tr><tr
<tr> class="row10"><td
<td>cam</td><td>The default <a href="/com/jme3/gde/core/docs/jme3/advanced/camera.html">camera</a> with perspective projection, 45° field of view, near plane = 1 wu, far plane = 1000 wu.</td> class="col0">getAudioRenderer() <br/> getListener()</td><td
</tr> class="col1">The <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">audio</a> system.</td></tr><tr
<td>assetManager <br/> class="row11"><td
getAssetManager()</td><td>An object that manages paths for loading models, textures, materials, sounds, etc. By default the <a href="/com/jme3/gde/core/docs/jme3/advanced/assetmanager.html">AssetManager</a> paths are relative to your projects root directory.</td> class="col0">keyInput <br/> mouseInput <br/> joyInput</td><td
</tr> class="col1">Default input contexts for keyboard, mouse, and joystick</td></tr><tr
<tr> class="row12"><td
<td>getAudioRenderer() <br/> class="col0">getInputManager()</td><td
getListener()</td><td>The <a href="/com/jme3/gde/core/docs/jme3/advanced/audio.html">audio</a> system.</td> class="col1">Use the <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">inputManager</a> to configure your custom inputs.</td></tr><tr
<tr> class="row13"><td
<td>keyInput <br/> class="col0">inputEnabled</td><td
mouseInput <br/> class="col1">Set this boolean whether the system should listen for user inputs (or instead just play a non-interactive scene).</td></tr><tr
joyInput</td><td>Default input contexts for keyboard, mouse, and joystick</td> class="row14"><td
</tr> class="col0">setPauseOnLostFocus()</td><td
<tr> class="col1">Set this boolean whether the game should pause when ever the window loses focus.</td></tr><tr
<td>getInputManager()</td><td>Use the <a href="/com/jme3/gde/core/docs/jme3/advanced/input_handling.html">inputManager</a> to configure your custom inputs.</td> class="row15"><td
</tr> class="col0">paused</td><td
<tr> class="col1">Set this boolean during runtime to pause/unpause a game.</td></tr><tr
<td>inputEnabled</td><td>Set this boolean whether the system should listen for user inputs (or instead just play a non-interactive scene).</td> class="row16"><td
</tr> class="col0">start() <br/> start(jMEContextType)</td><td
<tr> class="col1">Call this method to start a jME3 game. By default this opens a new jME3 window, initializes the scene, and starts the event loop. Can optionally accept com.jme3.system.JmeContext.Type.* as argument to run headless or embedded. (See below.)</td></tr><tr
<td>setPauseOnLostFocus()</td><td>Set this boolean whether the game should pause when ever the window loses focus.</td> class="row17"><td
</tr> class="col0">restart()</td><td
<tr> class="col1">Reloads the <a
<td>paused</td><td>Set this boolean during runtime to pause/unpause a game.</td> href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> into the current application context.</td></tr><tr
</tr> class="row18"><td
<tr> class="col0">stop()</td><td
<td>start() <br/> class="col1">Stops the running jME3 game and closes the jME3 window.</td></tr></table></div><p> The jME Context Type (com.jme3.system.JmeContext.Type.*) is one of the following:</p><ul><li
start(jMEContextType)</td><td>Call this method to start a jME3 game. By default this opens a new jME3 window, initializes the scene, and starts the event loop. Can optionally accept com.jme3.system.JmeContext.Type.* as argument to run headless or embedded. (See below.)</td> class="level1"><div
</tr> class="li"> Display – jME application runs in a window of its own. This is the Default.</div></li><li
<tr> class="level1"><div
<td>restart()</td><td>Reloads the <a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> into the current application context.</td> class="li"> Canvas – jME application is embedded in a <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/swing_canvas.html">Swing Canvas</a>)</div></li><li
<tr> class="level1"><div
<td>stop()</td><td>Stops the running jME3 game and closes the jME3 window.</td> class="li"> Headless – jME application runs its event loop without calculating any view and without opening any window. Can be used for a <a
</tr> href="/com/jme3/gde/core/docs/jme3/intermediate/headlessserver.html">Headless Server</a> application.</div></li><li
</table> class="level1"><div
class="li"> OffscreenSurface – jME application view is not shown, but calculated and cached as bitmap (back buffer).</div></li></ul><p> You can switch Context Types when starting the application, for example: <code>app.start(JmeContext.Type.Headless);</code> See also: <a
<p> href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a></p></div><h2><a
name="simpleapplication_class">SimpleApplication Class</a></h2><div
The jME Context Type (com.jme3.system.JmeContext.Type.*) is one of the following: class="level2"><p> The com.jme3.app.SimpleApplication class extends the com.jme3.app.Application class to provide default functionality like a first-person (fly-by) camera, and a scenegraph with a rootNode that is updated and rendered regularly.
</p> By default, a SimpleApplication displays statistics (such as frames per second) on-screen, using the com.jme3.app.StatsView class. You deactivate the statistics HUD by calling <code>app.setDisplayFps(false);
<ul> app.setDisplayStatView(false);</code>.
<li><div> Display – jME application runs in a window of its own. This is the Default.</div>
</li>
<li><div> Canvas – jME application is embedded in a <a href="/com/jme3/gde/core/docs/jme3/advanced/swing_canvas.html">Swing Canvas</a>)</div>
</li>
<li><div> Headless – jME application runs its event loop without calculating any view and without opening any window. Can be used for a <a href="/com/jme3/gde/core/docs/jme3/intermediate/headlessserver.html">Headless Server</a> application.</div>
</li>
<li><div> OffscreenSurface – jME application view is not shown, but calculated and cached as bitmap (back buffer).</div>
</li>
</ul>
<p>
You can switch Context Types when starting the application, for example: <code>app.start(JmeContext.Type.Headless);</code>
</p>
<p>
See also: <a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a>
</p>
</div>
<h2><a>SimpleApplication Class</a></h2>
<div>
<p>
The com.jme3.app.SimpleApplication class extends the com.jme3.app.Application class to provide default functionality like a first-person (fly-by) camera, and a scenegraph with a rootNode that is updated and rendered regularly.
</p>
<p>
By default, a SimpleApplication displays statistics (such as frames per second) on-screen, using the com.jme3.app.StatsView class. You deactivate the statistics view by calling <code>getGuiNode().detachAllChildren();</code>.
</p>
<p>
Some input keys are pre-configured by default: You quit the application by pressing the Escape key, and you can control the camera using the mouse, the arrow keys, and WASD keys. (More details below.) Some input keys are pre-configured by default: You quit the application by pressing the Escape key, and you can control the camera using the mouse, the arrow keys, and WASD keys. (More details below.)
</p> Additional to what Application offers, SimpleApplication offers:</p><div
class="table sectionedit2"><table
<p> class="inline"><tr
Additional to what Application offers, SimpleApplication offers: class="row0"><th
class="col0">SimpleApplication Feature</th><th
</p> class="col1">Purpose</th></tr><tr
<table> class="row1"><td
<tr> class="col0">getRootNode() <br/> rootNode</td><td
<th>SimpleApplication Feature</th><th>Purpose</th> class="col1">The root node of the scene graph. A Spatial that you attach to the rootNode appears in the 3D scene.</td></tr><tr
</tr> class="row2"><td
<tr> class="col0">getGuiNode() <br/> guiNode</td><td
<td>getRootNode() <br/> class="col1">Attach flat <acronym
rootNode</td><td>The root node of the scene graph. A Spatial that you attach to the rootNode appears in the 3D scene.</td> title="Graphical User Interface">GUI</acronym> elements (such as <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a> images and text) to this orthogonal <acronym
<tr> title="Graphical User Interface">GUI</acronym> node.</td></tr><tr
<td>getGuiNode() <br/> class="row3"><td
guiNode</td><td>Attach flat <acronym title="Graphical User Interface">GUI</acronym> elements (such as <a href="/com/jme3/gde/core/docs/jme3/advanced/hud.html">HUD</a> images and text) to this orthogonal <acronym title="Graphical User Interface">GUI</acronym> node.</td> class="col0">loadStatsView()</td><td
</tr> class="col1">Call this method to print live statistic information to the screen, such as current frames-per-second and triangles/vertices counts. Use this info during the development phase.</td></tr><tr
<tr> class="row4"><td
<td>loadStatsView()</td><td>Call this method to print live statistic information to the screen, such as current frames-per-second and triangles/vertices counts. You deactivate this statistics view by calling <code>getGuiNode().detachAllChildren();</code>. </td> class="col0">setDisplayFps(false); <br/> setDisplayStatView(false);</td><td
</tr> class="col1">Call these method to remove the statistic information from the screen, for example, before releases.</td></tr><tr
<tr> class="row5"><td
<td>getFlyByCamera() <br/> class="col0">getFlyByCamera() <br/> flyCam</td><td
flyCam</td><td>The default fly-by camera object, controlled by the WASD and arrow keys.</td> class="col1">The default fly-by camera object, controlled by the WASD and arrow keys.</td></tr><tr
</tr> class="row6"><td
<tr> class="col0">setShowSettings(true)</td><td
<td>setShowSettings(true)</td><td>Whether the user should be presented with a splashscreen and display settings dialog when starting the game. Set this boolean before calling start() on the SimpleApplication.</td> class="col1">Whether the user should be presented with a splashscreen and display settings dialog when starting the game. Set this boolean before calling start() on the SimpleApplication.</td></tr><tr
</tr> class="row7"><td
<tr> class="col0">simpleInitApp()</td><td
<td>simpleInitApp()</td><td>Override this method to initialize the game scene. Here you load and create objects, attach Spatials to the rootNode, and bring everything in its starts position.</td> class="col1">Override this method to initialize the game scene. Here you load and create objects, attach Spatials to the rootNode, and bring everything in its starts position.</td></tr><tr
</tr> class="row8"><td
<tr> class="col0">simpleUpdate(float tpf)</td><td
<td>simpleUpdate(float tpf)</td><td>Override this method to have access to the main event loop. Use this loop to poll the current game state and respond to changes, or to initiate state changes and to generate encounters. For advanced info how to hook into the update loop, see also <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a>. </td> class="col1">Override this method to have access to the main event loop. Use this loop to poll the current game state and respond to changes, or to initiate state changes and to generate encounters. For advanced info how to hook into the update loop, see also <a
</tr> href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> and <a
<tr> href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a>.</td></tr><tr
<td>simpleRender()</td><td>Optionally, override this method to do advanced modifications to the frameBuffer and scene graph.</td> class="row9"><td
</tr> class="col0">simpleRender()</td><td
</table> class="col1">Optionally, override this method to do advanced modifications to the frameBuffer and scene graph.</td></tr></table></div></div><h3><a
name="input_defaults">Input Defaults</a></h3><div
</div> class="level3"><p> The following default actions are available for a running game:</p><div
class="table sectionedit3"><table
<h3><a>Input Defaults</a></h3> class="inline"><tr
<div> class="row0"><th
class="col0">Key</th><th
<p> class="col1">Action</th></tr><tr
class="row1"><td
The following default actions are available for a running game: class="col0">KEY_ESCAPE</td><td
class="col1">Quits the game by calling <code>app.stop()</code></td></tr><tr
</p> class="row2"><td
<table> class="col0">KEY_C</td><td
<tr> class="col1">Prints camera position, rotation, and direction</td></tr><tr
<th>Key</th><th>Action</th> class="row3"><td
</tr> class="col0">KEY_M</td><td
<tr> class="col1">Prints memory usage stats</td></tr></table></div><p> If useInput() is true, the default Flyby Cam is active. Then the following so-called &quot;WASD&quot; inputs are additionally available:</p><div
<td>KEY_ESCAPE</td><td>Quits the game by calling <code>app.stop()</code></td> class="table sectionedit4"><table
</tr> class="inline"><tr
<tr> class="row0"><th
<td>KEY_C</td><td>Prints camera position, rotation, and direction</td> class="col0">Camera Motion</th><th
</tr> class="col1">Key or Mouse Input</th></tr><tr
<tr> class="row1"><td
<td>KEY_M</td><td>Prints memory usage stats</td> class="col0">Move Forward</td><td
</tr> class="col1">KEY_W</td></tr><tr
</table> class="row2"><td
class="col0">Move Left (Strafe)</td><td
<p> class="col1">KEY_A</td></tr><tr
class="row3"><td
If useInput() is true, the default Flyby Cam is active. Then the following so-called “WASD” inputs are additionally available: class="col0">Move Backward</td><td
class="col1">KEY_S</td></tr><tr
</p> class="row4"><td
<table> class="col0">Move Right (Strafe)</td><td
<tr> class="col1">KEY_D</td></tr><tr
<th>Camera Motion</th><th>Key or Mouse Input</th> class="row5"><td
</tr> class="col0">Move Vertical Upward</td><td
<tr> class="col1">KEY_Q</td></tr><tr
<td>Move Forward</td><td>KEY_W</td> class="row6"><td
</tr> class="col0">Move Vertical Downward</td><td
<tr> class="col1">KEY_Z</td></tr><tr
<td>Move Left (Strafe)</td><td>KEY_A</td> class="row7"><td
</tr> class="col0">Rotate Left</td><td
<tr> class="col1">KEY_LEFT, or move mouse horizontally left (-x)</td></tr><tr
<td>Move Backward</td><td>KEY_S</td> class="row8"><td
</tr> class="col0">Rotate Right</td><td
<tr> class="col1">KEY_RIGHT, or move mouse horizontally right (+x)</td></tr><tr
<td>Move Right (Strafe)</td><td>KEY_D</td> class="row9"><td
</tr> class="col0">Rotate Up</td><td
<tr> class="col1">KEY_UP, or move mouse vertically forward (+y)</td></tr><tr
<td>Move Vertical Upward</td><td>KEY_Q</td> class="row10"><td
</tr> class="col0">Rotate Down</td><td
<tr> class="col1">KEY_DOWN, or move mouse vertically backward (-y)</td></tr><tr
<td>Move Vertical Downward</td><td>KEY_Z</td> class="row11"><td
</tr> class="col0">Zoom In</td><td
<tr> class="col1">Scroll mouse wheel backward</td></tr><tr
<td>Rotate Left</td><td>KEY_LEFT, or move mouse horizontally left (-x)</td> class="row12"><td
</tr> class="col0">Zoom Out</td><td
<tr> class="col1">Scroll mouse wheel forward</td></tr><tr
<td>Rotate Right</td><td>KEY_RIGHT, or move mouse horizontally right (+x)</td> class="row13"><td
</tr> class="col0">Rotate drag</td><td
<tr> class="col1">Hold left mouse button and move</td></tr></table></div><div
<td>Rotate Up</td><td>KEY_UP, or move mouse vertically forward (+y)</td> class="tags"><span> <a
</tr> href="/wiki/doku.php/tag:display?do=showtag&amp;tag=tag%3Adisplay">display</a>, <a
<tr> href="/wiki/doku.php/tag:basegame?do=showtag&amp;tag=tag%3Abasegame">basegame</a>, <a
<td>Rotate Down</td><td>KEY_DOWN, or move mouse vertically backward (-y)</td> href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>, <a
</tr> href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>, <a
<tr> href="/wiki/doku.php/tag:intermediate?do=showtag&amp;tag=tag%3Aintermediate">intermediate</a>, <a
<td>Zoom In</td><td>Scroll mouse wheel backward</td> href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>, <a
</tr> href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>, <a
<tr> href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>, <a
<td>Zoom Out</td><td>Scroll mouse wheel forward</td> href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>, <a
</tr> href="/wiki/doku.php/tag:rootnode?do=showtag&amp;tag=tag%3Arootnode">rootnode</a> </span></div></div>
<tr>
<td>Rotate drag</td><td>Hold left mouse button and move</td>
</tr>
</table>
<div><span>
<a href="/wiki/doku.php/tag:display?do=showtag&amp;tag=tag%3Adisplay">display</a>,
<a href="/wiki/doku.php/tag:basegame?do=showtag&amp;tag=tag%3Abasegame">basegame</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:intermediate?do=showtag&amp;tag=tag%3Aintermediate">intermediate</a>,
<a href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>,
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>,
<a href="/wiki/doku.php/tag:rootnode?do=showtag&amp;tag=tag%3Arootnode">rootnode</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:simpleapplication?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:simpleapplication?do=export_xhtmlbody">view online version</a></em></p>

@ -1,25 +1,10 @@
<h3><a
<h3><a>Terrain Collision</a></h3> name="terrain_collision">Terrain Collision</a></h3><div
<div> class="level3"><p> <strong>*Work in progress</strong>*</p><p> This page will extend (not the Java keyword!) the Hello_Terrain tutorial in a few small ways in order to show you a quick way to create a Collision Shape out of the map we have generated. A Collision Shape allows a player (who is also a Collision Shape in this tutorial) to collide with the map, i.e. clip, walk on, stand on, etc. in order to create the type of world and interactivity most gamers are familiar with in FPS or MMOs.</p><div
class="tags"><span> <a
<p> href="/wiki/doku.php/tag:about?do=showtag&amp;tag=tag%3Aabout">about</a> </span></div></div><h3><a
name="sample_code">Sample Code</a></h3><div
<strong>*Work in progress</strong>* class="level3"><pre>package mygame;
</p>
<p>
This page will extend (not the Java keyword!) the Hello_Terrain tutorial in a few small ways in order to show you a quick way to create a Collision Shape out of the map we have generated. A Collision Shape allows a player (who is also a Collision Shape in this tutorial) to collide with the map, i.e. clip, walk on, stand on, etc. in order to create the type of world and interactivity most gamers are familiar with in FPS or MMOs.
</p>
<div><span>
<a href="/wiki/doku.php/tag:about?do=showtag&amp;tag=tag%3Aabout">about</a>
</span></div>
</div>
<h3><a>Sample Code</a></h3>
<div>
<pre>package mygame;
&nbsp; &nbsp;
import jme3tools.converters.ImageToAwt; import jme3tools.converters.ImageToAwt;
import com.jme3.app.SimpleBulletApplication; import com.jme3.app.SimpleBulletApplication;
@ -191,112 +176,29 @@ public class Main extends SimpleBulletApplication &#123;
&#125; &#125;
&#125; &#125;
&#125;; &#125;;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="what_s_going_on">What&#039;s Going On?</a></h3><div
class="level3"><p> To try this code, go into a New Project → JME3 → BasicGame using the default settings (if you haven&#039;t already made a default project before) the name should be BasicGame and the package would be called myGame, then just paste this over the entire preconstructed main.java text. Then Add the jme3-test-data library which is available through your library list. This should compile and run from there.</p></div><h3><a
<h3><a>What&#039;s Going On?</a></h3> name="explaining_the_code">Explaining the Code</a></h3><div
<div> class="level3"><p> I will only briefly describe the sections that are covered in the original Hello_Terrain. Most detail will be given to the additives.</p><p> Imports are to bring in the appropriate class definitions.</p><pre>private TerrainQuad terrain;</pre><p> Holds our map.</p><pre>PhysicsCharacterNode player;</pre><p> Creates our character in the style of FPS that many gamers are familiar with.</p><pre>Boolean left = false, right = false, up = false, down = false;</pre><p> Variables for creating fluid movement.</p><pre>private Vector3f walkDirection = new Vector3f&#40;&#41;;</pre><p> The direction we determine from combinations of the booleans.</p><p> The main function is standard.
In simpleInit we run setupKeys() first and create the common WASD and SPACEBAR to jump.</p><pre>inputManager.addListener(actionListener, new String[]{&quot;Lefts&quot;, &quot;Rights&quot;, &quot;Ups&quot;, &quot;Downs&quot;, &quot;Jumps&quot;})</pre><p> This line indicates our actionListener function and what to do when each command (the string names) is sent.</p><p> The onAction function basically sets the booleans true based on which directions we&#039;re pressing or makes us jump.
<p> The simpleUpdate function constants changed our direction based on the boolean (ie the directions) we&#039;re pressing.</p><p> The real collisioning happens in these parts;</p><pre>player = new PhysicsCharacterNode(new CapsuleCollisionShape(1.2f, 3f, 1), .05f);
To try this code, go into a New Project → JME3 → BasicGame using the default settings (if you haven&#039;t already made a default project before) the name should be BasicGame and the package would be called myGame, then just paste this over the entire preconstructed main.java text. Then Add the jme3-test-data library which is available through your library list. This should compile and run from there.
</p>
</div>
<h3><a>Explaining the Code</a></h3>
<div>
<p>
I will only briefly describe the sections that are covered in the original Hello_Terrain. Most detail will be given to the additives.
</p>
<p>
Imports are to bring in the appropriate class definitions.
</p>
<pre>private TerrainQuad terrain;</pre>
<p>
Holds our map.
</p>
<pre>PhysicsCharacterNode player;</pre>
<p>
Creates our character in the style of FPS that many gamers are familiar with.
</p>
<pre>Boolean left = false, right = false, up = false, down = false;</pre>
<p>
Variables for creating fluid movement.
</p>
<pre>private Vector3f walkDirection = new Vector3f&#40;&#41;;</pre>
<p>
The direction we determine from combinations of the booleans.
</p>
<p>
The main function is standard.
In simpleInit we run setupKeys() first and create the common WASD and SPACEBAR to jump.
</p>
<pre>inputManager.addListener(actionListener, new String[]{&quot;Lefts&quot;, &quot;Rights&quot;, &quot;Ups&quot;, &quot;Downs&quot;, &quot;Jumps&quot;})</pre>
<p>
This line indicates our actionListener function and what to do when each command (the string names) is sent.
</p>
<p>
The onAction function basically sets the booleans true based on which directions we&#039;re pressing or makes us jump.
The simpleUpdate function constants changed our direction based on the boolean (ie the directions) we&#039;re pressing.
</p>
<p>
The real collisioning happens in these parts;
</p>
<pre>player = new PhysicsCharacterNode(new CapsuleCollisionShape(1.2f, 3f, 1), .05f);
rootNode.attachChild(player); rootNode.attachChild(player);
getPhysicsSpace().add(player); getPhysicsSpace().add(player);
HeightfieldCollisionShape sceneShape = new HeightfieldCollisionShape(heightmap.getHeightMap()); HeightfieldCollisionShape sceneShape = new HeightfieldCollisionShape(heightmap.getHeightMap());
landscape = new PhysicsNode(terrain, sceneShape, 0); landscape = new PhysicsNode(terrain, sceneShape, 0);
landscape.setLocalTranslation(0, -100, 0); landscape.setLocalTranslation(0, -100, 0);
rootNode.attachChild(landscape); rootNode.attachChild(landscape);
getPhysicsSpace().add(landscape);</pre> getPhysicsSpace().add(landscape);</pre><p> The first chunk makes our player into a collision shape that&#039;s a capsule, kinda like a human right? And then attaches it to the rootNode and gets it&#039;s physics (important!).
<p>
The first chunk makes our player into a collision shape that&#039;s a capsule, kinda like a human right? And then attaches it to the rootNode and gets it&#039;s physics (important!).
The second chunk feeds the heightmap we made into a heightfield collision shape generator to create the collidable shape of the land mass. The second chunk feeds the heightmap we made into a heightfield collision shape generator to create the collidable shape of the land mass.
The third chunk sets our land and it&#039;s collision down some, attaches em to root, and gets the physics. The third chunk sets our land and it&#039;s collision down some, attaches em to root, and gets the physics.</p></div><h3><a
</p> name="conclusion">Conclusion</a></h3><div
class="level3"><p> You should spawn high up in the area and fall down to the map, giving you a few seconds to survey the domain. Then walk around and see how you like the lay of the land.</p><hr
</div> /><p> See also:</p><ul><li
class="level1"><div
<h3><a>Conclusion</a></h3> class="li"> <a
<div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a>,</div></li><li
class="level1"><div
<p> class="li"> <a
You should spawn high up in the area and fall down to the map, giving you a few seconds to survey the domain. Then walk around and see how you like the lay of the land. href="/com/jme3/gde/core/docs/jme3/advanced/terrain.html">Terrain</a></div></li></ul></div>
</p>
<hr />
<p>
See also:
</p>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_terrain.html">Hello Terrain</a>,</div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/terrain.html">Terrain</a></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:terrain_collision?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:terrain_collision?do=export_xhtmlbody">view online version</a></em></p>

File diff suppressed because it is too large Load Diff

@ -1,622 +1,261 @@
<h1><a
<h1><a>3D Game Development Terminology</a></h1> name="d_game_development_terminology">3D Game Development Terminology</a></h1><div
<div> class="level1"><p> Before you start, make certain you are familiar with the following concepts and terminology.</p></div><h1><a
name="d_graphics_and_audio">3D Graphics and Audio</a></h1><div
<p> class="level1"><p> <strong>OpenGL</strong> is the Open Graphics Library, a platform-independent specification for rendering 2D/3D computer graphics. For Java, there are two implementations of OpenGL-based renderers:</p><ol><li
class="level1"><div
Before you start, make certain you are familiar with the following concepts and terminology. class="li"> Lightweight Java Game Library (LWJGL)</div></li><li
</p> class="level1"><div
class="li"> Java OpenGL (JOGL)</div></li></ol><p> <strong>OpenAL</strong> is the Open Audio Library, a platform-independent 3D audio <acronym
</div> title="Application Programming Interface">API</acronym>.</p></div><h1><a
name="context_display_renderer">Context, Display, Renderer</a></h1><div
<h1><a>3D Graphics and Audio</a></h1> class="level1"><p> The <strong>jME Context</strong> makes settings, renderer, timer, input and event listeners, display system, accessible to a JME game.</p><ul><li
<div> class="level1"><div
class="li"> The <strong>jME Display System</strong> is what draws the custom JME window (instead of Java Swing).</div></li><li
<p> class="level1"><div
class="li"> The <strong>input system</strong> is what lets you respond to user input via mouse, keyboard, and joystick.</div></li><li
<strong>OpenGL</strong> is the Open Graphics Library, a platform-independent specification for rendering 2D/3D computer graphics. For Java, there are two implementations of OpenGL-based renderers: class="level1"><div
</p> class="li"> The <strong>renderer</strong> is what does all the work of calculating how to draw the 3D scenegraph to the 2D screen.</div><ul><li
<ol> class="level2"><div
<li><div> Lightweight Java Game Library (LWJGL)</div> class="li"> The <strong>Shader</strong> is a programmable part of the rendering pipeline. The jME3 game engine uses it to offer advanced customizable materials.</div></li></ul></li></ul></div><h1><a
</li> name="geometry">Geometry</a></h1><div
<li><div> Java OpenGL (JOGL)</div> class="level1"></div><h2><a
</li> name="coordinates">Coordinates</a></h2><div
</ol> class="level2"><p> Coordinates represent a location in a coordinate system, relative to the origin (0,0,0). m. In 3D space, you need to specify three coordinate values to locate a point: x,y,z.
As opposed to a vector (which looks similar), a coordinate does not have a &quot;direction&quot;. <a
<p> href="/wiki/lib/exe/detail.php/jme3:intermediate:coordinate-system.png?id=jme3%3Aterminology"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/coordinate-system.png?w=235&amp;h=210" class="mediaright" align="right" alt="" width="235" height="210" /></a></p></div><h3><a
<strong>OpenAL</strong> is the Open Audio Library, a platform-independent 3D audio <acronym title="Application Programming Interface">API</acronym>. name="the_origin">The Origin</a></h3><div
</p> class="level3"><p> The origin is the central point in the 3D world. It&#039;s at the coordinates (0,0,0).
Code sample: <code>Vector3f origin = new Vector3f( Vector3f.ZERO );</code></p></div><h2><a
</div> name="vectors">Vectors</a></h2><div
class="level2"><p> A vector has a length and a direction. It is used like an arrow pointing at a point in 3D space. A vector starts at the origin (0,0,0), and ends at the target coordinate (x,y,z). Backwards directions are expressed with negative values.
<h1><a>Context, Display, Renderer</a></h1> Code sample: <code>Vector3f v = new Vector3f( 17 , -4 , 0 );</code></p></div><h3><a
<div> name="unit_vectors">Unit Vectors</a></h3><div
class="level3"><p> A <em>unit vector</em> is a basic vector with a length of 1 world unit. Since its length is fixed (and it thus can only point at one location anyway), the only interesting thing about this vector is its direction.</p><ul><li
<p> class="level1"><div
class="li"> <code>Vector3f.UNIT_X</code> = ( 1, 0, 0) = right</div></li><li
The <strong>jME Context</strong> makes settings, renderer, timer, input and event listeners, display system, accessible to a JME game. class="level1"><div
</p> class="li"> <code>Vector3f.UNIT_Y</code> = ( 0, 1, 0) = up</div></li><li
<ul> class="level1"><div
<li><div> The <strong>jME Display System</strong> is what draws the custom JME window (instead of Java Swing). </div> class="li"> <code>Vector3f.UNIT_Z</code> = ( 0, 0, 1) = forwards</div></li><li
</li> class="level1"><div
<li><div> The <strong>input system</strong> is what lets you respond to user input via mouse, keyboard, and joystick.</div> class="li"> <code>Vector3f.UNIT_XYZ</code> = 1 wu diagonal right-up-forewards</div></li></ul></div><h3><a
</li> name="normalized_vectors">Normalized Vectors</a></h3><div
<li><div> The <strong>renderer</strong> is what does all the work of calculating how to draw the 3D scenegraph to the 2D screen.</div> class="level3"><p> A <em>normalized vector</em> is a custom <em>unit vector</em>. A normalized vector is not the same as a <em>(surface) normal vector</em>.
<ul>
<li><div> The <strong>Shader</strong> is a programmable part of the rendering pipeline. The jME3 game engine uses it to offer advanced customizable materials.</div>
</li>
</ul>
</li>
</ul>
</div>
<h1><a>Geometry</a></h1>
<div>
</div>
<h2><a>Coordinates</a></h2>
<div>
<p>
Coordinates represent a location in a coordinate system, relative to the origin (0,0,0). m. In 3D space, you need to specify three coordinate values to locate a point: x,y,z.
As opposed to a vector (which looks similar), a coordinate does not have a “direction”.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/coordinate-system.png">
</p>
</div>
<h3><a>The Origin</a></h3>
<div>
<p>
The origin is the central point in the 3D world. It&#039;s at the coordinates (0,0,0).
</p>
<p>
Code sample: <code>Vector3f origin = new Vector3f( Vector3f.ZERO );</code>
</p>
</div>
<h2><a>Vectors</a></h2>
<div>
<p>
A vector has a length and a direction. It is used like an arrow pointing at a point in 3D space. A vector starts at the origin (0,0,0), and ends at the target coordinate (x,y,z). Backwards directions are expressed with negative values.
</p>
<p>
Code sample: <code>Vector3f v = new Vector3f( 17 , -4 , 0 );</code>
</p>
</div>
<h3><a>Unit Vectors</a></h3>
<div>
<p>
A <em>unit vector</em> is a basic vector with a length of 1 world unit. Since its length is fixed (and it thus can only point at one location anyway), the only interesting thing about this vector is its direction.
</p>
<ul>
<li><div> <code>Vector3f.UNIT_X</code> = ( 1, 0, 0) = right</div>
</li>
<li><div> <code>Vector3f.UNIT_Y</code> = ( 0, 1, 0) = up</div>
</li>
<li><div> <code>Vector3f.UNIT_Z</code> = ( 0, 0, 1) = forwards</div>
</li>
<li><div> <code>Vector3f.UNIT_XYZ</code> = 1 wu diagonal right-up-forewards </div>
</li>
</ul>
</div>
<h3><a>Normalized Vectors</a></h3>
<div>
<p>
A <em>normalized vector</em> is a custom <em>unit vector</em>. A normalized vector is not the same as a <em>(surface) normal vector</em>.
</p>
<p>
When you normalize a vector, it still has the same direction, but you lose the information where the vector originally pointed. When you normalize a vector, it still has the same direction, but you lose the information where the vector originally pointed.
</p> For instance, you normalize vectors before calculating angles.</p></div><h3><a
name="surface_normals">Surface Normals</a></h3><div
<p> class="level3"><p> A surface normal is a vector that is perpendicular to a plane.
For instance, you normalize vectors before calculating angles. You calculate the Surface Normal by calculating the cross product.</p></div><h3><a
</p> name="cross_product">Cross Product</a></h3><div
class="level3"><p> The cross product is a calculation that you use to find a perpendicular vector (an orthogonal, a &quot;right angle&quot; at 90°).
</div>
<h3><a>Surface Normals</a></h3>
<div>
<p>
A surface normal is a vector that is perpendicular to a plane.
You calculate the Surface Normal by calculating the cross product.
</p>
</div>
<h3><a>Cross Product</a></h3>
<div>
<p>
The cross product is a calculation that you use to find a perpendicular vector (an orthogonal, a “right angle” at 90°).
</p>
<p>
In 3D space, speaking of an orthogonal only makes sense with respect to a plane. You need two vectors to uniquely define a plane. The cross product of the two vectors, <code>v1 × v2</code>, is a new vector that is perpendicular to this plane. A vector perpendicular to a plane is a called <em>Surface Normal</em>. In 3D space, speaking of an orthogonal only makes sense with respect to a plane. You need two vectors to uniquely define a plane. The cross product of the two vectors, <code>v1 × v2</code>, is a new vector that is perpendicular to this plane. A vector perpendicular to a plane is a called <em>Surface Normal</em>.
</p> Example: The x unit vector and the y unit vector together define the x/y plane. The vector perpendicular to them is the z axis. JME can calculate that this equation is true: <br/> <code>( Vector3f.UNIT_X.cross( Vector3f.UNIT_Y ) ).equals( Vector3f.UNIT_Z )</code> == true</p></div><h2><a
name="polygon_mesh_vertex">Polygon, Mesh, Vertex</a></h2><div
<p> class="level2"><p> <a
Example: The x unit vector and the y unit vector together define the x/y plane. The vector perpendicular to them is the z axis. JME can calculate that this equation is true: <br/> href="/wiki/lib/exe/detail.php/jme3:dolphin-mesh.png?id=jme3%3Aterminology"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/dolphin-mesh.png" class="mediaright" align="right" alt="" /></a> Most visible objects in a 3D scene are made up of polygon meshes – characters, terrains, buildings, etc. A mesh is a grid-like structure that represents a complex shape. The advantage of a mesh is that it is mathematically simple enough to render in real time, and detailed enough to be recognizable.
<code>( Vector3f.UNIT_X.cross( Vector3f.UNIT_Y ) ).equals( Vector3f.UNIT_Z )</code> == true
</p>
</div>
<h2><a>Polygon, Mesh, Vertex</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/dolphin-mesh.png">
</p>
<p>
Most visible objects in a 3D scene are made up of polygon meshes – characters, terrains, buildings, etc. A mesh is a grid-like structure that represents a complex shape. The advantage of a mesh is that it is mathematically simple enough to render in real time, and detailed enough to be recognizable.
</p>
<p>
Every shape is reduced to a number of connected polygons, usually triangles; even round surfaces such as spheres are reduced to a grid of triangles. The polygons&#039; corner points are called vertices. Every vertex is positioned at a coordinate, all vertices together describe the outline of the shape. Every shape is reduced to a number of connected polygons, usually triangles; even round surfaces such as spheres are reduced to a grid of triangles. The polygons&#039; corner points are called vertices. Every vertex is positioned at a coordinate, all vertices together describe the outline of the shape.
</p> You create 3D meshes in tools called mesh editors, e.g in Blender. <a
href="/com/jme3/gde/core/docs/jme3/math.html">Learn more about 3D maths here.</a></p></div><h1><a
<p> name="materialscolor_lighting_shading">Materials: Color, Lighting/Shading</a></h1><div
You create 3D meshes in tools called mesh editors, e.g in Blender. class="level1"><p> What we call &quot;color&quot; is merely part of an object&#039;s light reflection. The onlooker&#039;s brain uses shading and reflecting properties to infer an object&#039;s shape and material. Factors like these make all the difference between chalk vs milk, skin vs paper, water vs plastic, etc! (<a
</p> href="http://www.shaders.org/ifw2_textures/whatsin10.htm">External examples</a>)</p></div><h2><a
name="color">Color</a></h2><div
<p> class="level2"></div><h3><a
<a href="/com/jme3/gde/core/docs/jme3/math.html">Learn more about 3D maths here.</a> name="ambient_color">Ambient color</a></h3><div
</p> class="level3"><ul><li
class="level1"><div
</div> class="li"> The uniform base color of the mesh – what it looks like when not influenced by any light source.</div></li><li
class="level1"><div
<h1><a>Materials: Color, Lighting/Shading</a></h1> class="li"> Usually similar to the Diffuse color.</div></li><li
<div> class="level1"><div
class="li"> This is the minimum color you need for an object to be visible.</div></li></ul></div><h3><a
<p> name="diffuse_color">Diffuse color</a></h3><div
class="level3"><ul><li
What we call “color” is merely part of an object&#039;s light reflection. The onlooker&#039;s brain uses shading and reflecting properties to infer an object&#039;s shape and material. Factors like these make all the difference between chalk vs milk, skin vs paper, water vs plastic, etc! (<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.shaders.org/ifw2_textures/whatsin10.htm"><param name="text" value="<html><u>External examples</u></html>"><param name="textColor" value="blue"></object>) class="level1"><div
</p> class="li"> The base color of the mesh plus shattered light and shadows that are caused by a light source.</div></li><li
class="level1"><div
</div> class="li"> Usually similar to the Ambient color.</div></li></ul></div><h2><a
name="light_sources">Light Sources</a></h2><div
<h2><a>Color</a></h2> class="level2"></div><h3><a
<div> name="emissive_color">Emissive color</a></h3><div
class="level3"><ul><li
</div> class="level1"><div
class="li"> The color of light emitted by a light source or glowing material.</div></li><li
<h3><a>Ambient color</a></h3> class="level1"><div
<div> class="li"> Only glowing materials such as lights have an emissive color, normal objects don&#039;t have this property.</div></li><li
<ul> class="level1"><div
<li><div> The uniform base color of the mesh – what it looks like when not influenced by any light source.</div> class="li"> Often white (sun light).</div></li></ul></div><h2><a
</li> name="reflections">Reflections</a></h2><div
<li><div> Usually similar to the Diffuse color. </div> class="level2"></div><h3><a
</li> name="shininess">Shininess</a></h3><div
<li><div> This is the minimum color you need for an object to be visible.</div> class="level3"><ul><li
</li> class="level1"><div
</ul> class="li"> Degree of shininess of a surface (0-128).</div></li><li
class="level1"><div
</div> class="li"> Shiny objects have small, clearly outlined specular highlights. (E.g. glass, water, silver)</div></li><li
class="level1"><div
<h3><a>Diffuse color</a></h3> class="li"> Normal objects have wide, blurry specular highlights. (E.g. metal, plastic, stone, polished materials)</div></li><li
<div> class="level1"><div
<ul> class="li"> Uneven objects are not shiny and have no specular highlights. (E.g. cloth, paper, wood, snow)</div></li></ul></div><h3><a
<li><div> The base color of the mesh plus shattered light and shadows that are caused by a light source.</div> name="specular_color">Specular Color</a></h3><div
</li> class="level3"><ul><li
<li><div> Usually similar to the Ambient color.</div> class="level1"><div
</li> class="li"> If the material is shiny, then the Specular Color is the color of the reflected highlights.</div></li><li
</ul> class="level1"><div
class="li"> Usually the same as the emissive color of the light source (e.g. white).</div></li><li
</div> class="level1"><div
class="li"> You can use colors to achieve special specular effects, such as metallic or iridescent reflections.</div></li><li
<h2><a>Light Sources</a></h2> class="level1"><div
<div> class="li"> Non-shiny objects don&#039;t use a specular color.</div></li></ul><p> <a
href="/wiki/lib/exe/fetch.php?hash=08b76e&amp;media=http%3A%2F%2Fimg823.imageshack.us%2Fimg823%2F1171%2Ftanlglow2.png"><img
</div> src="/wiki/lib/exe/fetch.php?hash=08b76e&amp;w=400&amp;h=234&amp;media=http%3A%2F%2Fimg823.imageshack.us%2Fimg823%2F1171%2Ftanlglow2.png" class="mediacenter" alt="" width="400" height="234" /></a></p></div><h1><a
name="materialstextures">Materials: Textures</a></h1><div
<h3><a>Emissive color</a></h3> class="level1"><p> Textures are part of Materials. In the simplest case, an object could have just one texture, the Color Map, loaded from one image file. When you think back of old computer games you&#039;ll remember this looks quite plain.
<div> The more information you (the game designer) provide additionally to the Color Map, the higher the degree of detail and realism. Whether you want photo-realistic rendering or &quot;toon&quot; rendering (Cel Shading), everything depends on the quality of your materials and texture maps. Modern 3D graphics use several layers of information to describe one material, each layer is a Texture Map.</p></div><h2><a
<ul> name="texture_maps">Texture Maps</a></h2><div
<li><div> The color of light emitted by a light source or glowing material. </div> class="level2"></div><h3><a
</li> name="color_map">Color Map</a></h3><div
<li><div> Only glowing materials such as lights have an emissive color, normal objects don&#039;t have this property. </div> class="level3"><p> <a
</li> href="/wiki/lib/exe/fetch.php?hash=b4d15a&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Froad.jpg"><img
<li><div> Often white (sun light).</div> src="/wiki/lib/exe/fetch.php?hash=b4d15a&amp;w=64&amp;h=64&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Froad.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_road.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_splat_road.jpg" width="64" height="64" /></a></p><ul><li
</li> class="level1"><div
</ul> class="li"> A simple image file (or a procedural texture).</div></li><li
class="level1"><div
</div> class="li"> The image can have alpha channels for transparency.</div></li><li
class="level1"><div
<h2><a>Reflections</a></h2> class="li"> <strong>A color map is the minimum texture you need.</strong> All other texture maps are optional improvements.</div></li></ul></div><h3><a
<div> name="diffuse_map">Diffuse Map</a></h3><div
class="level3"><p> <a
</div> href="/wiki/lib/exe/fetch.php?hash=f41169&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_diffuse.jpg"><img
src="/wiki/lib/exe/fetch.php?hash=f41169&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_diffuse.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_hovertank_tank_diffuse.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_hovertank_tank_diffuse.jpg" width="128" height="128" /></a></p><ul><li
<h3><a>Shininess</a></h3> class="level1"><div
<div> class="li"> The Diffuse Map specifies the intensity of color.</div></li><li
<ul> class="level1"><div
<li><div> Degree of shininess of a surface (0-128).</div> class="li"> Its basically the same as a Color Map but its called Diffuse Map in a lighting environment, as it defines the color the object &quot;diffuses&quot;.</div></li></ul></div><h3><a
</li> name="bump_map">Bump Map</a></h3><div
<li><div> Shiny objects have small, clearly outlined specular highlights. (E.g. glass, water, silver)</div> class="level3"><p> Bump maps are used to describe detailed shapes that would be too hard or simply too inefficient to sculpt in a mesh editor. You use Normal Maps to model cracks in walls, rust, skin texture, or a canvas weave. You use Height Maps to model whole terrains with valleys and mountains. <a
</li> href="/wiki/lib/exe/fetch.php?hash=e15227&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png"><img
<li><div> Normal objects have wide, blurry specular highlights. (E.g. metal, plastic, stone, polished materials)</div> src="/wiki/lib/exe/fetch.php?hash=e15227&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2Fsplat%2Fmountains512.png" class="mediaright" align="right" alt="" width="128" height="128" /></a></p></div><h4><a
</li> name="height_map">Height Map</a></h4><div
<li><div> Uneven objects are not shiny and have no specular highlights. (E.g. cloth, paper, wood, snow)</div> class="level4"><ul><li
</li> class="level1"><div
</ul> class="li"> A height map is a grayscale image looking similar to a terrain map used in topography. Brighter grays represent higher areas and darker grays lower areas.</div></li><li
class="level1"><div
</div> class="li"> A heightmap can represent 256 height levels and is mostly used to roughly outline terrains.</div></li><li
class="level1"><div
<h3><a>Specular Color</a></h3> class="li"> You can draw a heightmap by hand in any image editor.</div></li></ul></div><h4><a
<div> name="normal_map">Normal Map</a></h4><div
<ul> class="level4"><p> <a
<li><div> If the material is shiny, then the Specular Color is the color of the reflected highlights. </div> href="/wiki/lib/exe/fetch.php?hash=945484&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_normals.png"><img
</li> src="/wiki/lib/exe/fetch.php?hash=945484&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_normals.png" class="mediaright" align="right" alt="" width="128" height="128" /></a></p><ul><li
<li><div> Usually the same as the emissive color of the light source (e.g. white). </div> class="level1"><div
</li> class="li"> A well-done Normal Map makes a shape more detailed–without the need to add costly polygons to the mesh. It contains shading information that makes the object appear smoother and more fine-grained.</div></li><li
<li><div> You can use colors to achieve special specular effects, such as metallic or iridescent reflections.</div> class="level1"><div
</li> class="li"> The Normal Map is displayed looking like a false-color version of the Color Map–but it is never used for coloring, instead, each RGB value encodes transformation data. This displacement data is represented by Surface Normals of the slopes, hence the name.</div></li><li
<li><div> Non-shiny objects don&#039;t use a specular color.</div> class="level1"><div
</li> class="li"> It&#039;s hard to draw normal maps by hand. Generally you use software tools to calculate them off 3D models.</div></li></ul></div><h3><a
</ul> name="specular_map">Specular Map</a></h3><div
class="level3"><p> <a
<p> href="/wiki/lib/exe/fetch.php?hash=789616&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_specular.jpg"><img
src="/wiki/lib/exe/fetch.php?hash=789616&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FHoverTank%2Ftank_specular.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_hovertank_tank_specular.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_hovertank_tank_specular.jpg" width="128" height="128" /></a></p><ul><li
<img src="/wiki/lib/exe/fetch.php"> class="level1"><div
</p> class="li"> A Specular Map further improves the realism of an object&#039;s surface: It contains extra information about shininess and makes the shape appear more realistically illumated.</div></li><li
class="level1"><div
</div> class="li"> Start out with a gray value that corresponds to the average shininess/dullness of this material. Then add ligher grays for smoother, shinier, more reflective areas; and darker grays for duller, rougher, worn-out areas. The resulting image file looks similar to a grayscale version of the Color Map.</div></li><li
class="level1"><div
<h1><a>Materials: Textures</a></h1> class="li"> You can use colors in a specular map to create certain reflective effects (iridiscence, metallic).</div></li></ul></div><h2><a
<div> name="seamless_tiled_textures">Seamless Tiled Textures</a></h2><div
class="level2"><p> <a
<p> href="/wiki/lib/exe/fetch.php?hash=5adfc8&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FBrickWall%2FBrickWall.jpg"><img
src="/wiki/lib/exe/fetch.php?hash=5adfc8&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FTextures%2FTerrain%2FBrickWall%2FBrickWall.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_brickwall_brickwall.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_textures_terrain_brickwall_brickwall.jpg" width="128" height="128" /></a> This is a very simple, commonly used type of texture. When texturing a wide area (e.g. walls, floors), you don&#039;t create one huge texture, instead you tile a small texture repeatedly to fill the area.
Textures are part of Materials. In the simplest case, an object could have just one texture, the Color Map, loaded from one image file. When you think back of old computer games you&#039;ll remember this looks quite plain. A seamless texture is an image file that has been designed so that it can be used as tiles: The right edge matches the left edge, and the top edge matches the bottom edge. The onlooker cannot easily tell where one starts and the next one ends, thus creating an illusion of a huge texture. The downside is that the tiling becomes painfully obvious when the area is viewed from a distance. Also you cannot use it on more complex models such as characters.</p></div><h2><a
</p> name="uv_maps">UV Maps</a></h2><div
class="level2"><p> <a
<p> href="/wiki/lib/exe/fetch.php?hash=82332e&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FFerrari%2FCar.jpg"><img
The more information you (the game designer) provide additionally to the Color Map, the higher the degree of detail and realism. Whether you want photo-realistic rendering or “toon” rendering (Cel Shading), everything depends on the quality of your materials and texture maps. Modern 3D graphics use several layers of information to describe one material, each layer is a Texture Map. src="/wiki/lib/exe/fetch.php?hash=82332e&amp;w=128&amp;h=128&amp;media=http%3A%2F%2Fjmonkeyengine.googlecode.com%2Fsvn%2Ftrunk%2Fengine%2Fsrc%2Ftest-data%2FModels%2FFerrari%2FCar.jpg" class="mediaright" align="right" title="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_ferrari_car.jpg" alt="jmonkeyengine.googlecode.com_svn_trunk_engine_src_test-data_models_ferrari_car.jpg" width="128" height="128" /></a> Creating a texture for a cube is easy – but what about a character with a face and extremities? For more complex objects, you design the texture in the same ways as a sewing pattern: One image file contains the outline of the front, back, and side of the object, next to one another. Specific areas of the flat texture (UV coordinates) map onto certain areas of your 3D model (XYZ coordinates), hence the name UV map.
</p> Getting the seams and mappings right is crucial: You will have to use a graphic tool like Blender to create UV Maps. It&#039;s worth the while to learn this, UV mapped models look a lot more professional.</p></div><h2><a
name="environment_maps">Environment Maps</a></h2><div
</div> class="level2"><p> <a
href="/wiki/lib/exe/fetch.php?hash=124408&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fglass-teapot1.png"><img
<h2><a>Texture Maps</a></h2> src="/wiki/lib/exe/fetch.php?hash=124408&amp;w=160&amp;h=90&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fglass-teapot1.png" class="mediaright" align="right" alt="" width="160" height="90" /></a> Environment Maps are used to create the impression of reflections and refractions. You create a Cube Map to represent your environment, similar to a skybox. (Sphere Maps are possible, but often look too distorted.) You give the Cube Map a set of images showing a &quot;360° view&quot; of the completed scene. The renderer uses this as base to texture the reflective surface.
<div> Of course these reflections are static and not &quot;real&quot;, e.g. the player will not see his avatar&#039;s face reflected, etc… But they cause the desired &quot;glass/mirror/water&quot; effect, and are fast enough to render in real usecases, it&#039;s better than nothing.</p></div><h2><a
name="mip_map_texture">MIP Map Texture</a></h2><div
</div> class="level2"><p> You provide the texture in two or three resolutions to be stored in one file (MIP = &quot;multum in parvo&quot; = &quot;many in one&quot;). Depending on how close (or far) the camera is, the engine automatically renders a more (or less) detailed texture for the object. Thus objects look smooth from close up, but don&#039;t waste resources with unspottable details when far away. Good for everything, but requires more time to create and more space to store textures.</p></div><h2><a
name="procedural_textures">Procedural Textures</a></h2><div
<h3><a>Color Map</a></h3> class="level2"><p> A procedural texture is generated from repeating one small image, plus some pseudo-random, gradient variations (Perlin noise). Procedural textures look more natural than static rectangular textures, for instance, they look less distorted on spheres. On big meshes, their repetitiveness is much less noticable than tiled seamless textures. Procedural textures are ideal for irregular large-area textures like grass, soil, rock, rust, and walls. See also: <a
<div> href="http://jmonkeyengine.org/wiki/doku.php/jme3:jmonkeyplatform:neotexture">jMonkeyPlatform NeoTexture plugin</a> <a
href="/wiki/lib/exe/fetch.php?hash=051bf1&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fneotexture-2.jpg"><img
<p> src="/wiki/lib/exe/fetch.php?hash=051bf1&amp;w=380&amp;h=189&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fneotexture-2.jpg" class="mediacenter" title="jmonkeyengine.org_wp-content_uploads_2010_10_neotexture-2.jpg" alt="jmonkeyengine.org_wp-content_uploads_2010_10_neotexture-2.jpg" width="380" height="189" /></a> See also: <a
href="http://www.blender.org/education-help/tutorials/materials/">Creating Materials in Blender</a>, <a
<img src="/wiki/lib/exe/fetch.php"> href="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/Every_Material_Known_to_Man">Blender: Every Material Known to Man</a></p></div><h1><a
</p> name="animation">Animation</a></h1><div
<ul> class="level1"><p> In 3D games, Skeletal Animation is used for animated characters, but in principle the skeleton approach can be extended to any 3D mesh (for example, an opening crate&#039;s hinge can be considered a joint).
<li><div> A simple image file (or a procedural texture). </div> Unless you animate a 3D cartoon, realism of animated characters is generally a problem: Movement can look alien-like mechanical or broken, the character appears hollow, or as if floating. Professional game designers invest a lot of effort to make characters animate in a natural way (including motion capturing).</p></div><h2><a
</li> name="rigging_and_skinning">Rigging and Skinning</a></h2><div
<li><div> The image can have alpha channels for transparency. </div> class="level2"><p> <a
</li> href="/wiki/lib/exe/fetch.php?hash=6038ee&amp;media=http%3A%2F%2Fpub.admc.com%2Fmisc%2Fjme%2Fblenderjmetut%2Fblenderswordsman.png"><img
<li><div> <strong>A color map is the minimum texture you need.</strong> All other texture maps are optional improvements.</div> src="/wiki/lib/exe/fetch.php?hash=6038ee&amp;w=195&amp;h=151&amp;media=http%3A%2F%2Fpub.admc.com%2Fmisc%2Fjme%2Fblenderjmetut%2Fblenderswordsman.png" class="mediaright" align="right" alt="" width="195" height="151" /></a> An animated character has an armature: An internal skeleton (Bones) and an external surface (Skin). The Skin is the visible outside of the character and it includes clothing. The Bones are not visible and are used to interpolate (calculate) the morphing steps of the skin.
</li> JME3, the game engine, only loads and plays your recorded animations. You must use a tool (such as Blender) to set up (rig, skin, and animate) a character.</p><ol><li
</ul> class="level1"><div
class="li"> <strong>Rigging:</strong> The Construction of a character&#039;s skeleton.</div><ul><li
</div> class="level2"><div
class="li"> Create as few Bones as possible to decrease complexity.</div></li><li
<h3><a>Diffuse Map</a></h3> class="level2"><div
<div> class="li"> Bones are connected in a parent-child hierarchy: Moving one bone can pull another bone with it (e.g. arm pulls hand).</div></li><li
class="level2"><div
<p> class="li"> Bones follow a certain naming scheme so the 3D engines know what&#039;s what.</div></li></ul></li><li
class="level1"><div
<img src="/wiki/lib/exe/fetch.php"> class="li"> <strong>Skinning:</strong> The association of individual bones with the corresponding skin sections.</div><ul><li
</p> class="level2"><div
<ul> class="li"> Each Bone is connected to a part of the Skin. Animating the (invisible) Bone pulls the (visible) Skin with it. <br/> E.g. the thigh Bone is connected to the upper leg Skin.</div></li><li
<li><div> The Diffuse Map specifies the intensity of color. </div> class="level2"><div
</li> class="li"> One part of the Skin can be affected by more than one bone (e.g. knee, elbow).</div></li><li
<li><div> Its basically the same as a Color Map but its called Diffuse Map in a lighting environment, as it defines the color the object “diffuses”.</div> class="level2"><div
</li> class="li"> The connection between bones and skin sections is gradual: You assign weights how much each skin polygon is affected by any bone&#039;s motion. <br/> E.g. when the thigh bone moves, the leg is fully affected, the hips joints less so, and the head not at all.</div></li></ul></li><li
</ul> class="level1"><div
class="li"> <strong>Keyframe Animation:</strong> A keyframe is one recorded snapshot of a motion sequence.</div><ul><li
</div> class="level2"><div
class="li"> A series of keyframes makes up one animation.</div></li><li
<h3><a>Bump Map</a></h3> class="level2"><div
<div> class="li"> Each model can have several animations. Each animation has a name to identify it (e.g. &quot;walk&quot;, &quot;attack&quot;, &quot;jump&quot;).</div></li><li
class="level2"><div
<p> class="li"> You specify in your game code which keyframe animation to load, and when to play it.</div></li></ul></li></ol></div><h2><a
name="kinematics">Kinematics</a></h2><div
Bump maps are used to describe detailed shapes that would be too hard or simply too inefficient to sculpt in a mesh editor. You use Normal Maps to model cracks in walls, rust, skin texture, or a canvas weave. You use Height Maps to model whole terrains with valleys and mountains. class="level2"><ul><li
</p> class="level1"><div
class="li"> Forward kinematics: &quot;Given the angles of all the character&#039;s joints, what is the position of the character&#039;s hand?&quot;</div></li><li
<p> class="level1"><div
<img src="/wiki/lib/exe/fetch.php"> class="li"> Inverse kinematics: &quot;Given the position of the character&#039;s hand, what are the angles of all the character&#039;s joints?&quot;</div></li></ul></div><h2><a
</p> name="controller_and_channel">Controller and Channel</a></h2><div
class="level2"><p> In the JME3 application, you register animated models to the Animation Controller. The controller object gives you access to the available animation sequences. The controller has several channels, each channels can run one animation sequence at a time. To run several sequences, you create several channels, and run them in parallel.</p></div><h1><a
</div> name="artificial_intelligence_ai">Artificial Intelligence (AI)</a></h1><div
class="level1"><p> Non-player (computer-controlled) characters (NPCs) are only fun in a game if they do not stupidly bump into walls, or blindly run into the line of fire. You want to make NPCs &quot;aware&quot; of their surroundings and let them make decisions based on the game state – otherwise the player can just ignore them. The most common use case is that you want to make enemies interact in a way so they offer a more interesting challenge for the player.
<h4><a>Height Map</a></h4> &quot;Smart&quot; game elements are called artificially intelligent agents (AI agents). An AI agent can be an NPC, but also an &quot;automatic alarm system&quot; that locks doors after an intruder alert, or a trained pet.
<div> The domain of artificial intelligence deals, among other things, with:</p><ul><li
<ul> class="level1"><div
<li><div> A height map is a grayscale image looking similar to a terrain map used in topography. Brighter grays represent higher areas and darker grays lower areas. </div> class="li"> Knowledge – An agent only &quot;knows&quot; what it can &quot;see and hear&quot;, this implies that things can be hidden from it. You can make a group of agents share knowledge (e.g. guards with two-way radios know, other guards don&#039;t know about the intruder).</div></li><li
</li> class="level1"><div
<li><div> A heightmap can represent 256 height levels and is mostly used to roughly outline terrains.</div> class="li"> Goal Planning – The agent has a priority to achieve a specific goal (a future state). It splits the goal into subgoals, determines tactics and strategies, and prioritizes them. The agent keeps testing whether the current state is closer to the (sub)goal. If unsuccessful, the agent changes the tactics/strategy. E.g. Finding the best path to reach a target in a changing environment.</div></li><li
</li> class="level1"><div
<li><div> You can draw a heightmap by hand in any image editor.</div> class="li"> Problem solving – The agent uses a given set of facts and rules to deduct what state it is in. In every state, only a certain subset of reactions makes sense. The actual decision depends on the agent&#039;s goal. Examples: If target in range, attack or protect base or raise alarm. If idle, lay traps or heal oneself or recharge ammunition. If floor on fire, then danger. If danger, escape or kamikaze.</div></li></ul><p> There are lots of resources explaining interesting AI algorithms:</p><ul><li
</li> class="level1"><div
</ul> class="li"> <a
href="http://www.policyalmanac.org/games/aStarTutorial.htm">A* (A-Star) pathfinding for beginners</a></div></li><li
</div> class="level1"><div
class="li"> <a
<h4><a>Normal Map</a></h4> href="http://theory.stanford.edu/~amitp/GameProgramming/">A* (A-star) pathfinding theory</a></div></li><li
<div> class="level1"><div
class="li"> <a
<p> href="http://hem.fyristorg.com/dawnbringer/z-path.html">&quot;Z-Path&quot; algorithm</a> (backwards pathfinding)</div></li><li
class="level1"><div
<img src="/wiki/lib/exe/fetch.php"> class="li"> <a
</p> href="http://web.media.mit.edu/~jorkin/goap.html">Goal-Oriented Action Planning</a></div></li><li
<ul> class="level1"><div
<li><div> A well-done Normal Map makes a shape more detailed–without the need to add costly polygons to the mesh. It contains shading information that makes the object appear smoother and more fine-grained.</div> class="li"> <a
</li> href="http://neuroph.sourceforge.net/">Java Neural Networks</a></div></li><li
<li><div> The Normal Map is displayed looking like a false-color version of the Color Map–but it is never used for coloring, instead, each RGB value encodes transformation data. This displacement data is represented by Surface Normals of the slopes, hence the name. </div> class="level1"><div
</li> class="li"> …</div></li></ul></div>
<li><div> It&#039;s hard to draw normal maps by hand. Generally you use software tools to calculate them off 3D models.</div>
</li>
</ul>
</div>
<h3><a>Specular Map</a></h3>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<ul>
<li><div> A Specular Map further improves the realism of an object&#039;s surface: It contains extra information about shininess and makes the shape appear more realistically illumated. </div>
</li>
<li><div> Start out with a gray value that corresponds to the average shininess/dullness of this material. Then add ligher grays for smoother, shinier, more reflective areas; and darker grays for duller, rougher, worn-out areas. The resulting image file looks similar to a grayscale version of the Color Map.</div>
</li>
<li><div> You can use colors in a specular map to create certain reflective effects (iridiscence, metallic). </div>
</li>
</ul>
</div>
<h2><a>Seamless Tiled Textures</a></h2>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
This is a very simple, commonly used type of texture. When texturing a wide area (e.g. walls, floors), you don&#039;t create one huge texture, instead you tile a small texture repeatedly to fill the area.
</p>
<p>
A seamless texture is an image file that has been designed so that it can be used as tiles: The right edge matches the left edge, and the top edge matches the bottom edge. The onlooker cannot easily tell where one starts and the next one ends, thus creating an illusion of a huge texture. The downside is that the tiling becomes painfully obvious when the area is viewed from a distance. Also you cannot use it on more complex models such as characters.
</p>
</div>
<h2><a>UV Maps</a></h2>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
Creating a texture for a cube is easy – but what about a character with a face and extremities? For more complex objects, you design the texture in the same ways as a sewing pattern: One image file contains the outline of the front, back, and side of the object, next to one another. Specific areas of the flat texture (UV coordinates) map onto certain areas of your 3D model (XYZ coordinates), hence the name UV map.
</p>
<p>
Getting the seams and mappings right is crucial: You will have to use a graphic tool like Blender to create UV Maps. It&#039;s worth the while to learn this, UV mapped models look a lot more professional.
</p>
</div>
<h2><a>Environment Maps</a></h2>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
Environment Maps are used to create the impression of reflections and refractions. You create a Cube Map to represent your environment, similar to a skybox. (Sphere Maps are possible, but often look too distorted.) You give the Cube Map a set of images showing a “360° view” of the completed scene. The renderer uses this as base to texture the reflective surface.
</p>
<p>
Of course these reflections are static and not “real”, e.g. the player will not see his avatar&#039;s face reflected, etc… But they cause the desired “glass/mirror/water” effect, and are fast enough to render in real usecases, it&#039;s better than nothing.
</p>
</div>
<h2><a>MIP Map Texture</a></h2>
<div>
<p>
You provide the texture in two or three resolutions to be stored in one file (MIP = “multum in parvo” = “many in one”). Depending on how close (or far) the camera is, the engine automatically renders a more (or less) detailed texture for the object. Thus objects look smooth from close up, but don&#039;t waste resources with unspottable details when far away. Good for everything, but requires more time to create and more space to store textures.
</p>
</div>
<h2><a>Procedural Textures</a></h2>
<div>
<p>
A procedural texture is generated from repeating one small image, plus some pseudo-random, gradient variations (Perlin noise). Procedural textures look more natural than static rectangular textures, for instance, they look less distorted on spheres. On big meshes, their repetitiveness is much less noticable than tiled seamless textures. Procedural textures are ideal for irregular large-area textures like grass, soil, rock, rust, and walls. See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.org/wiki/doku.php/jme3:jmonkeyplatform:neotexture"><param name="text" value="<html><u>jMonkeyPlatform NeoTexture plugin</u></html>"><param name="textColor" value="blue"></object>
</p>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.blender.org/education-help/tutorials/materials/"><param name="text" value="<html><u>Creating Materials in Blender</u></html>"><param name="textColor" value="blue"></object>, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/Every_Material_Known_to_Man"><param name="text" value="<html><u>Blender: Every Material Known to Man</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<h1><a>Animation</a></h1>
<div>
<p>
In 3D games, Skeletal Animation is used for animated characters, but in principle the skeleton approach can be extended to any 3D mesh (for example, an opening crate&#039;s hinge can be considered a joint).
</p>
<p>
Unless you animate a 3D cartoon, realism of animated characters is generally a problem: Movement can look alien-like mechanical or broken, the character appears hollow, or as if floating. Professional game designers invest a lot of effort to make characters animate in a natural way (including motion capturing).
</p>
</div>
<h2><a>Rigging and Skinning</a></h2>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
An animated character has an armature: An internal skeleton (Bones) and an external surface (Skin). The Skin is the visible outside of the character and it includes clothing. The Bones are not visible and are used to interpolate (calculate) the morphing steps of the skin.
</p>
<p>
JME3, the game engine, only loads and plays your recorded animations. You must use a tool (such as Blender) to set up (rig, skin, and animate) a character.
</p>
<ol>
<li><div> <strong>Rigging:</strong> The Construction of a character&#039;s skeleton. </div>
<ul>
<li><div> Create as few Bones as possible to decrease complexity. </div>
</li>
<li><div> Bones are connected in a parent-child hierarchy: Moving one bone can pull another bone with it (e.g. arm pulls hand). </div>
</li>
<li><div> Bones follow a certain naming scheme so the 3D engines know what&#039;s what.</div>
</li>
</ul>
</li>
<li><div> <strong>Skinning:</strong> The association of individual bones with the corresponding skin sections. </div>
<ul>
<li><div> Each Bone is connected to a part of the Skin. Animating the (invisible) Bone pulls the (visible) Skin with it. <br/>
E.g. the thigh Bone is connected to the upper leg Skin.</div>
</li>
<li><div> One part of the Skin can be affected by more than one bone (e.g. knee, elbow).</div>
</li>
<li><div> The connection between bones and skin sections is gradual: You assign weights how much each skin polygon is affected by any bone&#039;s motion. <br/>
E.g. when the thigh bone moves, the leg is fully affected, the hips joints less so, and the head not at all.</div>
</li>
</ul>
</li>
<li><div> <strong>Keyframe Animation:</strong> A keyframe is one recorded snapshot of a motion sequence.</div>
<ul>
<li><div> A series of keyframes makes up one animation. </div>
</li>
<li><div> Each model can have several animations. Each animation has a name to identify it (e.g. “walk”, “attack”, “jump”). </div>
</li>
<li><div> You specify in your game code which keyframe animation to load, and when to play it.</div>
</li>
</ul>
</li>
</ol>
</div>
<h2><a>Kinematics</a></h2>
<div>
<ul>
<li><div> Forward kinematics: “Given the angles of all the character&#039;s joints, what is the position of the character&#039;s hand?”</div>
</li>
<li><div> Inverse kinematics: “Given the position of the character&#039;s hand, what are the angles of all the character&#039;s joints?” </div>
</li>
</ul>
</div>
<h2><a>Controller and Channel</a></h2>
<div>
<p>
In the JME3 application, you register animated models to the Animation Controller. The controller object gives you access to the available animation sequences. The controller has several channels, each channels can run one animation sequence at a time. To run several sequences, you create several channels, and run them in parallel.
</p>
</div>
<h1><a>Artificial Intelligence (AI)</a></h1>
<div>
<p>
Non-player (computer-controlled) characters (NPCs) are only fun in a game if they do not stupidly bump into walls, or blindly run into the line of fire. You want to make NPCs “aware” of their surroundings and let them make decisions based on the game state – otherwise the player can just ignore them. The most common use case is that you want to make enemies interact in a way so they offer a more interesting challenge for the player.
</p>
<p>
“Smart” game elements are called artificially intelligent agents (AI agents). An AI agent can be an NPC, but also an “automatic alarm system” that locks doors after an intruder alert, or a trained pet.
</p>
<p>
The domain of artificial intelligence deals, among other things, with:
</p>
<ul>
<li><div> Knowledge – An agent only “knows” what it can “see and hear”, this implies that things can be hidden from it. You can make a group of agents share knowledge (e.g. guards with two-way radios know, other guards don&#039;t know about the intruder).</div>
</li>
<li><div> Goal Planning – The agent has a priority to achieve a specific goal (a future state). It splits the goal into subgoals, determines tactics and strategies, and prioritizes them. The agent keeps testing whether the current state is closer to the (sub)goal. If unsuccessful, the agent changes the tactics/strategy. E.g. Finding the best path to reach a target in a changing environment.</div>
</li>
<li><div> Problem solving – The agent uses a given set of facts and rules to deduct what state it is in. In every state, only a certain subset of reactions makes sense. The actual decision depends on the agent&#039;s goal. Examples: If target in range, attack or protect base or raise alarm. If idle, lay traps or heal oneself or recharge ammunition. If floor on fire, then danger. If danger, escape or kamikaze.</div>
</li>
</ul>
<p>
There are lots of resources explaining interesting AI algorithms:
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.policyalmanac.org/games/aStarTutorial.htm"><param name="text" value="<html><u>A* (A-Star) pathfinding for beginners</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://theory.stanford.edu/~amitp/GameProgramming/"><param name="text" value="<html><u>A* (A-star) pathfinding theory</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://hem.fyristorg.com/dawnbringer/z-path.html"><param name="text" value="<html><u>&quot;Z-Path&quot; algorithm</u></html>"><param name="textColor" value="blue"></object> (backwards pathfinding)</div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://web.media.mit.edu/~jorkin/goap.html"><param name="text" value="<html><u>Goal-Oriented Action Planning</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://neuroph.sourceforge.net/"><param name="text" value="<html><u>Java Neural Networks</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:terminology?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:terminology?do=export_xhtmlbody">view online version</a></em></p>

@ -1,132 +1,61 @@
<h1><a
<h1><a>The Scene Graph and Other jME3 Terminology</a></h1> name="the_scene_graph_and_other_jme3_terminology">The Scene Graph and Other jME3 Terminology</a></h1><div
<div> class="level1"><p> Before you start making games, make sure you understand general <a
href="/com/jme3/gde/core/docs/jme3/terminology.html">3D Gaming terminology</a>.</p><p> Second, if you are a beginner, we recommend our <a
<p> href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html">Scene Graph for Dummies</a> presentation for a visual introduction to the concept of a scene graph.</p><p> Then continue learning about jME3 concepts here.</p></div><h2><a
name="coordinate_system">Coordinate System</a></h2><div
Before you start making games, make sure you understand general <a href="/com/jme3/gde/core/docs/jme3/terminology.html">3D Gaming terminology</a>. class="level2"><p> <a
</p> href="/wiki/lib/exe/detail.php/jme3:intermediate:coordinate-system.png?id=jme3%3Athe_scene_graph"><img
src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/coordinate-system.png?w=235&amp;h=210" class="mediaright" align="right" alt="" width="235" height="210" /></a></p><p> The jMonkeyEngine uses a right-handed coordinate system, just as OpenGL does.</p><p> The coordinate system consists of:</p><ul><li
<p> class="level1"><div
Second, if you are a beginner, we recommend our <a href="/com/jme3/gde/core/docs/jme3/scenegraph_for_dummies.html">Scene Graph for Dummies</a> presentation for a visual introduction to the concept of a scene graph. class="li"> The origin, a single point in space.</div><ul><li
</p> class="level2"><div
class="li"> This point is always at coordinate (0,0,0)</div></li></ul></li><li
<p> class="level1"><div
Then continue learning about jME3 concepts here. class="li"> Three coordinate axes that are mutually perpendicular, and meet in the origin.</div><ul><li
</p> class="level2"><div
class="li"> The X axis is &quot;right/left&quot;</div></li><li
</div> class="level2"><div
class="li"> The Y axis is &quot;up/down&quot;</div></li><li
<h2><a>Coordinate System</a></h2> class="level2"><div
<div> class="li"> The Z axis is &quot;towards you/away from you&quot;</div></li></ul></li></ul><p> Every point in 3D space is defined by its (x,y,z) coordinates. The data type for vectors is com.jme3.math.Vector3f.</p><p> For your orientation, the default camera&#039;s location is (0.0f,0.0f,10.0f), and it is looking in the direction described by the unit vector (0.0f, 0.0f, -1.0f). This means your point of view is on the positive side of the Z axis, looking towards the origin, down the Z axis.</p><p> The unit of meassurement is <code>world unit</code> (wu). Typically, 1 wu is considered to be one meter. All scales, vectors and points are relative to this coordinate system.</p></div><h2><a
name="scene_graph_and_rootnode">Scene Graph and RootNode</a></h2><div
<p> class="level2"><p> The scene graph represents your 3D world. Objects in the jME3 scene graph are called <a
href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a>s. Everything attached to the <em>rootNode</em> is part of the scene graph. <em>Attaching</em> a Spatial to the rootNode (or other nodes) adds the Spatial to the scene; <em>detaching</em> removes it.</p><p> <a
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/coordinate-system.png"> href="/wiki/lib/exe/detail.php/jme3:intermediate:scene-graph.png?id=jme3%3Athe_scene_graph"><img
</p> src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/scene-graph.png" class="mediacenter" alt="" /></a></p></div><h2><a
name="spatialsnode_vs_geometry">Spatials: Node vs Geometry</a></h2><div
<p> class="level2"><p> A Spatial can be transformed, loaded and saved. There are two types of Spatials, <em>Nodes</em> and <em>Geometries</em>.</p><div
The jMonkeyEngine uses a right-handed coordinate system, just as OpenGL does. class="table sectionedit1"><table
</p> class="inline"><tr
class="row0"><td
<p> class="col0 leftalign"></td><th
The coordinate system consists of: class="col1" colspan="2"> Spatial</th></tr><tr
class="row1"><th
</p> class="col0"> Purpose:</th><td
<ul> class="col1" colspan="2"> A Spatial is an abstract data structure that stores transformations (translation, rotation, scale).</td></tr><tr
<li><div> The origin, a single point in space.</div> class="row2"><td
<ul> class="col0 leftalign"></td><th
<li><div> This point is always at coordinate (0,0,0)</div> class="col1"> Geometry</th><th
</li> class="col2"> Node</th></tr><tr
</ul> class="row3"><th
</li> class="col0"> Visibility:</th><td
<li><div> Three coordinate axes that are mutually perpendicular, and meet in the origin. </div> class="col1"> A visible 3-D object.</td><td
<ul> class="col2"> An invisible &quot;handle&quot; for a group of objects.</td></tr><tr
<li><div> The X axis is “right/left”</div> class="row4"><th
</li> class="col0"> Purpose:</th><td
<li><div> The Y axis is “up/down”</div> class="col1"> Represents the &quot;look&quot; of an object: Shape, color, texture, opacity/transparency.</td><td
</li> class="col2"> Groups Geometries and other Nodes together: You transform a Node to affect all attached Nodes.</td></tr><tr
<li><div> The Z axis is “towards you/away from you”</div> class="row5"><th
</li> class="col0"> Content:</th><td
</ul> class="col1"> Transformations, mesh, material.</td><td
</li> class="col2"> Transformations. No mesh, no material.</td></tr><tr
</ul> class="row6"><th
class="col0"> Examples:</th><td
<p> class="col1"> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc…</td><td
class="col2"> The rootNode, the guiNode, an audio node, a custom grouping node, etc.</td></tr></table></div></div><h2><a
Every point in 3D space is defined by its (x,y,z) coordinates. The data type for vectors is com.jme3.math.Vector3f. name="how_to_use_this_knowledge">How to Use This Knowledge?</a></h2><div
</p> class="level2"><p> Before you start creating your game, you should have completed the <a
href="/com/jme3/gde/core/docs/jme3/beginner.html">Hello World tutorial series</a>. It shows how to load and create Spatials, how to lay out a scene by attaching and transforming Spatials, and how to add interaction and effects to a game.</p><p> The <a
<p> href="/com/jme3/gde/core/docs/jme3.html">intermediate and advanced documentation</a> gives you more details on how to put all the parts together to create an awesome Java 3D game!</p></div>
For your orientation, the default camera&#039;s location is (0.0f,0.0f,10.0f), and it is looking in the direction described by the unit vector (0.0f, 0.0f, -1.0f). This means your point of view is on the positive side of the Z axis, looking towards the origin, down the Z axis.
</p>
<p>
The unit of meassurement is <code>world unit</code> (wu). Typically, 1 wu is considered to be one meter. All scales, vectors and points are relative to this coordinate system.
</p>
</div>
<h2><a>Scene Graph and RootNode</a></h2>
<div>
<p>
The scene graph represents your 3D world. Objects in the jME3 scene graph are called <a href="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">Spatial</a>s. Everything attached to the <em>rootNode</em> is part of the scene graph. <em>Attaching</em> a Spatial to the rootNode (or other nodes) adds the Spatial to the scene; <em>detaching</em> removes it.
</p>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/jme3/intermediate/scene-graph.png">
</p>
</div>
<h2><a>Spatials: Node vs Geometry</a></h2>
<div>
<p>
A Spatial can be transformed, loaded and saved. There are two types of Spatials, <em>Nodes</em> and <em>Geometries</em>.
</p>
<table>
<tr>
<td> </td><th> Spatial </th>
</tr>
<tr>
<th> Purpose: </th><td> A Spatial is an abstract data structure that stores transformations (translation, rotation, scale). </td>
</tr>
<tr>
<td> </td><th> Geometry </th><th> Node </th>
</tr>
<tr>
<th> Visibility: </th><td> A visible 3-D object. </td><td> An invisible “handle” for a group of objects. </td>
</tr>
<tr>
<th> Purpose: </th><td> Represents the “look” of an object: Shape, color, texture, opacity/transparency. </td><td> Groups Geometries and other Nodes together: You transform a Node to affect all attached Nodes. </td>
</tr>
<tr>
<th> Content: </th><td> Transformations, mesh, material. </td><td> Transformations. No mesh, no material. </td>
</tr>
<tr>
<th> Examples: </th><td> A box, a sphere, player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc… </td><td> The rootNode, the guiNode, an audio node, a custom grouping node, etc. </td>
</tr>
</table>
</div>
<h2><a>How to Use This Knowledge?</a></h2>
<div>
<p>
Before you start creating your game, you should have completed the <a href="/com/jme3/gde/core/docs/jme3/beginner.html">Hello World tutorial series</a>. It shows how to load and create Spatials, how to lay out a scene by attaching and transforming Spatials, and how to add interaction and effects to a game.
</p>
<p>
The <a href="/com/jme3/gde/core/docs/jme3.html">intermediate and advanced documentation</a> gives you more details on how to put all the parts together to create an awesome Java 3D game!
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:the_scene_graph?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:the_scene_graph?do=export_xhtmlbody">view online version</a></em></p>

@ -1,54 +1,13 @@
<h1><a
<h1><a>WebStart (JNLP) Deployment</a></h1> name="webstart_jnlp_deployment">WebStart (JNLP) Deployment</a></h1><div
<div> class="level1"><p> When you <a
href="/com/jme3/gde/core/docs/sdk/application_deployment.html">use the jMonkeyPlatform to deploy your application</a>, you can configure the project to build files required for WebStart automatically. If you use another IDE, or work on the command line, use the following tips to set up WebStart correctly:</p><p> Problem:</p><p> When running under WebStart, jMonkeyEngine may not have permission to extract the native libraries to the current directory.</p><p> Solution:</p><p> You can instruct WebStart to load the native libraries itself using the JNLP file, and then instruct jME3 not to try to do so itself.</p></div><h2><a
<p> name="simple_way">Simple way</a></h2><div
class="level2"><p> You can import the LWJGL JNLP extension directly into your extension, however be aware that your application will break whenever they update their jars. Simply add this line to your JNLP:</p><pre><span>&lt;extension name=&quot;lwjgl&quot; href=&quot;http://lwjgl.org/webstart/2.7.1/extension.jnlp&quot; /&gt;</span></pre></div><h2><a
When you <a href="/com/jme3/gde/core/docs/sdk/application_deployment.html">use the jMonkeyPlatform to deploy your application</a>, you can configure the project to build files required for WebStart automatically. If you use another IDE, or work on the command line, use the following tips to set up WebStart correctly: name="reliable_way">Reliable way</a></h2><div
</p> class="level2"></div><h3><a
name="native_jars">Native jars</a></h3><div
<p> class="level3"><p> You can download the LWJGL native jars from their site, or to ensure you&#039;re using the exact same version as bundled with your jME3 release, make your own:</p><pre>mkdir tmp
Problem:
</p>
<p>
When running under WebStart, jMonkeyEngine may not have permission to extract the native libraries to the current directory.
</p>
<p>
Solution:
</p>
<p>
You can instruct WebStart to load the native libraries itself using the JNLP file, and then instruct jME3 not to try to do so itself.
</p>
</div>
<h2><a>Simple way</a></h2>
<div>
<p>
You can import the LWJGL JNLP extension directly into your extension, however be aware that your application will break whenever they update their jars. Simply add this line to your JNLP:
</p>
<pre><span>&lt;extension name=&quot;lwjgl&quot; href=&quot;http://lwjgl.org/webstart/2.7.1/extension.jnlp&quot; /&gt;</span></pre>
</div>
<h2><a>Reliable way</a></h2>
<div>
</div>
<h3><a>Native jars</a></h3>
<div>
<p>
You can download the LWJGL native jars from their site, or to ensure you&#039;re using the exact same version as bundled with your jME3 release, make your own:
</p>
<pre>
mkdir tmp
cd tmp cd tmp
jar xfv ../jME3-lwjgl-natives.jar jar xfv ../jME3-lwjgl-natives.jar
cd native cd native
@ -56,23 +15,9 @@ for i in *; do
cd $i cd $i
jar cfv ../../native_$i.jar . jar cfv ../../native_$i.jar .
cd .. cd ..
done done</pre><p> Remember to sign all the jar files and move them into the right place from the tmp directory.</p></div><h3><a
</pre> name="jnlp_file">JNLP file</a></h3><div
class="level3"><p> Add the following to your JNLP file:</p><pre> <span>&lt;resources os=&quot;Windows&quot;&gt;</span>
<p>
Remember to sign all the jar files and move them into the right place from the tmp directory.
</p>
</div>
<h3><a>JNLP file</a></h3>
<div>
<p>
Add the following to your JNLP file:
</p>
<pre> <span>&lt;resources os=&quot;Windows&quot;&gt;</span>
<span>&lt;j2se version=&quot;1.4+&quot;/&gt;</span> <span>&lt;j2se version=&quot;1.4+&quot;/&gt;</span>
<span>&lt;nativelib href=&quot;native_windows.jar&quot;/&gt;</span> <span>&lt;nativelib href=&quot;native_windows.jar&quot;/&gt;</span>
<span><span>&lt;/resources&gt;</span></span> <span><span>&lt;/resources&gt;</span></span>
@ -87,20 +32,11 @@ Add the following to your JNLP file:
<span>&lt;resources os=&quot;SunOS&quot; arch=&quot;x86&quot;&gt;</span> <span>&lt;resources os=&quot;SunOS&quot; arch=&quot;x86&quot;&gt;</span>
<span>&lt;j2se version=&quot;1.4+&quot;/&gt;</span> <span>&lt;j2se version=&quot;1.4+&quot;/&gt;</span>
<span>&lt;nativelib href=&quot;native_solaris.jar&quot;/&gt;</span> <span>&lt;nativelib href=&quot;native_solaris.jar&quot;/&gt;</span>
<span><span>&lt;/resources&gt;</span></span></pre> <span><span>&lt;/resources&gt;</span></span></pre></div><h3><a
</div> name="set_low-permissions_mode">Set low-permissions mode</a></h3><div
class="level3"><p> In your main() method, if running under WebStart, tell jME3 it is running in a low-permission environment so that it doesn&#039;t try to load the natives itself:</p><pre> public static void main&#40;String&#91;&#93; args&#41;
<h3><a>Set low-permissions mode</a></h3>
<div>
<p>
In your main() method, if running under WebStart, tell jME3 it is running in a low-permission environment so that it doesn&#039;t try to load the natives itself:
</p>
<pre> public static void main&#40;String&#91;&#93; args&#41;
&#123; &#123;
if &#40;System.getProperty&#40;&quot;javawebstart.version&quot;&#41; != null&#41; &#123; if &#40;System.getProperty&#40;&quot;javawebstart.version&quot;&#41; != null&#41; &#123;
JmeSystem.setLowPermissions&#40;true&#41;; JmeSystem.setLowPermissions&#40;true&#41;;
&#125;</pre> &#125;</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:webstart?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:webstart?do=export_xhtmlbody">view online version</a></em></p>

@ -1,312 +1,146 @@
<h1><a
<h1><a>jMonkeyPlatform: Application Deployment</a></h1> name="jmonkeyplatformapplication_deployment">jMonkeyPlatform: Application Deployment</a></h1><div
<div> class="level1"><p> After you have written and tested your game, you want to brand it and distribute it to your users. If you use the build script provided by the jMonkeyPlatform&#039;s BaseGame, you have the following deployment options:</p><ul><li
class="level1"><div
<p> class="li"> Desktop application (.JAR)</div></li><li
class="level1"><div
After you have written and tested your game, you want to brand it and distribute it to your users. If you use the build script provided by the jMonkeyPlatform&#039;s BaseGame, you have the following deployment options: class="li"> WebStart from <acronym
title="Uniform Resource Locator">URL</acronym> (.JNLP + .JAR)</div></li><li
</p> class="level1"><div
<ul> class="li"> Applet in browser page (.JNLP + .JAR)</div></li><li
<li><div> Desktop application (.JAR)</div> class="level1"><div
</li> class="li"> Android Mobile phone (work in progress)</div></li></ul></div><h2><a
<li><div> WebStart from <acronym title="Uniform Resource Locator">URL</acronym> (.JNLP + .JAR)</div> name="requirements">Requirements</a></h2><div
</li> class="level2"><p> Since JAR files are platform independent, your customers can play your jMonkeyEngine application on Windows, Mac <acronym
<li><div> Applet in browser page (.JNLP + .JAR)</div> title="Operating System">OS</acronym>, or Linux. The only requirement is that the user has the free Java 5 or 6 Runtime (or browser plugin) installed. For more information see <a
</li> href="http://java.com">http://java.com</a>.</p></div><h2><a
<li><div> Android Mobile phone (work in progress)</div> name="branding">Branding</a></h2><div
</li> class="level2"><ol><li
</ul> class="level1"><div
class="li"> Open your game project in the jMonkeyPlatform&#039;s Projects window.</div></li><li
</div> class="level1"><div
class="li"> Right-click the project and open the Properties</div></li><li
<h2><a>Requirements</a></h2> class="level1"><div
<div> class="li"> Open the properties → Application section. Here you do your branding:</div><ol><li
class="level2"><div
<p> class="li"> Title: the game&#039;s name</div></li><li
class="level2"><div
Since JAR files are platform independent, your customers can play your jMonkeyEngine application on Windows, Mac <acronym title="Operating System">OS</acronym>, or Linux. The only requirement is that the user has the free Java 5 or 6 Runtime (or browser plugin) installed. For more information see <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://java.com"><param name="text" value="<html><u>http://java.com</u></html>"><param name="textColor" value="blue"></object>. class="li"> Vendor: your name</div></li><li
</p> class="level2"><div
class="li"> Description: why your game is the coolest ever ;)</div></li><li
</div> class="level2"><div
class="li"> Homepage: Your web <acronym
<h2><a>Branding</a></h2> title="Uniform Resource Locator">URL</acronym></div></li><li
<div> class="level2"><div
<ol> class="li"> Splashscreen: Browse to a picture that will be shown while the game loads.</div></li></ol></li><li
<li><div> Open your game project in the jMonkeyPlatform&#039;s Projects window. </div> class="level1"><div
</li> class="li"> Click OK.</div></li><li
<li><div> Right-click the project and open the Properties</div> class="level1"><div
</li> class="li"> Clean and Build.</div></li></ol></div><h2><a
<li><div> Open the properties → Application section. Here you do your branding: </div> name="creating_the_distributable">Creating the Distributable</a></h2><div
<ol> class="level2"><p> When you run the build script provided by the jMonkeyPlatform, it automatically compiles your classes, libraries, and assets. It creates a <code>dist</code> directory in your project directory which contains the executable JAR and a directory with libraries.</p><p> In the simplest case, you zip up the <code>dist</code> directory and distribute it to your customers. Companies often have additional tools to create executables and installers.</p><p> Here are your deployment options in detail:</p></div><h3><a
<li><div> Title: the game&#039;s name</div> name="desktop_application_jar">Desktop Application (JAR)</a></h3><div
</li> class="level3"><p> The JAR file is the most common deployment method for Java desktop applications. The user downloads the executable JAR file to his machine and runs it to start the game.</p><ol><li
<li><div> Vendor: your name</div> class="level1"><div
</li> class="li"> Right-click your project and open the Project Properties.</div></li><li
<li><div> Description: why your game is the coolest ever ;)</div> class="level1"><div
</li> class="li"> In the Application&gt;Web Start category, make sure the box &quot;Enable Web Start&quot; is not checked. Click OK.</div></li><li
<li><div> Homepage: Your web <acronym title="Uniform Resource Locator">URL</acronym></div> class="level1"><div
</li> class="li"> Right-click your project and Clean and Build.</div></li><li
<li><div> Splashscreen: Browse to a picture that will be shown while the game loads.</div> class="level1"><div
</li> class="li"> If the build succeeds you see a line similar to <br/> <code>Building jar: /home/joe/jMonkeyPlatform/MySuperTestGame/dist/MySuperTestGame.jar</code> <br/> this means the executable JAR has been generated successfully in your project directory.</div></li><li
</ol> class="level1"><div
</li> class="li"> Zip up the <code>dist</code> directory and distribute it to your users. Make sure to keep the <code>lib</code> directory in it!</div></li></ol><p> Most operating systems execute a JAR when users double-click on it, but you can also create a launcher.</p></div><h3><a
<li><div> Click OK. </div> name="desktop_executables">Desktop Executables</a></h3><div
</li> class="level3"><p> jMonkeyPlatform allows you to create launchers for different desktop platforms, like an .exe file for Windows systems, an Application for MaxOSX and a launcher for Linux systems.</p><ol><li
<li><div> Clean and Build.</div> class="level1"><div
</li> class="li"> Right-click your project and open the Project Properties.</div></li><li
</ol> class="level1"><div
class="li"> In the Application&gt;Desktop category, select the checkboxes for the platforms you want to distribute to.</div></li><li
</div> class="level1"><div
class="li"> Click OK.</div></li></ol><p> When you build your project, zip files for each selected platform will be created in the <code>dist</code> folder that contain all that is needed to run your application on that platform.</p></div><h3><a
<h2><a>Creating the Distributable</a></h2> name="web_start_jnlp">Web Start (JNLP)</a></h3><div
<div> class="level3"><p> Web Start allows your users to start your application by simply clicking a link that you provide, for example in a button on your web page. The browser downloads the JAR file and then automatically runs your game in an extra window. The only requirement is that the user&#039;s browser has the Java plugin installed. This is a very user-friendly way for your customers to play your game without any extra steps to install it. Optionally, you can set it up so the file is saved to their desktop and can be restarted later, so they do not need to be online to play.</p><ol><li
class="level1"><div
<p> class="li"> Right-click your project and open the Project Properties.</div><ol><li
class="level2"><div
When you run the build script provided by the jMonkeyPlatform, it automatically compiles your classes, libraries, and assets. It creates a <code>dist</code> directory in your project directory which contains the executable JAR and a directory with libraries. class="li"> In the Application&gt;Web Start category, check the box to Enable Web Start.</div></li><li
</p> class="level2"><div
class="li"> Check the box to make the application self-signed. <img
<p> src="/wiki/lib/images/smileys/icon_exclaim.gif" class="middle" alt=":!:" /></div></li><li
In the simplest case, you zip up the <code>dist</code> directory and distribute it to your customers. Companies often have additional tools to create executables and installers. class="level2"><div
</p> class="li"> Optionally, check the box to allow offline use.</div></li><li
class="level2"><div
<p> class="li"> Make sure <code>Application Descriptor</code> is activated. Click OK.</div></li></ol></li><li
Here are your deployment options in detail: class="level1"><div
class="li"> Right-click your project and Clean and Build. The <code>dist</code> directory is generated.</div></li><li
</p> class="level1"><div
class="li"> Upload the contents of the <code>dist</code> directory to a public http server</div></li><li
</div> class="level1"><div
class="li"> Either edit the sample launch.html file, or simply add a standard link (A HREF) pointing to your .jnlp file to one of your web pages.</div></li><li
<h3><a>Desktop Application (JAR)</a></h3> class="level1"><div
<div> class="li"> Tell your users to open your page in a webbrowser, and click the link to webstart the application.</div></li></ol><p> Look at the sample launch.html, you can have any custom content around the link. Keep a copy of your launcher file because the jMonkeyPlatform will always regenerate its default launch.html.</p><p> Also, see this <a
href="http://www.youtube.com/watch?v=oZnssg8TBWQ">demo video</a> on creating WebStarts.</p></div><h3><a
<p> name="browser_applet">Browser Applet</a></h3><div
class="level3"><p> A browser Applet is a Java application that runs in the web browser while the user is visiting your web page. The only requirement is that the user&#039;s browser has the Java plugin installed. There is no installation step, the user can play right away in the browser. The user will not be able to save the game to his harddrive, nor can he play offline.</p><p> These instrcutions assume that you have already written a game that you want to turn into an Applet. As opposed to other jME3 games, Applets cannot capture the mouse for navigation, so the camera will be switched to dragToRotate mode. The jMonkeyPlatform and the included build script already contain what you need.</p></div><h4><a
The JAR file is the most common deployment method for Java desktop applications. The user downloads the executable JAR file to his machine and runs it to start the game. name="to_turn_a_project_into_an_applet">To Turn a Project Into an Applet</a></h4><div
class="level4"><ol><li
</p> class="level1"><div
<ol> class="li"> Right-click your project and open the Project Properties.</div><ol><li
<li><div> Right-click your project and open the Project Properties. </div> class="level2"><div
</li> class="li"> In the Application&gt;Applet category, check the box to enable Applet creation.</div></li><li
<li><div> In the Application&gt;Web Start category, make sure the box “Enable Web Start” is not checked. Click OK.</div> class="level2"><div
</li> class="li"> Change the applet width and height as you want it.</div></li><li
<li><div> Right-click your project and Clean and Build. </div> class="level2"><div
</li> class="li"> Click OK.</div></li></ol></li><li
<li><div> If the build succeeds you see a line similar to <br/> class="level1"><div
<code>Building jar: /home/joe/jMonkeyPlatform/MySuperTestGame/dist/MySuperTestGame.jar</code> <br/> class="li"> Right-click your project and Clean and Build.</div></li></ol><p> The <code>dist/Applet</code> directory now contains all the files necessary for the game to run as Applet. To test the Applet-based game, run the project in the jMonkeyPlatform.</p></div><h4><a
this means the executable JAR has been generated successfully in your project directory. </div> name="to_deploy_the_game_as_applet">To Deploy the Game as Applet</a></h4><div
</li> class="level4"><ol><li
<li><div> Zip up the <code>dist</code> directory and distribute it to your users. Make sure to keep the <code>lib</code> directory in it! </div> class="level1"><div
</li> class="li"> Edit the <code>dist/Applet/run-applet.html</code> file in anyway you like. Just keep the Applet code.</div></li><li
</ol> class="level1"><div
class="li"> Upload the contents of the <code>dist/Applet</code> directory to a public http server.</div></li><li
<p> class="level1"><div
class="li"> Access the run-applet.html file using a webbrowser</div></li><li
Most operating systems execute a JAR when users double-click on it, but you can also create a launcher. class="level1"><div
</p> class="li"> Click the link to web-start your application.</div></li></ol></div><h4><a
name="to_troubleshoot_applets">To Troubleshoot Applets</a></h4><div
</div> class="level4"><ul><li
class="level1"><div
<h3><a>Desktop Executables</a></h3> class="li"> Open the Java console for error messages.</div></li><li
<div> class="level1"><div
class="li"> Depending on your settings, the browser caches the applet, the html page, and/or the jnlp file, even after you have cleaned and built the project. Make sure to empty the browser cache.</div></li></ul></div><h3><a
<p> name="android">Android</a></h3><div
class="level3"><p> TODO</p></div><h2><a
jMonkeyPlatform allows you to create launchers for different desktop platforms, like an .exe file for Windows systems, an Application for MaxOSX and a launcher for Linux systems. name="tipswitching_build_configurations">Tip: Switching Build Configurations</a></h2><div
class="level2"><p> The jMonkeyPlatform has a Run Configuration menu in the toolbar. Use it to save your various sets of Project Property configuations, and switch between them.</p><ol><li
</p> class="level1"><div
<ol> class="li"> Click the <code>Set Project Configuration</code> popup in the toolbar and choose Customize.</div></li><li
<li><div> Right-click your project and open the Project Properties. </div> class="level1"><div
</li> class="li"> The Project Properties Run section opens. Under Configuration, click New.</div></li><li
<li><div> In the Application&gt;Desktop category, select the checkboxes for the platforms you want to distribute to.</div> class="level1"><div
</li> class="li"> Name the saved configuration, for instance &quot;my webstart&quot; vs &quot;my desktop app&quot;, or &quot;development&quot; vs &quot;deployment&quot;. Click OK.</div></li><li
<li><div> Click OK.</div> class="level1"><div
</li> class="li"> Make sure the new config is selected in the <code>Set Project Configuration</code> popup above the editor.</div></li><li
</ol> class="level1"><div
class="li"> Make changes to the Project Properties as described above.</div></li></ol><p> Now you can use the <code>Set Project Configuration</code> popup menu to switch between your run/build configurations.</p></div><h2><a
<p> name="tipreducing_distribution_size">Tip: Reducing Distribution Size</a></h2><div
class="level2"><p> There may be several parts of the full jMonkeyEngine library that you do not even use in your application. You should leave out the corresponding libraries from your distribution.</p><p> To remove unused libraries:</p><ol><li
When you build your project, zip files for each selected platform will be created in the <code>dist</code> folder that contain all that is needed to run your application on that platform. class="level1"><div
</p> class="li"> Right-click your project and select &quot;Properties&quot;</div></li><li
class="level1"><div
</div> class="li"> Select &quot;Libraries&quot; on the left</div></li><li
class="level1"><div
<h3><a>Web Start (JNLP)</a></h3> class="li"> Select the &quot;jme3-libraries&quot; entry and press &quot;remove&quot;. <br/> This library package contains <strong>all</strong> libraries for jME3 and is quite large.</div></li><li
<div> class="level1"><div
class="li"> Press the &quot;Add Library&quot; button</div></li><li
<p> class="level1"><div
class="li"> Select the &quot;jme3-libraries-lwjgl-minimum&quot; library</div></li><li
Web Start allows your users to start your application by simply clicking a link that you provide, for example in a button on your web page. The browser downloads the JAR file and then automatically runs your game in an extra window. The only requirement is that the user&#039;s browser has the Java plugin installed. This is a very user-friendly way for your customers to play your game without any extra steps to install it. Optionally, you can set it up so the file is saved to their desktop and can be restarted later, so they do not need to be online to play. class="level1"><div
class="li"> Add other jME3 libraries in the same way depending which features you use (jme3-libraries-gui, jme3-libraries-physics, jme3-libraries-video etc.)</div></li><li
</p> class="level1"><div
<ol> class="li"> Click OK.</div></li><li
<li><div> Right-click your project and open the Project Properties. </div> class="level1"><div
<ol> class="li"> Clean, Build and Run the project and make sure you have not missed anything.</div></li></ol></div>
<li><div> In the Application&gt;Web Start category, check the box to Enable Web Start. </div>
</li>
<li><div> Check the box to make the application self-signed. <img src="/wiki/lib/images/smileys/icon_exclaim.gif" class="middle" alt=":!:" /> </div>
</li>
<li><div> Optionally, check the box to allow offline use. </div>
</li>
<li><div> Make sure <code>Application Descriptor</code> is activated. Click OK.</div>
</li>
</ol>
</li>
<li><div> Right-click your project and Clean and Build. The <code>dist</code> directory is generated. </div>
</li>
<li><div> Upload the contents of the <code>dist</code> directory to a public http server</div>
</li>
<li><div> Either edit the sample launch.html file, or simply add a standard link (A HREF) pointing to your .jnlp file to one of your web pages.</div>
</li>
<li><div> Tell your users to open your page in a webbrowser, and click the link to webstart the application.</div>
</li>
</ol>
<p>
Look at the sample launch.html, you can have any custom content around the link. Keep a copy of your launcher file because the jMonkeyPlatform will always regenerate its default launch.html.
</p>
<p>
Also, see this <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.youtube.com/watch?v=oZnssg8TBWQ"><param name="text" value="<html><u>demo video</u></html>"><param name="textColor" value="blue"></object> on creating WebStarts.
</p>
</div>
<h3><a>Browser Applet</a></h3>
<div>
<p>
A browser Applet is a Java application that runs in the web browser while the user is visiting your web page. The only requirement is that the user&#039;s browser has the Java plugin installed. There is no installation step, the user can play right away in the browser. The user will not be able to save the game to his harddrive, nor can he play offline.
</p>
<p>
These instrcutions assume that you have already written a game that you want to turn into an Applet. As opposed to other jME3 games, Applets cannot capture the mouse for navigation, so the camera will be switched to dragToRotate mode. The jMonkeyPlatform and the included build script already contain what you need.
</p>
</div>
<h4><a>To Turn a Project Into an Applet</a></h4>
<div>
<ol>
<li><div> Right-click your project and open the Project Properties. </div>
<ol>
<li><div> In the Application&gt;Applet category, check the box to enable Applet creation. </div>
</li>
<li><div> Change the applet width and height as you want it.</div>
</li>
<li><div> Click OK.</div>
</li>
</ol>
</li>
<li><div> Right-click your project and Clean and Build. </div>
</li>
</ol>
<p>
The <code>dist/Applet</code> directory now contains all the files necessary for the game to run as Applet. To test the Applet-based game, run the project in the jMonkeyPlatform.
</p>
</div>
<h4><a>To Deploy the Game as Applet</a></h4>
<div>
<ol>
<li><div> Edit the <code>dist/Applet/run-applet.html</code> file in anyway you like. Just keep the Applet code.</div>
</li>
<li><div> Upload the contents of the <code>dist/Applet</code> directory to a public http server.</div>
</li>
<li><div> Access the run-applet.html file using a webbrowser</div>
</li>
<li><div> Click the link to web-start your application.</div>
</li>
</ol>
</div>
<h4><a>To Troubleshoot Applets</a></h4>
<div>
<ul>
<li><div> Open the Java console for error messages.</div>
</li>
<li><div> Depending on your settings, the browser caches the applet, the html page, and/or the jnlp file, even after you have cleaned and built the project. Make sure to empty the browser cache.</div>
</li>
</ul>
</div>
<h3><a>Android</a></h3>
<div>
<p>
TODO
</p>
</div>
<h2><a>Tip: Switching Build Configurations</a></h2>
<div>
<p>
The jMonkeyPlatform has a Run Configuration menu in the toolbar. Use it to save your various sets of Project Property configuations, and switch between them.
</p>
<ol>
<li><div> Click the <code>Set Project Configuration</code> popup in the toolbar and choose Customize.</div>
</li>
<li><div> The Project Properties Run section opens. Under Configuration, click New.</div>
</li>
<li><div> Name the saved configuration, for instance “my webstart” vs “my desktop app”, or “development” vs “deployment”. Click OK.</div>
</li>
<li><div> Make sure the new config is selected in the <code>Set Project Configuration</code> popup above the editor.</div>
</li>
<li><div> Make changes to the Project Properties as described above. </div>
</li>
</ol>
<p>
Now you can use the <code>Set Project Configuration</code> popup menu to switch between your run/build configurations.
</p>
</div>
<h2><a>Tip: Reducing Distribution Size</a></h2>
<div>
<p>
There may be several parts of the full jMonkeyEngine library that you do not even use in your application. You should leave out the corresponding libraries from your distribution.
</p>
<p>
To remove unused libraries:
</p>
<ol>
<li><div> Right-click your project and select “Properties”</div>
</li>
<li><div> Select “Libraries” on the left</div>
</li>
<li><div> Select the “jme3-libraries” entry and press “remove”. <br/>
This library package contains <strong>all</strong> libraries for jME3 and is quite large.</div>
</li>
<li><div> Press the “Add Library” button</div>
</li>
<li><div> Select the “jme3-libraries-lwjgl-minimum” library</div>
</li>
<li><div> Add other jME3 libraries in the same way depending which features you use (jme3-libraries-gui, jme3-libraries-physics, jme3-libraries-video etc.) </div>
</li>
<li><div> Click OK.</div>
</li>
<li><div> Clean, Build and Run the project and make sure you have not missed anything.</div>
</li>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:application_deployment?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:application_deployment?do=export_xhtmlbody">view online version</a></em></p>

@ -1,188 +1,61 @@
<h1><a
<h1><a>jMonkeyPlatform AssetPacks</a></h1> name="jmonkeyplatform_assetpacks">jMonkeyPlatform AssetPacks</a></h1><div
<div> class="level1"><p> AssetPacks are a way to package jME3 compatible assets like models, textures, sounds and whole scenes into a package that contains publisher info, license info, descriptions etc. for all of the assets. An AssetPack basically consists of an <code>assetpack.xml</code> file that describes the content and an <code>assets</code> folder that contains the content. The integrated browser in jMP allows you to add the assets of installed AssetPacks to any project you are doing.</p></div><h2><a
name="the_assetpack_browser">The AssetPack Browser</a></h2><div
<p> class="level2"><p> <a
AssetPacks are a way to package jME3 compatible assets like models, textures, sounds and whole scenes into a package that contains publisher info, license info, descriptions etc. for all of the assets. An AssetPack basically consists of an <code>assetpack.xml</code> file that describes the content and an <code>assets</code> folder that contains the content. The integrated browser in jMP allows you to add the assets of installed AssetPacks to any project you are doing. href="/wiki/lib/exe/fetch.php?hash=1ca01e&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackbrowser-300x166.jpg"><img
</p> src="/wiki/lib/exe/fetch.php?hash=1ca01e&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackbrowser-300x166.jpg" class="mediaright" align="right" title="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackbrowser-300x166.jpg" alt="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackbrowser-300x166.jpg" /></a></p><p> The AssetPack browser in jMP makes browsing the installed AssetPacks easy. Browse categories, search for tags and find the right asset for your project. When you have found it, you can add it with one click to your current scene. The AssetPack manager will automagically copy all needed textures, sounds etc. to your projects assets folder.</p><p> You can also browse a selection of online assetpacks that are available on jMonkeyEngine.org for download and install them to your jMonkeyPlatforms AssetPack browser.</p><p> The AssetPack browser uses a predefined directory to store the AssetPacks which is also used for new AssetPack projects. You can see and change the folder path in the AssetPack preferences (jMonkeyPlatform→Settings).</p></div><h3><a
name="using_the_browser">Using the browser</a></h3><div
</div> class="level3"><p> To preview a model from the browser, right-click it and select &quot;Preview Asset&quot;</p><p> To add a model from the AssetPack browser to a scene do the following:</p><ol><li
class="level1"><div
<h2><a>The AssetPack Browser</a></h2> class="li"> Create a new scene (j3o) file or use an existing one</div></li><li
<div> class="level1"><div
class="li"> Open it in the SceneComposer by right-clicking it and selecting &quot;Edit in SceneComposer&quot;</div></li><li
<p> class="level1"><div
class="li"> Select the root node of the scene (or another node you want to add the model to)</div></li><li
<img src="/wiki/lib/exe/fetch.php"> class="level1"><div
</p> class="li"> Right-click a model in the AssetBrowser and select &quot;Add to SceneComposer&quot;</div></li></ol><p> The model will be added to your scene and all needed texture files will be copied to your projects assets folder.</p></div><h2><a
name="assetpack_projects">AssetPack Projects</a></h2><div
<p> class="level2"><p> AssetPack projects are a way to create your own AssetPacks, either for personal use or for publishing. With this project type in jMonkeyPlatform you can create a library of assets on your computer that you can use in any of your projects via the AssetPack browser.
The AssetPack browser in jMP makes browsing the installed AssetPacks easy. Browse categories, search for tags and find the right asset for your project. When you have found it, you can add it with one click to your current scene. The AssetPack manager will automagically copy all needed textures, sounds etc. to your projects assets folder. Editing of asset and project info, adding of new assets and setting their properties, everything you need to create and publish your AssetPacks is there.</p><ol><li
</p> class="level1"><div
class="li"> Select &quot;File → New Project&quot;</div></li><li
<p> class="level1"><div
You can also browse a selection of online assetpacks that are available on jMonkeyEngine.org for download and install them to your jMonkeyPlatforms AssetPack browser. class="li"> Select &quot;AssetPack Project&quot;</div></li><li
</p> class="level1"><div
class="li"> Fill in the project info and press &quot;finish&quot;</div></li></ol><p> You can access and change the project properties by right-clicking the project and selecting &quot;Properties&quot;.</p></div><h3><a
<p> name="adding_assets">Adding Assets</a></h3><div
The AssetPack browser uses a predefined directory to store the AssetPacks which is also used for new AssetPack projects. You can see and change the folder path in the AssetPack preferences (jMonkeyPlatform→Settings). class="level3"><p> <a
</p> href="/wiki/lib/exe/fetch.php?hash=2edd4a&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackimport-300x222.jpg"><img
src="/wiki/lib/exe/fetch.php?hash=2edd4a&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackimport-300x222.jpg" class="mediaright" align="right" title="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackimport-300x222.jpg" alt="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackimport-300x222.jpg" /></a></p><p> To add new assets to your AssetPack do the following:</p><ol><li
</div> class="level1"><div
class="li"> Right-Click the &quot;Assets&quot; node of the AssetPack project</div></li><li
<h3><a>Using the browser</a></h3> class="level1"><div
<div> class="li"> Select &quot;Add Asset..&quot;</div></li><li
class="level1"><div
<p> class="li"> Specify the info about your asset and press Next</div></li><li
To preview a model from the browser, right-click it and select “Preview Asset” class="level1"><div
</p> class="li"> Press the &quot;add files&quot; button and select all files belonging to your asset</div></li><li
class="level1"><div
<p> class="li"> Select the &quot;main&quot; checkbox for the main model file if your asset is a model file</div></li><li
To add a model from the AssetPack browser to a scene do the following: class="level1"><div
</p> class="li"> Change the asset paths and types if needed and press &quot;finish&quot;</div></li></ol><p> The global asset type can be &quot;model&quot;, &quot;scene&quot;, &quot;texture&quot;, &quot;sound&quot;, &quot;shader&quot; or &quot;other&quot;</p><p> With the &quot;model&quot; or &quot;scene&quot; types, the AssetPack browser will try to load and add a model file from the selected assets when the user selects &quot;Add to SceneComposer&quot;. Specify the &quot;load this model with material&quot; flag for the model file that should be loaded via the AssetManager, you can also specify multiple mesh or scene files to be loaded. All texture and other needed files will be copied to the users project folder.</p><p> On the &quot;Add Files&quot; page you define the path of the files in the AssetPack. The importer tries to generate a proper path from the info entered on the first page. Note that for j3o binary models, the texture paths have to be exactly like they were during conversion. The given paths will also be used when copying the data to the users &quot;assets&quot; folder.</p><p> With the &quot;add files&quot; button you can open a file browser to select files from your harddisk that will be copied into the <code>assets/</code> folder of the AssetPack project. With the &quot;add existing&quot; button you can add a file thats already in your AssetPack assets folder to a new asset item. This way you can reuse e.g. textures for asset items or make items for an existing collection of asset files that you copied to the projects assets folder.</p><p> <a
<ol> href="/wiki/lib/exe/fetch.php?hash=8119b0&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackimport2-300x179.jpg"><img
<li><div> Create a new scene (j3o) file or use an existing one</div> src="/wiki/lib/exe/fetch.php?hash=8119b0&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackimport2-300x179.jpg" class="mediaright" align="right" title="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackimport2-300x179.jpg" alt="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackimport2-300x179.jpg" /></a></p><p> You can specify a specific material to be used for the single mesh/scene files, just select it in the dropdown below the mesh or scene file. If you don&#039;t select a material file here, the first found material file is used or none if none is found.</p><p> If the material file is an Ogre material file (.material) it will be used for loading an Ogre scene or mesh file. If it is a jMonkeyEngine3 material file (.j3m), it will be applied to the mesh regardless of model type. Note that for j3o models you don&#039;t need material files as the material is stored inside the j3o file.</p><p> In your AssetPack Project, if you right-click your asset and select &quot;preview asset&quot; you should be able to see your model. If you do, it should work for the user as well.</p><p> You can change the single assets properties in the properties window after you have added them. Just select an asset and open the properties window (Windows→Properties).</p><p> Supported formats for models are:</p><ol><li
</li> class="level1"><div
<li><div> Open it in the SceneComposer by right-clicking it and selecting “Edit in SceneComposer”</div> class="li"> OgreXML</div></li><li
</li> class="level1"><div
<li><div> Select the root node of the scene (or another node you want to add the model to)</div> class="li"> Wavefront OBJ</div></li><li
</li> class="level1"><div
<li><div> Right-click a model in the AssetBrowser and select “Add to SceneComposer”</div> class="li"> jMonkeyEngine3 j3o</div></li></ol></div><h3><a
</li> name="assetpack_publishing">AssetPack Publishing</a></h3><div
</ol> class="level3"><p> <a
href="/wiki/lib/exe/fetch.php?hash=2498cf&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackdownload-263x300.jpg"><img
<p> src="/wiki/lib/exe/fetch.php?hash=2498cf&amp;media=http%3A%2F%2Fjmonkeyengine.org%2Fwp-content%2Fuploads%2F2010%2F10%2Fassetpackdownload-263x300.jpg" class="mediaright" align="right" title="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackdownload-263x300.jpg" alt="jmonkeyengine.org_wp-content_uploads_2010_10_assetpackdownload-263x300.jpg" /></a></p><p> You can publish your AssetPacks either as a zip file or directly to jmonkeyengine.org, using your website user name and login. This means other jMonkeyPlatform users can download your AssetPacks and install them to their local database right off the AssetPack online packages browser.</p><p> To make sure you can upload, you have to be registered on jmonkeyengine.org and have to enter your login info in the AssetPack preferences (jMonkeyPlatform→Settings).</p><ol><li
The model will be added to your scene and all needed texture files will be copied to your projects assets folder. class="level1"><div
</p> class="li"> Right-Click your AssetPack project and select &quot;Publish AssetPack..&quot;</div></li><li
class="level1"><div
</div> class="li"> Check the description etc. settings and press &quot;Next&quot;</div></li><li
class="level1"><div
<h2><a>AssetPack Projects</a></h2> class="li"> Select the checkbox for online and/or local publishing and press &quot;finish&quot;</div></li></ol></div>
<div>
<p>
AssetPack projects are a way to create your own AssetPacks, either for personal use or for publishing. With this project type in jMonkeyPlatform you can create a library of assets on your computer that you can use in any of your projects via the AssetPack browser.
Editing of asset and project info, adding of new assets and setting their properties, everything you need to create and publish your AssetPacks is there.
</p>
<ol>
<li><div> Select “File → New Project”</div>
</li>
<li><div> Select “AssetPack Project”</div>
</li>
<li><div> Fill in the project info and press “finish”</div>
</li>
</ol>
<p>
You can access and change the project properties by right-clicking the project and selecting “Properties”.
</p>
</div>
<h3><a>Adding Assets</a></h3>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
To add new assets to your AssetPack do the following:
</p>
<ol>
<li><div> Right-Click the “Assets” node of the AssetPack project</div>
</li>
<li><div> Select “Add Asset..”</div>
</li>
<li><div> Specify the info about your asset and press Next</div>
</li>
<li><div> Press the “add files” button and select all files belonging to your asset</div>
</li>
<li><div> Select the “main” checkbox for the main model file if your asset is a model file</div>
</li>
<li><div> Change the asset paths and types if needed and press “finish”</div>
</li>
</ol>
<p>
The global asset type can be “model”, “scene”, “texture”, “sound”, “shader” or “other”
</p>
<p>
With the “model” or “scene” types, the AssetPack browser will try to load and add a model file from the selected assets when the user selects “Add to SceneComposer”. Specify the “load this model with material” flag for the model file that should be loaded via the AssetManager, you can also specify multiple mesh or scene files to be loaded. All texture and other needed files will be copied to the users project folder.
</p>
<p>
On the “Add Files” page you define the path of the files in the AssetPack. The importer tries to generate a proper path from the info entered on the first page. Note that for j3o binary models, the texture paths have to be exactly like they were during conversion. The given paths will also be used when copying the data to the users “assets” folder.
</p>
<p>
With the “add files” button you can open a file browser to select files from your harddisk that will be copied into the <code>assets/</code> folder of the AssetPack project. With the “add existing” button you can add a file thats already in your AssetPack assets folder to a new asset item. This way you can reuse e.g. textures for asset items or make items for an existing collection of asset files that you copied to the projects assets folder.
</p>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
You can specify a specific material to be used for the single mesh/scene files, just select it in the dropdown below the mesh or scene file. If you don&#039;t select a material file here, the first found material file is used or none if none is found.
</p>
<p>
If the material file is an Ogre material file (.material) it will be used for loading an Ogre scene or mesh file. If it is a jMonkeyEngine3 material file (.j3m), it will be applied to the mesh regardless of model type. Note that for j3o models you don&#039;t need material files as the material is stored inside the j3o file.
</p>
<p>
In your AssetPack Project, if you right-click your asset and select “preview asset” you should be able to see your model. If you do, it should work for the user as well.
</p>
<p>
You can change the single assets properties in the properties window after you have added them. Just select an asset and open the properties window (Windows→Properties).
</p>
<p>
Supported formats for models are:
</p>
<ol>
<li><div> OgreXML</div>
</li>
<li><div> Wavefront OBJ</div>
</li>
<li><div> jMonkeyEngine3 j3o</div>
</li>
</ol>
</div>
<h3><a>AssetPack Publishing</a></h3>
<div>
<p>
<img src="/wiki/lib/exe/fetch.php">
</p>
<p>
You can publish your AssetPacks either as a zip file or directly to jmonkeyengine.org, using your website user name and login. This means other jMonkeyPlatform users can download your AssetPacks and install them to their local database right off the AssetPack online packages browser.
</p>
<p>
To make sure you can upload, you have to be registered on jmonkeyengine.org and have to enter your login info in the AssetPack preferences (jMonkeyPlatform→Settings).
</p>
<ol>
<li><div> Right-Click your AssetPack project and select “Publish AssetPack..”</div>
</li>
<li><div> Check the description etc. settings and press “Next”</div>
</li>
<li><div> Select the checkbox for online and/or local publishing and press “finish”</div>
</li>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:asset_packs?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:asset_packs?do=export_xhtmlbody">view online version</a></em></p>

@ -1,252 +1,112 @@
<h1><a
<h1><a>jMonkeyPlatform: Code Editor and Palette</a></h1> name="jmonkeyplatformcode_editor_and_palette">jMonkeyPlatform: Code Editor and Palette</a></h1><div
<div> class="level1"><p> The Source Code Editor is the central part of the jMonkeyPlatform. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s assistive features.</p><p> Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the &quot;see also links&quot;).</p></div><h2><a
name="code_completion_and_code_generation">Code Completion and Code Generation</a></h2><div
<p> class="level2"><p> While typing Java code in the source code editor, you will see popups that help you to write more quickly by completing keywords, and generating code snippets. Additionally, they will let you see the javadoc for the classes you are working with.</p><p> <a
href="/wiki/lib/exe/detail.php/sdk:netbeans_code_completion.png?id=sdk%3Acode_editor"><img
The Source Code Editor is the central part of the jMonkeyPlatform. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s assistive features. src="nbdocs:/com/jme3/gde/core/docs/sdk/netbeans_code_completion.png" class="mediaright" align="right" alt="" /></a></p><p> Code Completion</p><ul><li
</p> class="level1"><div
class="li"> Complete keyword / method / variable: <strong>Ctrl-Space</strong> (Alternatively use <strong>Ctrl-\</strong>)</div><ul><li
<p> class="level2"><div
Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the “see also links”). class="li"> Customize Code Completion options: Tools &gt; Options &gt; Editor &gt; Code Completion</div></li></ul></li><li
</p> class="level1"><div
class="li"> Show expected parameters of this method in a tooltip: <strong>Ctrl-P</strong></div></li><li
</div> class="level1"><div
class="li"> Complete any string (even non-Java) that has been used before: <strong>(Shift-)Ctrl-K</strong></div></li></ul><p> Code Generation</p><ul><li
<h2><a>Code Completion and Code Generation</a></h2> class="level1"><div
<div> class="li"> Auto-fix import statements: <strong>Ctrl-Shift-I</strong></div></li><li
class="level1"><div
<p> class="li"> Auto-generate getters/setters, try/catch, equals/hashCode: <strong>Alt-Insert</strong></div><ul><li
class="level2"><div
While typing Java code in the source code editor, you will see popups that help you to write more quickly by completing keywords, and generating code snippets. Additionally, they will let you see the javadoc for the classes you are working with. class="li"> Customize code completion: Choose Tools &gt; Options &gt; Editor &gt; Code Completion</div></li></ul></li><li
</p> class="level1"><div
class="li"> Auto-generate common code snippets such as loops, declarations, println, by typing the <strong>template name + TabKey</strong></div><ul><li
<p> class="level2"><div
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/netbeans_code_completion.png"> class="li"> Customize code templates: Choose Tools &gt; Options &gt; Editor &gt; Code Templates</div></li></ul></li><li
</p> class="level1"><div
class="li"> Rename, move, or introduce methods, fields, and variables, without breaking the project: <strong>Refactoring menu</strong></div></li></ul></div><h2><a
<p> name="semantic_and_syntactic_coloring">Semantic and Syntactic Coloring</a></h2><div
Code Completion class="level2"><p> <a
</p> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-5.png?id=sdk%3Acode_editor"><img
<ul> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-5.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><p> The text color in the editor gives you important hints how the compiler will interpret what you typed, even before you compiled it.</p><p> Examples:</p><ul><li
<li><div> Complete keyword / method / variable: <strong>Ctrl-Space</strong> (Alternatively use <strong>Ctrl-\</strong>)</div> class="level1"><div
<ul> class="li"> Java keywords are <strong>blue</strong>, variables and fields are <strong>green</strong>, parameters are <strong>orange</strong>.</div></li><li
<li><div> Customize Code Completion options: Tools &gt; Options &gt; Editor &gt; Code Completion </div> class="level1"><div
</li> class="li"> <del>Strikethrough</del> means deprecated method or field.</div></li><li
</ul> class="level1"><div
</li> class="li"> <em
<li><div> Show expected parameters of this method in a tooltip: <strong>Ctrl-P</strong> </div> class="u">Gray underline</em> means unused variable or method.</div></li><li
</li> class="level1"><div
<li><div> Complete any string (even non-Java) that has been used before: <strong>(Shift-)Ctrl-K</strong></div> class="li"> Place the caret in a method or variable and all its ocurrences are marked <strong>tan</strong>.</div></li><li
</li> class="level1"><div
</ul> class="li"> Place the caret in a method&#039;s return type to highlight all exit points</div></li><li
class="level1"><div
<p> class="li"> and many more…</div></li></ul><p> To customize Colors and indentation:</p><ul><li
class="level1"><div
Code Generation class="li"> Tools &gt; Options &gt; Editor &gt; Formatting.</div></li><li
</p> class="level1"><div
<ul> class="li"> Tools &gt; Options &gt; Fonts and Colors.</div></li></ul></div><h2><a
<li><div> Auto-fix import statements: <strong>Ctrl-Shift-I</strong></div> name="editor_hints_and_quick_fixes_aka_lightbulbs">Editor Hints and Quick Fixes (a.k.a. Lightbulbs)</a></h2><div
</li> class="level2"><p> Editor hints and quick fixes show as lightbulbs along the left edge of the editor. They point out warnings and errors, and often propose useful solutions!</p><ul><li
<li><div> Auto-generate getters/setters, try/catch, equals/hashCode: <strong>Alt-Insert</strong></div> class="level1"><div
<ul> class="li"> Execute a quick fix: Place the caret in the line next to the lightbulb and press <strong>Alt-Enter</strong> (or click the lightbulb)</div><ul><li
<li><div> Customize code completion: Choose Tools &gt; Options &gt; Editor &gt; Code Completion</div> class="level2"><div
</li> class="li"> Customize hints: Choose Tools &gt; Options &gt; Editor &gt; Hints.</div></li></ul></li></ul></div><h2><a
</ul> name="javadoc">Javadoc</a></h2><div
</li> class="level2"><ul><li
<li><div> Auto-generate common code snippets such as loops, declarations, println, by typing the <strong>template name + TabKey</strong> </div> class="level1"><div
<ul> class="li"> Place the caret above a method or a class that has no Javadoc, type <code
<li><div> Customize code templates: Choose Tools &gt; Options &gt; Editor &gt; Code Templates</div> class="code html4strict">/**</code> and press Enter: The editor generates skeleton code for a Javadoc comment.</div></li><li
</li> class="level1"><div
</ul> class="li"> Right-click the project in the Projects window and choose Generate Javadoc.</div></li><li
</li> class="level1"><div
<li><div> Rename, move, or introduce methods, fields, and variables, without breaking the project: <strong>Refactoring menu</strong></div> class="li"> Right-click a file and choose Tools &gt; Analyze Javadoc</div></li></ul><p> To display a javadoc popup in the editor, place the caret in a line and press <strong>Ctrl-Space</strong> (Alternatively use <strong>Ctrl-\</strong>).</p><ul><li
</li> class="level1"><div
</ul> class="li"> If the javadoc popup doesn&#039;t work, make certain that</div><ul><li
class="level2"><div
</div> class="li"> You have the Java <acronym
title="Java Development Kit">JDK</acronym> documentation installed and set up: Tools &gt; Java Platforms</div></li><li
<h2><a>Semantic and Syntactic Coloring</a></h2> class="level2"><div
<div> class="li"> You downloaded and set up javadoc for third-party libraries: Project properties &gt; Libraries &gt; Edit</div></li></ul></li></ul></div><h2><a
name="navigating_the_jme3_source">Navigating the jME3 Source</a></h2><div
<p> class="level2"><p> When the JavaDoc does not deliver enough information, you can have a look at the source of every method or object of jME3 that you use. Just right-click the variable or method, select &quot;Navigate &gt; Go to source..&quot; and an editor will open showing you the source file of jME3.</p></div><h2><a
name="palette">Palette</a></h2><div
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-5.png"> class="level2"><p> <a
</p> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-4.png?id=sdk%3Acode_editor"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-4.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><p> Choose Windows &gt; Palette to open the context-sensitive Palette. The jMonkeyPlatform provides you with jme3 code snippets here that you can drag and drop into your source files.</p><ul><li
<p> class="level1"><div
The text color in the editor gives you important hints how the compiler will interpret what you typed, even before you compiled it. class="li"> Examples: Node and Model creation code snippets.</div></li></ul><p> Tip: Choose Tools &gt; Add to Palette… from the menu to add your own code snippets to the Palette. (not available yet in alpha build)</p></div><h2><a
</p> name="keyboard_shortcuts">Keyboard Shortcuts</a></h2><div
class="level2"><p> Keyboard Shortcuts save you time when when you need to repeat common actions such as Build&amp;Run or navigation to files.</p><ul><li
<p> class="level1"><div
Examples: class="li"> Go to File: <strong>Alt-Shift-O</strong></div></li><li
</p> class="level1"><div
<ul> class="li"> Go to Type: <strong>Ctrl-O</strong></div></li><li
<li><div> Java keywords are <strong>blue</strong>, variables and fields are <strong>green</strong>, parameters are <strong>orange</strong>. </div> class="level1"><div
</li> class="li"> Open in Projects / Files / Favorites window: <strong>Ctrl-Shift-1 / 2 / 3</strong></div></li><li
<li><div> <del>Strikethrough</del> means deprecated method or field. </div> class="level1"><div
</li> class="li"> Build&amp;Run Project / File: <strong>F6 / Shift-F6</strong></div></li><li
<li><div> <em>Gray underline</em> means unused variable or method.</div> class="level1"><div
</li> class="li"> Switch to Editor / Projects / Files / Navigator: <strong>Ctrl-0 / 1 / 3 / 7</strong></div></li><li
<li><div> Place the caret in a method or variable and all its ocurrences are marked <strong>tan</strong>.</div> class="level1"><div
</li> class="li"> Indent code: <strong>Ctrl-Shift-F</strong></div></li></ul><p> By default, jMonkeyEngine uses the same <a
<li><div> Place the caret in a method&#039;s return type to highlight all exit points</div> href="http://netbeans.org/project_downloads/www/shortcuts-6.5.pdf">Editor Shortcuts</a> as the NetBeans IDE, but you can also switch to an Eclipse Keymap, or create your own set.</p><ul><li
</li> class="level1"><div
<li><div> and many more…</div> class="li"> Customize keyboard shortcuts: Tools &gt; Options &gt; Keymap</div></li></ul></div><h2><a
</li> name="tips_and_tricks">Tips and Tricks</a></h2><div
</ul> class="level2"><ul><li
class="level1"><div
<p> class="li"> To browse the physical file structure of your project, use the Files window: <strong>Ctrl-2</strong></div></li><li
class="level1"><div
To customize Colors and indentation: class="li"> To open a file that is not part of a Java project, add it to the Favorites window: <strong>Ctrl-3</strong></div></li><li
</p> class="level1"><div
<ul> class="li"> If you cannot find a particular menu item or option panel, use the IDE Search box in the top right! <strong>Ctrl-i</strong></div></li><li
<li><div> Tools &gt; Options &gt; Editor &gt; Formatting.</div> class="level1"><div
</li> class="li"> If a code block, class, or javadoc is quite long and you don&#039;t want to scroll over it, click the <strong>+/-</strong> signs to collapse (fold) the code block temporarily.</div></li><li
<li><div> Tools &gt; Options &gt; Fonts and Colors.</div> class="level1"><div
</li> class="li"> Press <strong>F1</strong> for Help</div></li></ul><hr
</ul> /><p> See also</p><ul><li
class="level1"><div
</div> class="li"> <a
href="http://netbeans.org/kb/docs/java/editor-codereference.html">Code Assistance</a></div></li></ul></div>
<h2><a>Editor Hints and Quick Fixes (a.k.a. Lightbulbs)</a></h2>
<div>
<p>
Editor hints and quick fixes show as lightbulbs along the left edge of the editor. They point out warnings and errors, and often propose useful solutions!
</p>
<ul>
<li><div> Execute a quick fix: Place the caret in the line next to the lightbulb and press <strong>Alt-Enter</strong> (or click the lightbulb)</div>
<ul>
<li><div> Customize hints: Choose Tools &gt; Options &gt; Editor &gt; Hints.</div>
</li>
</ul>
</li>
</ul>
</div>
<h2><a>Javadoc</a></h2>
<div>
<ul>
<li><div> Place the caret above a method or a class that has no Javadoc, type <code>/**</code> and press Enter: The editor generates skeleton code for a Javadoc comment. </div>
</li>
<li><div> Right-click the project in the Projects window and choose Generate Javadoc.</div>
</li>
<li><div> Right-click a file and choose Tools &gt; Analyze Javadoc</div>
</li>
</ul>
<p>
To display a javadoc popup in the editor, place the caret in a line and press <strong>Ctrl-Space</strong> (Alternatively use <strong>Ctrl-\</strong>).
</p>
<ul>
<li><div> If the javadoc popup doesn&#039;t work, make certain that</div>
<ul>
<li><div> You have the Java <acronym title="Java Development Kit">JDK</acronym> documentation installed and set up: Tools &gt; Java Platforms </div>
</li>
<li><div> You downloaded and set up javadoc for third-party libraries: Project properties &gt; Libraries &gt; Edit</div>
</li>
</ul>
</li>
</ul>
</div>
<h2><a>Navigating the jME3 Source</a></h2>
<div>
<p>
When the JavaDoc does not deliver enough information, you can have a look at the source of every method or object of jME3 that you use. Just right-click the variable or method, select “Navigate &gt; Go to source..” and an editor will open showing you the source file of jME3.
</p>
</div>
<h2><a>Palette</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-4.png">
</p>
<p>
Choose Windows &gt; Palette to open the context-sensitive Palette. The jMonkeyPlatform provides you with jme3 code snippets here that you can drag and drop into your source files.
</p>
<ul>
<li><div> Examples: Node and Model creation code snippets.</div>
</li>
</ul>
<p>
Tip: Choose Tools &gt; Add to Palette… from the menu to add your own code snippets to the Palette. (not available yet in alpha build)
</p>
</div>
<h2><a>Keyboard Shortcuts</a></h2>
<div>
<p>
Keyboard Shortcuts save you time when when you need to repeat common actions such as Build&amp;Run or navigation to files.
</p>
<ul>
<li><div> Go to File: <strong>Alt-Shift-O</strong></div>
</li>
<li><div> Go to Type: <strong>Ctrl-O</strong></div>
</li>
<li><div> Open in Projects / Files / Favorites window: <strong>Ctrl-Shift-1 / 2 / 3</strong></div>
</li>
<li><div> Build&amp;Run Project / File: <strong>F6 / Shift-F6</strong></div>
</li>
<li><div> Switch to Editor / Projects / Files / Navigator: <strong>Ctrl-0 / 1 / 3 / 7</strong></div>
</li>
<li><div> Indent code: <strong>Ctrl-Shift-F</strong></div>
</li>
</ul>
<p>
By default, jMonkeyEngine uses the same <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/project_downloads/www/shortcuts-6.5.pdf"><param name="text" value="<html><u>Editor Shortcuts</u></html>"><param name="textColor" value="blue"></object> as the NetBeans IDE, but you can also switch to an Eclipse Keymap, or create your own set.
</p>
<ul>
<li><div> Customize keyboard shortcuts: Tools &gt; Options &gt; Keymap</div>
</li>
</ul>
</div>
<h2><a>Tips and Tricks</a></h2>
<div>
<ul>
<li><div> To browse the physical file structure of your project, use the Files window: <strong>Ctrl-2</strong></div>
</li>
<li><div> To open a file that is not part of a Java project, add it to the Favorites window: <strong>Ctrl-3</strong></div>
</li>
<li><div> If you cannot find a particular menu item or option panel, use the IDE Search box in the top right! <strong>Ctrl-i</strong></div>
</li>
<li><div> If a code block, class, or javadoc is quite long and you don&#039;t want to scroll over it, click the <strong>+/-</strong> signs to collapse (fold) the code block temporarily.</div>
</li>
<li><div> Press <strong>F1</strong> for Help</div>
</li>
</ul>
<hr />
<p>
See also
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/kb/docs/java/editor-codereference.html"><param name="text" value="<html><u>Code Assistance</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:code_editor?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:code_editor?do=export_xhtmlbody">view online version</a></em></p>

@ -1,236 +1,112 @@
<h1><a
<h1><a>jMonkeyPlatform: Debugging, Profiling, Testing</a></h1> name="jmonkeyplatformdebugging_profiling_testing">jMonkeyPlatform: Debugging, Profiling, Testing</a></h1><div
<div> class="level1"><p> Debugging, testing and profiling are important parts of the development cycle. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s assistive features.</p><p> <br/></p><p> Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the &quot;see also links&quot;).</p></div><h2><a
name="testing">Testing</a></h2><div
<p> class="level2"><p> The jMonkeyPlatform supports the JUnit testing framework. It is a good practice to write tests (assertions) for each of your classes. Each test makes certain this &quot;unit&quot; (e.g. method) meets its design and behaves as intended. Run your tests after each major change and you immediately see if you broke something.</p></div><h4><a
name="creating_tests">Creating Tests</a></h4><div
Debugging, testing and profiling are important parts of the development cycle. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s assistive features. class="level4"><ol><li
</p> class="level1"><div
class="li"> Right-click in a java file in the Projects window and choose Tools &gt; Create JUnit Tests.</div></li><li
<p> class="level1"><div
<br/> class="li"> Click OK. The jMonkeyPlatform creates a JUnit test skeleton in the Test Package directory.</div></li><li
class="level1"><div
</p> class="li"> The body of each generated test method is provided solely as a guide. In their place, you need to write your actual test cases!</div></li><li
class="level1"><div
<p> class="li"> You can use tests such as <code>assertTrue(), assertFalse(), assertEquals()</code>, or <code>assert()</code>.</div><ul><li
Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the “see also links”). class="level2"><div
</p> class="li"> Here is an example for assertions that test an addition method: <code>assert( add(1, 1) == 2); assert( add(2,-5) == -3); …</code></div></li></ul></li><li
class="level1"><div
</div> class="li"> &quot;Optimally&quot;, you should write a test case for every method (100% coverage).</div></li></ol><p> <br/> Tip: Use the Navigate menu to jump from a test to its tested class, and back.</p></div><h4><a
name="running_tests">Running Tests</a></h4><div
<h2><a>Testing</a></h2> class="level4"><ol><li
<div> class="level1"><div
class="li"> Right-click the class in the Projects window and Choose Test File, or right-click the project and select Test to run all tests.</div></li><li
<p> class="level1"><div
class="li"> Check the Test window to see successful test (green) and test failures (red).</div></li><li
The jMonkeyPlatform supports the JUnit testing framework. It is a good practice to write tests (assertions) for each of your classes. Each test makes certain this “unit” (e.g. method) meets its design and behaves as intended. Run your tests after each major change and you immediately see if you broke something. class="level1"><div
</p> class="li"> If a test fails that has succeeded before, you know that your latest changes broke something!</div></li></ol><p> Using unit tests regularly allows you to detect side-effects on classes that you thought were unaffected by a code change.</p><p> <br/> See also:</p><ul><li
class="level1"><div
</div> class="li"> <a
href="http://netbeans.org/kb/docs/java/junit-intro.html">Writing JUnit Tests</a></div></li><li
<h4><a>Creating Tests</a></h4> class="level1"><div
<div> class="li"> <a
<ol> href="http://www.junit.org">http://www.junit.org</a></div></li></ul></div><h2><a
<li><div> Right-click in a java file in the Projects window and choose Tools &gt; Create JUnit Tests.</div> name="debugging">Debugging</a></h2><div
</li> class="level2"><p> In the jMonkeyPlatform, you have access to a debugger to examine your application for errors such as deadlocks and NullPointerExeptions. You can set breakpoints, watch variables, and execute your code line-by-line to identify the source of a problem.</p><ol><li
<li><div> Click OK. The jMonkeyPlatform creates a JUnit test skeleton in the Test Package directory.</div> class="level1"><div
</li> class="li"> First, you set breakpoints and/or watches before the problematic lines of code where you suspect the bug.</div><ul><li
<li><div> The body of each generated test method is provided solely as a guide. In their place, you need to write your actual test cases!</div> class="level2"><div
</li> class="li"> If you want to watch a variable&#039;s value: Right-click on a variable and select New Watch from the context menu.</div></li><li
<li><div> You can use tests such as <code>assertTrue(), assertFalse(), assertEquals()</code>, or <code>assert()</code>.</div> class="level2"><div
<ul> class="li"> If you want to step through the execution line by line: Right-click on a line and choose Toggle Line Breakpoint; a pink box appears as a mark.</div></li></ul></li><li
<li><div> Here is an example for assertions that test an addition method: <code>assert( add(1, 1) == 2); assert( add(2,-5) == -3); …</code></div> class="level1"><div
</li> class="li"> Choose &quot;Debug &gt; Debug Main Project&quot; to start a debugger session for the whole project. Or, right-click in a file and select Debug File to debug only one file.</div></li><li
</ul> class="level1"><div
</li> class="li"> The application starts running normally. If you have set a breakpoint, the execution stops. Debugger windows open and print debugger output.</div></li><li
<li><div> “Optimally”, you should write a test case for every method (100% coverage).</div> class="level1"><div
</li> class="li"> You can do many things now to track down a bug:</div><ul><li
</ol> class="level2"><div
class="li"> Inspect the values of local variables.</div></li><li
<p> class="level2"><div
class="li"> Use the Step buttons in the top to step into, out of, and over expressions while you watch the execution.</div></li><li
<br/> class="level2"><div
class="li"> Navigate through your application&#039;s call stack. Right-click on threads to suspend or resume them.</div></li><li
Tip: Use the Navigate menu to jump from a test to its tested class, and back. class="level2"><div
</p> class="li"> Choose Debug &gt; Evaluate Expression from the menu to evaluate an expression.</div></li><li
class="level2"><div
</div> class="li"> Move the mouse pointer over a variable to inspect its value in a tooltip.</div></li><li
class="level2"><div
<h4><a>Running Tests</a></h4> class="li"> Inspect the classes loaded on the heap and the percentage and number of object instances. Right-click a class in the Loaded Classes window and choose Show in Instances view (JDK6 only).</div></li><li
<div> class="level2"><div
<ol> class="li"> And more…</div></li></ul></li><li
<li><div> Right-click the class in the Projects window and Choose Test File, or right-click the project and select Test to run all tests.</div> class="level1"><div
</li> class="li"> To stop debugging, choose Debug &gt; End Debugger Session from the menu.</div></li></ol></div><h2><a
<li><div> Check the Test window to see successful test (green) and test failures (red). </div> name="profiling">Profiling</a></h2><div
</li> class="level2"><p> The profiler tool is used to monitor thread states, CPU performance, and memory usage of your jme3 application. It helps you detect memory leaks and bottlenecks in your game while it&#039;s running. <br/></p></div><h4><a
<li><div> If a test fails that has succeeded before, you know that your latest changes broke something!</div> name="installing_the_profiler">Installing the Profiler</a></h4><div
</li> class="level4"><p> If you do not see a Profiler menu in the jMonkeyPlatform, you need to download the Profiler plugin first.</p><ol><li
</ol> class="level1"><div
class="li"> Open the Tools &gt; Plugins menu, and got to the &quot;Available plugins&quot; tab</div></li><li
<p> class="level1"><div
class="li"> Find the &quot;Java Profiler&quot; plugin (&quot;Java SE&quot; category) and check the Install box.</div></li><li
Using unit tests regularly allows you to detect side-effects on classes that you thought were unaffected by a code change. class="level1"><div
</p> class="li"> Click the install button and follow the instructions.</div></li><li
class="level1"><div
<p> class="li"> When you start the profiler for the first time, you are prompted to run a calibration once. Click OK in the &quot;Profiler integration&quot; dialog to complete the installation process.</div></li></ol></div><h4><a
<br/> name="monitoring_and_analyzing">Monitoring and Analyzing</a></h4><div
class="level4"><ol><li
See also: class="level1"><div
</p> class="li"> Choose Profile Project from the Profile menu.</div></li><li
<ul> class="level1"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/kb/docs/java/junit-intro.html"><param name="text" value="<html><u>Writing JUnit Tests</u></html>"><param name="textColor" value="blue"></object></div> class="li"> Select one of three tasks:</div><ul><li
</li> class="level2"><div
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.junit.org"><param name="text" value="<html><u>http://www.junit.org</u></html>"><param name="textColor" value="blue"></object></div> class="li"> <strong>Monitor Application</strong> – Collect high-level information about properties of the target JVM, including thread activity and memory allocations.</div></li><li
</li> class="level2"><div
</ul> class="li"> <strong>Analyze CPU Performance</strong> – Collect detailed data on application performance, including the time to execute methods and the number of times the method is invoked.</div></li><li
class="level2"><div
</div> class="li"> <strong>Analyze Memory Usage</strong> – Collect detailed data on object allocation and garbage collection.</div></li></ul></li><li
class="level1"><div
<h2><a>Debugging</a></h2> class="li"> Click Run. Your application starts and runs normally.</div></li><li
<div> class="level1"><div
class="li"> Use the Profiling window to track and collect live profiling results while you application is running.</div></li></ol></div><h4><a
<p> name="comparing_snapshots">Comparing Snapshots</a></h4><div
class="level4"><p> Click the Take Snapshot button to capture the profiling data for later!</p><ul><li
In the jMonkeyPlatform, you have access to a debugger to examine your application for errors such as deadlocks and NullPointerExeptions. You can set breakpoints, watch variables, and execute your code line-by-line to identify the source of a problem. class="level1"><div
class="li"> You can store and view snapshots in the Profiling window.</div></li><li
</p> class="level1"><div
<ol> class="li"> Choose Compare Snapshots from the profiler window to compare two selected snapshots</div></li></ul></div><h4><a
<li><div> First, you set breakpoints and/or watches before the problematic lines of code where you suspect the bug.</div> name="using_profiling_points">Using Profiling Points</a></h4><div
<ul> class="level4"><p> Profiling points are similar to debugger breakpoints: You place them directly in the source code and they can trigger profiling behaviour when hit.</p><ul><li
<li><div> If you want to watch a variable&#039;s value: Right-click on a variable and select New Watch from the context menu.</div> class="level1"><div
</li> class="li"> Open a class in the browser, right-click in a line, and select Profiling &gt; Insert Profiling Point to add a profiling point here.</div></li><li
<li><div> If you want to step through the execution line by line: Right-click on a line and choose Toggle Line Breakpoint; a pink box appears as a mark.</div> class="level1"><div
</li> class="li"> Use Profiling points if you need a trigger to reset profiling results, take a snapshot or heap dump, record the timestamp or execution time of a code fragment, stop and start a load generator script (requires the load generator plugin).</div></li><li
</ul> class="level1"><div
</li> class="li"> Open the Profiling Points window to view, modify and delete the Profiling Points in your projects.</div></li></ul><p> <br/> See also:</p><ul><li
<li><div> Choose “Debug &gt; Debug Main Project” to start a debugger session for the whole project. Or, right-click in a file and select Debug File to debug only one file. </div> class="level1"><div
</li> class="li"> <a
<li><div> The application starts running normally. If you have set a breakpoint, the execution stops. Debugger windows open and print debugger output. </div> href="http://netbeans.org/kb/docs/java/profiler-profilingpoints.html">Using Profiling Points</a></div></li><li
</li> class="level1"><div
<li><div> You can do many things now to track down a bug:</div> class="li"> <a
<ul> href="http://netbeans.org/kb/docs/java/profiler-intro.html">Introduction to Profiling Java Applications</a></div></li></ul></div>
<li><div> Inspect the values of local variables.</div>
</li>
<li><div> Use the Step buttons in the top to step into, out of, and over expressions while you watch the execution.</div>
</li>
<li><div> Navigate through your application&#039;s call stack. Right-click on threads to suspend or resume them.</div>
</li>
<li><div> Choose Debug &gt; Evaluate Expression from the menu to evaluate an expression. </div>
</li>
<li><div> Move the mouse pointer over a variable to inspect its value in a tooltip.</div>
</li>
<li><div> Inspect the classes loaded on the heap and the percentage and number of object instances. Right-click a class in the Loaded Classes window and choose Show in Instances view (JDK6 only). </div>
</li>
<li><div> And more…</div>
</li>
</ul>
</li>
<li><div> To stop debugging, choose Debug &gt; End Debugger Session from the menu.</div>
</li>
</ol>
</div>
<h2><a>Profiling</a></h2>
<div>
<p>
The profiler tool is used to monitor thread states, CPU performance, and memory usage of your jme3 application. It helps you detect memory leaks and bottlenecks in your game while it&#039;s running.
<br/>
</p>
</div>
<h4><a>Installing the Profiler</a></h4>
<div>
<p>
If you do not see a Profiler menu in the jMonkeyPlatform, you need to download the Profiler plugin first.
</p>
<ol>
<li><div> Open the Tools &gt; Plugins menu, and got to the “Available plugins” tab </div>
</li>
<li><div> Find the “Java Profiler” plugin (“Java SE” category) and check the Install box.</div>
</li>
<li><div> Click the install button and follow the instructions.</div>
</li>
<li><div> When you start the profiler for the first time, you are prompted to run a calibration once. Click OK in the “Profiler integration” dialog to complete the installation process.</div>
</li>
</ol>
</div>
<h4><a>Monitoring and Analyzing</a></h4>
<div>
<ol>
<li><div> Choose Profile Project from the Profile menu. </div>
</li>
<li><div> Select one of three tasks:</div>
<ul>
<li><div> <strong>Monitor Application</strong> – Collect high-level information about properties of the target JVM, including thread activity and memory allocations.</div>
</li>
<li><div> <strong>Analyze CPU Performance</strong> – Collect detailed data on application performance, including the time to execute methods and the number of times the method is invoked.</div>
</li>
<li><div> <strong>Analyze Memory Usage</strong> – Collect detailed data on object allocation and garbage collection.</div>
</li>
</ul>
</li>
<li><div> Click Run. Your application starts and runs normally. </div>
</li>
<li><div> Use the Profiling window to track and collect live profiling results while you application is running.</div>
</li>
</ol>
</div>
<h4><a>Comparing Snapshots</a></h4>
<div>
<p>
Click the Take Snapshot button to capture the profiling data for later!
</p>
<ul>
<li><div> You can store and view snapshots in the Profiling window. </div>
</li>
<li><div> Choose Compare Snapshots from the profiler window to compare two selected snapshots</div>
</li>
</ul>
</div>
<h4><a>Using Profiling Points</a></h4>
<div>
<p>
Profiling points are similar to debugger breakpoints: You place them directly in the source code and they can trigger profiling behaviour when hit.
</p>
<ul>
<li><div> Open a class in the browser, right-click in a line, and select Profiling &gt; Insert Profiling Point to add a profiling point here.</div>
</li>
<li><div> Use Profiling points if you need a trigger to reset profiling results, take a snapshot or heap dump, record the timestamp or execution time of a code fragment, stop and start a load generator script (requires the load generator plugin).</div>
</li>
<li><div> Open the Profiling Points window to view, modify and delete the Profiling Points in your projects. </div>
</li>
</ul>
<p>
<br/>
See also:
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/kb/docs/java/profiler-profilingpoints.html"><param name="text" value="<html><u>Using Profiling Points</u></html>"><param name="textColor" value="blue"></object></div>
</li>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/kb/docs/java/profiler-intro.html"><param name="text" value="<html><u>Introduction to Profiling Java Applications</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:debugging_profiling_testing?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:debugging_profiling_testing?do=export_xhtmlbody">view online version</a></em></p>

@ -1,93 +1,36 @@
<h1><a
<h1><a>Default Build Script</a></h1> name="default_build_script">Default Build Script</a></h1><div
<div> class="level1"><p> If you use jME3 together with the jMonkeyPlatform (recommended) then you benefit from the provided build script. Every new project comes with a default Ant script. The toolbar buttons and clean/build/run actions in the jMonkeyPlatform are already pre-configured.</p></div><h2><a
name="default_targets">Default Targets</a></h2><div
<p> class="level2"><p> The build script includes targets for the following tasks:</p><ul><li
class="level1"><div
If you use jME3 together with the jMonkeyPlatform (recommended) then you benefit from the provided build script. Every new project comes with a default Ant script. The toolbar buttons and clean/build/run actions in the jMonkeyPlatform are already pre-configured. class="li"> clean – deletes the built classes and executables in the dist directory.</div></li><li
</p> class="level1"><div
class="li"> jar – compiles the classes, builds the executable JAR in the dist directory, copies libraries.</div></li><li
</div> class="level1"><div
class="li"> run – runs the executable JAR.</div></li><li
<h2><a>Default Targets</a></h2> class="level1"><div
<div> class="li"> javadoc – compiles javadoc from your java files into html files.</div></li><li
class="level1"><div
<p> class="li"> debug – used by the jMonkeyPlatform Debugger plugin.</div></li><li
class="level1"><div
The build script includes targets for the following tasks: class="li"> test – Used by the jMonkeyPlatform JUnit Test plugin.</div></li></ul><p> Usage on the command line:</p><pre>ant clean
</p>
<ul>
<li><div> clean – deletes the built classes and executables in the dist directory.</div>
</li>
<li><div> jar – compiles the classes, builds the executable JAR in the dist directory, copies libraries.</div>
</li>
<li><div> run – runs the executable JAR.</div>
</li>
<li><div> javadoc – compiles javadoc from your java files into html files.</div>
</li>
<li><div> debug – used by the jMonkeyPlatform Debugger plugin.</div>
</li>
<li><div> test – Used by the jMonkeyPlatform JUnit Test plugin.</div>
</li>
</ul>
<p>
Usage on the command line:
</p>
<pre>ant clean
ant jar ant jar
ant run</pre> ant run</pre><p> Recommended Usage: Use the menu items or toolbar buttons in the jMonkeyPlatform to trigger clean, build, and run actions.</p></div><h2><a
name="browsing_the_build_script">Browsing the Build Script</a></h2><div
<p> class="level2"><p> To see the build script and the predefined tasks</p><ol><li
Recommended Usage: Use the menu items or toolbar buttons in the jMonkeyPlatform to trigger clean, build, and run actions. class="level1"><div
</p> class="li"> Open your project in the jMonkeyPlatform if it isn&#039;t already open (File &gt; Open Project…)</div></li><li
class="level1"><div
</div> class="li"> Open the Files window (Window &gt; Files)</div></li><li
class="level1"><div
<h2><a>Browsing the Build Script</a></h2> class="li"> Open the project node. You see <code>build.xml</code> listed.</div><ol><li
<div> class="level2"><div
class="li"> Double-click <code>build.xml</code> to see how the jme3-specify build targets were defined. You typically do not need to edit the existing ones, but you can.</div></li><li
<p> class="level2"><div
class="li"> Click the triangle next to <code>build.xml</code> to see all targets.</div><ol><li
To see the build script and the predefined tasks class="level3"><div
</p> class="li"> Double-click a target in the Files window, or the Navigator, to see how the target was defined. <br/> You will notice that the file <code>nbproject/build-impl.xml</code> opens. It contains very generic targets that you typically will never need to edit. Note that <code>build.xml</code> includes <code>build-impl.xml</code>!</div></li></ol></li></ol></li></ol></div><h2><a
<ol> name="adding_custom_targets">Adding Custom Targets</a></h2><div
<li><div> Open your project in the jMonkeyPlatform if it isn&#039;t already open (File &gt; Open Project…)</div> class="level2"><p> The build script is a non-proprietary Apache Ant script. It will work out-of-the-box, but if necessary, you can extend and customize it.</p><p> Read the comments in <code>build.xml</code>, they explain how to override targets, or extend them, to customize the build process without breaking the existing functionality.</p></div>
</li>
<li><div> Open the Files window (Window &gt; Files)</div>
</li>
<li><div> Open the project node. You see <code>build.xml</code> listed.</div>
<ol>
<li><div> Double-click <code>build.xml</code> to see how the jme3-specify build targets were defined. You typically do not need to edit the existing ones, but you can.</div>
</li>
<li><div> Click the triangle next to <code>build.xml</code> to see all targets.</div>
<ol>
<li><div> Double-click a target in the Files window, or the Navigator, to see how the target was defined. <br/>
You will notice that the file <code>nbproject/build-impl.xml</code> opens. It contains very generic targets that you typically will never need to edit. Note that <code>build.xml</code> includes <code>build-impl.xml</code>!</div>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</div>
<h2><a>Adding Custom Targets</a></h2>
<div>
<p>
The build script is a non-proprietary Apache Ant script. It will work out-of-the-box, but if necessary, you can extend and customize it.
</p>
<p>
Read the comments in <code>build.xml</code>, they explain how to override targets, or extend them, to customize the build process without breaking the existing functionality.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:default_build_script?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:default_build_script?do=export_xhtmlbody">view online version</a></em></p>

@ -1,89 +1,71 @@
<h2><a
<h2><a>Developing for jMonkeyPlatform</a></h2> name="developing_for_jmonkeyplatform">Developing for jMonkeyPlatform</a></h2><div
<div> class="level2"><p> <em>Note that all info is subject to change while jMP is still in alpha!</em> In general, developing plugins for jMonkeyPlatform is not much different than creating plugins for the NetBeans Platform which in turn is not much different than creating Swing applications. You can use jMonkeyPlatform to develop plugins, be it for personal use or to contribute to the community.
<p>
<em>Note that all info is subject to change while jMP is still in alpha!</em>
</p>
<p>
In general, developing plugins for jMonkeyPlatform is not much different than creating plugins for the NetBeans Platform which in turn is not much different than creating Swing applications. You can use jMonkeyPlatform to develop plugins, be it for personal use or to contribute to the community.
</p>
<p>
If you feel like you want to make an addition to jMonkeyPlatform dont hesitate to contact the jme team regardless of your knowledge in NetBeans platform development. For new plugins, the basic project creation and layout of the plugin can always be handled by a core developer and you can go on from there fleshing out the plugin. If you feel like you want to make an addition to jMonkeyPlatform dont hesitate to contact the jme team regardless of your knowledge in NetBeans platform development. For new plugins, the basic project creation and layout of the plugin can always be handled by a core developer and you can go on from there fleshing out the plugin.
</p> By using the Platform functions, your plugin feels more like a Platform application (global save button, file type support etc.).</p></div><h4><a
name="creating_plugins_and_components">Creating plugins and components</a></h4><div
<p> class="level4"><ul><li
By using the Platform functions, your plugin feels more like a Platform application (global save button, file type support etc.). class="level1"><div
</p> class="li"> <a
href="/com/jme3/gde/core/docs/sdk/development/setup.html">Creating a plugin</a></div></li><li
</div> class="level1"><div
class="li"> <a
<h4><a>Creating plugins and components</a></h4> href="/com/jme3/gde/core/docs/sdk/development/general.html">Creating components</a></div></li></ul></div><h4><a
<div> name="extending_jmonkeyplatform">Extending jMonkeyPlatform</a></h4><div
<ul> class="level4"><ul><li
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/setup.html">Creating a plugin</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/general.html">Creating components</a></div> href="/com/jme3/gde/core/docs/sdk/development/scene.html">The Main Scene</a></div></li><li
</li> class="level1"><div
</ul> class="li"> <a
href="/com/jme3/gde/core/docs/sdk/development/sceneexplorer.html">The Scene Explorer</a></div></li><li
</div> class="level1"><div
class="li"> <a
<h4><a>Extending jMonkeyPlatform</a></h4> href="/com/jme3/gde/core/docs/sdk/development/projects_assets.html">Projects and Assets</a></div></li></ul></div><h4><a
<div> name="recipes">Recipes</a></h4><div
<ul> class="level4"><ul><li
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/scene.html">The Main Scene</a></div> class="level1"><div
</li> class="li"> <a
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/sceneexplorer.html">The Scene Explorer</a></div> href="/com/jme3/gde/core/docs/sdk/development/extension_library.html">Create a library plugin from a jar file</a></div></li><li
</li> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/projects_assets.html">Projects and Assets</a></div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/sdk/development/model_loader.html">Create a new or custom model filetype and loader</a></div></li></ul></div><h4><a
</ul> name="general_notes">General Notes</a></h4><div
class="level4"><ul><li
</div> class="level1"><div
class="li"> <strong>Remember the scene runs on the render thread and most everything you do in the plugin (button events etc.) runs on the AWT thread, always encapsulate calls to either side correctly via Callables/Runnables or register as an AppState to the SceneApplication to have an update() call by the render thread.</strong></div></li><li
<h4><a>Recipes</a></h4> class="level1"><div
<div> class="li"> Although the scene can be accessed at any time via SceneApplication.getApplication() it is not recommended to modify the scene like that. Other plugins might be accessing the scene and updates will not be properly recognized. Use the sceneRequest object and the lookup of selected nodes and files to access things like the assetManager etc.</div></li><li
<ul> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/extension_library.html">Create a library plugin from a jar file</a></div> class="li"> It became a standard in jMP to start the name of methods that execute directly on the OpenGL thread with \&quot;do\&quot; e.g \&quot;doMoveSpatial\&quot;, this makes identifying threading issues easier.</div></li><li
</li> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/sdk/development/model_loader.html">Create a new or custom model filetype and loader</a></div> class="li"> The AssetManager of jme3 is threadsafe and can be used from any thread to load assets</div></li><li
</li> class="level1"><div
</ul> class="li"> You can get access to the ProjectAssetManager via the Lookup of a JmeSpatial and other objects</div></li><li
class="level1"><div
</div> class="li"> Use org.openide.filesystems.FileObject instead of java.io.File for file access, it always uses system-independent \&quot;/\&quot; path separators and has some more advanced functions that make file handling easier.</div></li><li
class="level1"><div
<h4><a>General Notes</a></h4> class="li"> You can get a file from a string using Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(\&quot;aaa/bbb/ccc/whatever\&quot;);</div></li><li
<div> class="level1"><div
<ul> class="li"> You can convert a regular java File to a FileObject and vice versa using org.openide.filesystems.FileUtil</div></li><li
<li><div> <em>Although the scene can be accessed at any time via SceneApplication.getApplication() it is not recommended to modify the scene like that. Other plugins might be accessing the scene and updates will not be properly recognized.</em></div> class="level1"><div
</li> class="li"> If you have problems with unresolved classes, check if all needed Libraries are registered in the settings of your Project. To find out which library contains a certain class, just enter the name in the library search field.</div></li></ul></div><h4><a
<li><div> <em>Remember the scene runs on the render thread and most everything you do in the plugin (button events etc.) runs on the AWT thread, always encapsulate calls to either side correctly via Callables/Runnables or register as an AppState to the SceneApplication to have an update() call by the render thread.</em></div> name="handy_things_in_jmonkeyplatform_core">Handy things in jMonkeyPlatform Core</a></h4><div
</li> class="level4"><ul><li
<li><div> <em>It became a standard in jMP to start the name of methods that execute directly on the OpenGL thread with “do” e.g “doMoveSpatial”, this makes identifying threading issues easier.</em></div> class="level1"><div
</li> class="li"> com.jme3.gde.core.scene.controller</div><ul><li
<li><div> <em>The AssetManager of jme3 is threadsafe and can be used from any thread to load assets</em></div> class="level2"><div
</li> class="li"> AbstractCameraController → A basic camera control for plugins, used by SimpleSceneComposer and \&quot;View Model\&quot;</div></li><li
<li><div> <em>You can get access to the ProjectAssetManager via the Lookup of a JmeSpatial and other objects</em></div> class="level2"><div
</li> class="li"> SceneToolController → A basic controller for having selection, cursor etc. displayed in the scene, used by SimpleSceneComposer</div></li></ul></li><li
<li><div> <em>Use org.openide.filesystems.FileObject instead of java.io.File for file access, it always uses system-independent ”/” path separators and has some more advanced functions that make file handling easier. class="level1"><div
* You can get a file from a string using Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(“aaa/bbb/ccc/whatever”);</em></div> class="li"> com.jme3.gde.core.scene</div><ul><li
</li> class="level2"><div
<li><div> You can convert a regular java File to a FileObject and vice versa using org.openide.filesystems.FileUtil</div> class="li"> OffViewPanel → A panel that renders a 3d scene in a preview and displays it in a lightweight swing panel</div></li></ul></li><li
</li> class="level1"><div
<li><div> <em>If you have problems with unresolved classes, check if all needed Libraries are registered in the settings of your Project. To find out which library contains a certain class, just enter the name in the library search field.</em></div> class="li"> com.jme3.gde.core.util</div><ul><li
</li> class="level2"><div
</ul> class="li"> DataObjectSaveNode → Allows enabling the save all button by using any file and implementing the SvaeCookie yourself.</div></li></ul></li></ul><p> Learn more about NetBeans Plugin Development at <a
href="http://platform.netbeans.org">http://platform.netbeans.org</a> .\\<br/> Also check out this Essential NetBeans Platform Refcard: <a
<p> href="http://refcardz.dzone.com/refcardz/essential-netbeans-platform">http://refcardz.dzone.com/refcardz/essential-netbeans-platform</a></p></div>
Learn more about NetBeans Plugin Development at <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://platform.netbeans.org"><param name="text" value="<html><u>http://platform.netbeans.org</u></html>"><param name="textColor" value="blue"></object> .<br/>
Also check out this Essential NetBeans Platform Refcard: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://refcardz.dzone.com/refcardz/essential-netbeans-platform"><param name="text" value="<html><u>http://refcardz.dzone.com/refcardz/essential-netbeans-platform</u></html>"><param name="textColor" value="blue"></object>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development?do=export_xhtmlbody">view online version</a></em></p>

@ -1,79 +1,46 @@
<h1><a
<h1><a>Creating an extension library plugin</a></h1> name="creating_an_extension_library_plugin">Creating an extension library plugin</a></h1><div
<div> class="level1"><p> This page describes how you can wrap any jar library into a plugin that a jMP user can download, install and then use the contained library in his own game projects.</p><p> <br/> Creating the plugin project (in jMP):</p><ul><li
class="level1"><div
<p> class="li"> Create a new Module Suite (or use an existing one)</div></li><li
This page describes how you can wrap any jar library into a plugin that a jMP user can download, install and then use the contained library in his own game projects. class="level1"><div
</p> class="li"> Open the suite, right-click the &quot;Modules&quot; folder and select &quot;Add new..&quot;</div></li><li
class="level1"><div
<p> class="li"> For &quot;Project Name&quot; enter an all-lowercase name without spaces like <code>my-library</code></div></li><li
<br/> class="level1"><div
class="li"> Make sure the &quot;Project Location&quot; is inside the module suite folder and press &quot;Next&quot;</div></li><li
Creating the plugin project (in jMP): class="level1"><div
</p> class="li"> Enter the base java package for your plugin in &quot;Code Name Base&quot; like <code>com.mycompany.plugins.mylibrary</code></div></li><li
<ul> class="level1"><div
<li><div> Create a new Module Suite (or use an existing one)</div> class="li"> Enter a &quot;Module Display Name&quot; for your plugin like &quot;My Library&quot;</div></li><li
</li> class="level1"><div
<li><div> Open the suite, right-click the “Modules” folder and select “Add new..”</div> class="li"> Check the &quot;Generate <acronym
</li> title="Extensible Markup Language">XML</acronym> Layer&quot; checkbox</div></li><li
<li><div> For “Project Name” enter an all-lowercase name without spaces like <code>my-library</code></div> class="level1"><div
</li> class="li"> Press Finish</div></li></ul><p> Adding the library:</p><ul><li
<li><div> Make sure the “Project Location” is inside the module suite folder and press “Next”</div> class="level1"><div
</li> class="li"> Right click the Module Project and select &quot;New→Other&quot;</div></li><li
<li><div> Enter the base java package for your plugin in “Code Name Base” like <code>com.mycompany.plugins.mylibrary</code></div> class="level1"><div
</li> class="li"> Under &quot;Module Development&quot; select the &quot;Java SE Library Descriptor&quot; template and press &quot;Next&quot;</div></li><li
<li><div> Enter a “Module Display Name” for your plugin like “My Library”</div> class="level1"><div
</li> class="li"> If you dont have the external library registered in jMP yet, click &quot;Manage Libraries&quot; and do the following:</div><ul><li
<li><div> Check the “Generate <acronym title="Extensible Markup Language">XML</acronym> Layer” checkbox</div> class="level2"><div
</li> class="li"> Click &quot;New Library&quot;, enter a name for the library and press OK</div></li><li
<li><div> Press Finish</div> class="level2"><div
</li> class="li"> In the &quot;Classpath&quot; tab, press &quot;Add JAR/Folder&quot; and select the jar file(s) needed for the library</div></li><li
</ul> class="level2"><div
class="li"> In the &quot;JavaDoc&quot; tab, press &quot;Add ZIP/Folder&quot; and add the javadoc for the library (zipped or folder)</div></li><li
<p> class="level2"><div
class="li"> In the &quot;Sources&quot; tab you can add a folder or jar file containing the source files of the library if available</div></li><li
Adding the library: class="level2"><div
</p> class="li"> Press OK</div></li></ul></li><li
<ul> class="level1"><div
<li><div> Right click the Module Project and select “New→Other”</div> class="li"> Select the external library from the list and press &quot;Next&quot;</div></li><li
</li> class="level1"><div
<li><div> Under “Module Development” select the “Java SE Library Descriptor” template and press “Next”</div> class="li"> Enter a name for the Library (used as filename for the description file)</div></li><li
</li> class="level1"><div
<li><div> If you dont have the external library registered in jMP yet, click “Manage Libraries” and do the following:</div> class="li"> Enter a display name for the Library (This is the name the user later sees in his library list)</div></li><li
<ul> class="level1"><div
<li><div> Click “New Library”, enter a name for the library and press OK</div> class="li"> Press OK</div></li></ul><p> You will notice a new file &quot;MyLibrary.xml&quot; is created in the plugins base package and linked to in the layer.xml file. This is basically it, you can configure a version number, license file (should be placed in Module root folder) and more via the Module Properties.</p><p> <br/> After you are done, you can <a
</li> href="/com/jme3/gde/core/docs/sdk/development/setup#jmp_contributions_update_center.html">contribute the plugin in the jMP contribution update center</a>.</p></div>
<li><div> In the “Classpath” tab, press “Add JAR/Folder” and select the jar file(s) needed for the library</div>
</li>
<li><div> In the “JavaDoc” tab, press “Add ZIP/Folder” and add the javadoc for the library (zipped or folder)</div>
</li>
<li><div> In the “Sources” tab you can add a folder or jar file containing the source files of the library if available</div>
</li>
<li><div> Press OK</div>
</li>
</ul>
</li>
<li><div> Select the external library from the list and press “Next”</div>
</li>
<li><div> Enter a name for the Library (used as filename for the description file)</div>
</li>
<li><div> Enter a display name for the Library (This is the name the user later sees in his library list)</div>
</li>
<li><div> Press OK</div>
</li>
</ul>
<p>
You will notice a new file “MyLibrary.xml” is created in the plugins base package and linked to in the layer.xml file. This is basically it, you can configure a version number, license file (should be placed in Module root folder) and more via the Module Properties.
</p>
<p>
<br/>
After you are done, you can <a href="/com/jme3/gde/core/docs/sdk/development/setup#jmp_contributions_update_center.html">contribute the plugin in the jMP contribution update center</a>.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:extension_library?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:extension_library?do=export_xhtmlbody">view online version</a></em></p>

@ -1,22 +1,8 @@
<h1><a
<h1><a>Creating plugin components</a></h1> name="creating_plugin_components">Creating plugin components</a></h1><div
<div> class="level1"><p> For the most common extensions like Windows, File Types, Libraries etc. there exist templates that you can add to your plugin.</p><ol><li
class="level1"><div
<p> class="li"> Right-click your Module Project and select New→Other</div></li><li
For the most common extensions like Windows, File Types, Libraries etc. there exist templates that you can add to your plugin. class="level1"><div
class="li"> Select &quot;Module Development&quot; to the left</div></li></ol><p> You will see a list of components you can add to your project. A wizard will guide you through the creation of the component.</p></div>
</p>
<ol>
<li><div> Right-click your Module Project and select New→Other</div>
</li>
<li><div> Select “Module Development” to the left</div>
</li>
</ol>
<p>
You will see a list of components you can add to your project. A wizard will guide you through the creation of the component.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:general?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:general?do=export_xhtmlbody">view online version</a></em></p>

@ -1,41 +1,22 @@
<h1><a
<h1><a>Creating a model importer</a></h1> name="creating_a_model_importer">Creating a model importer</a></h1><div
<div> class="level1"><ol><li
class="level1"><div
<p> class="li"> Create plugin</div></li><li
class="level1"><div
TODO class="li"> Add importer jar file (wrap jar file)</div></li><li
class="level1"><div
</p> class="li"> Add filetype (Template)</div></li><li
<ol> class="level1"><div
<li><div> Create plugin</div> class="li"> Change DataObject to extend SpatialAssetDataObject</div></li><li
</li> class="level1"><div
<li><div> Add importer jar file (wrap jar file)</div> class="li"> Implement loadAsset method in DataObject (if necessary, most model formats should load normally via the loader)</div></li><li
</li> class="level1"><div
<li><div> Add filetype (Template)</div> class="li"> Create AssetManagerConfigurator \</div></li></ol><p> See also:</p><ul><li
</li> class="level1"><div
<li><div> Change DataObject to extend SpatialAssetDataObject</div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/sdk/development/projects_assets.html">Projects and Assets</a></div></li><li
<li><div> Implement loadAsset method in DataObject (if necessary)</div> class="level1"><div
</li> class="li"> <a
<li><div> Create AssetManagerConfiguratorSee also:</div> href="http://platform.netbeans.org/tutorials/nbm-filetype.html">http://platform.netbeans.org/tutorials/nbm-filetype.html</a></div></li></ul></div>
</li>
</ol>
<p>
<object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://platform.netbeans.org/tutorials/nbm-filetype.html"><param name="text" value="<html><u>http://platform.netbeans.org/tutorials/nbm-filetype.html</u></html>"><param name="textColor" value="blue"></object>
</p>
<div>
<fieldset>
<legend><img src="/wiki/lib/plugins/task/images/ics.gif"> Task</legend>
<table>
<tr>
<th>Assigned to:</th><td><span>normen</span></td>
</tr>
</table>
</fieldset>
</div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:model_loader?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:model_loader?do=export_xhtmlbody">view online version</a></em></p>

@ -1,44 +1,29 @@
<h1><a
<h1><a>Projects and Assets</a></h1> name="projects_and_assets">Projects and Assets</a></h1><div
<div> class="level1"><p> The <acronym
title="Software Development Kit">SDK</acronym> heavily uses the systems provided by the base platform for the handling of assets and projects and extends the system with jME3 specific features.</p></div><h2><a
<p> name="projectassetmanager">ProjectAssetManager</a></h2><div
The <acronym title="Software Development Kit">SDK</acronym> heavily uses the systems provided by the base platform for the handling of assets and projects and extends the system with jME3 specific features. class="level2"><p> All AssetDataObjects and SceneExplorerNodes allow access to the ProjectAssetManager of the project they were loaded from.</p><pre>ProjectAssetManager pm = node.getLookup&#40;&#41;.lookup&#40;ProjectAssetManager.class&#41;</pre><p> The ProjectAssetManager is basically a normal DesktopAssetManager for each project with some added functionality:</p><ul><li
</p> class="level1"><div
class="li"> Access to the FileObject of the assets folder of the project to load and save data</div></li><li
</div> class="level1"><div
class="li"> Convert absolute file paths to relative asset paths and vice versa</div></li><li
<h2><a>AssetDataObject</a></h2> class="level1"><div
<div> class="li"> Get lists of all textures, materials etc. in the project</div></li><li
class="level1"><div
<p> class="li"> more convenient stuff.. :)</div></li></ul></div><h2><a
Most “files” that you encounter in the <acronym title="Software Development Kit">SDK</acronym> come in the form of AssetDataObjects. All Nodes that you encounter contain the AssetDataObject they were loaded from. It provides not just access to the FileObject of the specific file but also an AssetData object that allows access to jME specific properties and data. The AssetData object also allows loading the object via the jME3 assetManager. It is accessible via the lookup of the Node or AssetDataObject: name="assetdataobject">AssetDataObject</a></h2><div
class="level2"><p> Most &quot;files&quot; that you encounter in the <acronym
</p> title="Software Development Kit">SDK</acronym> come in the form of AssetDataObjects. All Nodes that you encounter contain the AssetDataObject they were loaded from. It provides not just access to the FileObject of the specific file but also an AssetData object that allows access to jME specific properties and data. The AssetData object also allows loading the object via the jME3 assetManager. It is accessible via the lookup of the Node or AssetDataObject:</p><pre>assetDataObject.getLookup&#40;&#41;.lookup&#40;AssetData.class&#41;</pre></div><h2><a
<pre>assetDataObject.getLookup&#40;&#41;.lookup&#40;AssetData.class&#41;</pre> name="new_asset_file_types">New Asset File Types</a></h2><div
</div> class="level2"><p> When you add a new file type for a model format or other asset file that can be loaded in jME3 you can start by using new file type template (New File→Module Development→File Type). Change the DataObject to extend AssetDataObject (general), SpatialAssetDataObject (some type of model) or BinaryModelDataObject (basically a j3o savable file). And possibly override the loadAsset and saveAsset methods which are used by the AssetData object.</p><pre>public class BlenderDataObject extends SpatialAssetDataObject &#123;
public BlenderDataObject&#40;FileObject pf, MultiFileLoader loader&#41; throws DataObjectExistsException, IOException &#123;
<h2><a>ProjectAssetManager</a></h2> super&#40;pf, loader&#41;;
<div> &#125;
&#125;</pre><p> An AssetManagerConfigurator class can be created to configure the assetManager of the projects and model importer to use the new asset type:</p><pre>@org.openide.util.lookup.ServiceProvider&#40;service = AssetManagerConfigurator.class&#41;
<p> public class BlenderAssetManagerConfigurator implements AssetManagerConfigurator &#123;
All AssetDataObjects and SceneExplorerNodes allow access to the ProjectAssetManager of the project they were loaded from. public void prepareManager&#40;AssetManager manager&#41; &#123;
manager.registerLoader&#40;com.jme3.scene.plugins.blender.BlenderModelLoader.class, &quot;blend&quot;&#41;;
</p> &#125;
<pre>ProjectAssetManager pm = node.getLookup&#40;&#41;.lookup&#40;ProjectAssetManager.class&#41;</pre> &#125;</pre></div>
<p>
The ProjectAssetManager is basically a normal DesktopAssetManager for each project with some added functionality:
</p>
<ul>
<li><div> Access to the FileObject of the assets folder of the project to load and save data</div>
</li>
<li><div> Convert absolute file paths to relative asset paths and vice versa</div>
</li>
<li><div> Get lists of all textures, materials etc. in the project</div>
</li>
<li><div> more convenient stuff.. :)</div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:projects_assets?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:projects_assets?do=export_xhtmlbody">view online version</a></em></p>

@ -1,50 +1,14 @@
<h1><a
<h1><a>The Scene</a></h1> name="the_scene">The Scene</a></h1><div
<div> class="level1"><p> To reduce system overhead the jMonkeyPlatform Core supplies one scene/jme3 application that is shared between plugins. Furthermore there&#039;s the &quot;SceneExplorer&quot; that shows a visual representation of the scenegraph and its objects properties across plugins.</p><p> <br/> Note: All info due to change until jMP is stable!</p></div><h2><a
name="how_to_access_the_scene">How to access the Scene</a></h2><div
<p> class="level2"><p> There are several ways for your plugin to interact with the Scene:</p><ul><li
class="level1"><div
To reduce system overhead the jMonkeyPlatform Core supplies one scene/jme3 application that is shared between plugins. Furthermore there&#039;s the “SceneExplorer” that shows a visual representation of the scenegraph and its objects properties across plugins. class="li"> It listens for selected spatials / objects and offers options for those</div></li><li
</p> class="level1"><div
class="li"> It requests the whole scene for itself and loads/arranges the content in it (e.g. a terrain editor or model animation plugin).</div></li></ul></div><h2><a
<p> name="listening_for_node_selection">Listening for Node selection</a></h2><div
<br/> class="level2"><p> In jMP, all objects are wrapped into NetBeans &quot;Nodes&quot; (different thing than jme Nodes!). Such nodes can have properties and icons and can be displayed and selected in the jMP UI. The SceneExplorer shows a tree of Nodes that wrap the Spatials of the current scene and allows manipulating their properties on selection. A jME &quot;Spatial&quot; is wrapped by a &quot;JmeSpatial&quot; node, for example. One advantage of these Nodes is that one can manipulate properties of Spatials directly from the AWT thread.</p><p> <br/> To listen to the current selection, implement org.openide.util.LookupListener and register like this:</p><pre>private final Result&lt;JmeSpatial&gt; result;
Note: All info due to change until jMP is stable!
</p>
</div>
<h2><a>How to access the Scene</a></h2>
<div>
<p>
There are several ways for your plugin to interact with the Scene:
</p>
<ul>
<li><div> It listens for selected spatials / objects and offers options for those</div>
</li>
<li><div> It requests the whole scene for itself and loads/arranges the content in it (e.g. a terrain editor or model animation plugin).</div>
</li>
</ul>
</div>
<h2><a>Listening for Node selection</a></h2>
<div>
<p>
In jMP, all objects are wrapped into NetBeans “Nodes” (different thing than jme Nodes!). Such nodes can have properties and icons and can be displayed and selected in the jMP UI. The SceneExplorer shows a tree of Nodes that wrap the Spatials of the current scene and allows manipulating their properties on selection. A jME “Spatial” is wrapped by a “JmeSpatial” node, for example. One advantage of these Nodes is that one can manipulate properties of Spatials directly from the AWT thread.
</p>
<p>
<br/>
To listen to the current selection, implement org.openide.util.LookupListener and register like this:
</p>
<pre>private final Result&lt;JmeSpatial&gt; result;
&nbsp; &nbsp;
//method to register the listener; //method to register the listener;
private void registerListener&#40;&#41;&#123; private void registerListener&#40;&#41;&#123;
@ -60,11 +24,7 @@ public void resultChanged&#40;LookupEvent ev&#41; &#123;
spatial.getPropertySets&#40;&#41;&#91;0&#93;.setValue&#40;&quot;Local Translation&quot;, Vector3f.ZERO&#41;; spatial.getPropertySets&#40;&#41;&#91;0&#93;.setValue&#40;&quot;Local Translation&quot;, Vector3f.ZERO&#41;;
return; return;
&#125; &#125;
&#125;</pre> &#125;</pre><p> You can also access the &quot;real&quot; spatial but since its part of the scenegraph you will have to modify it on that thread:</p><pre>//retrieve the &quot;real&quot; spatial class from the JmeNode
<p>
You can also access the “real” spatial but since its part of the scenegraph you will have to modify it on that thread:
</p>
<pre>//retrieve the &quot;real&quot; spatial class from the JmeNode
for &#40;JmeSpatial jmeSpatial : items&#41; &#123; for &#40;JmeSpatial jmeSpatial : items&#41; &#123;
//the spatial is stored inside the JmeSpatials &quot;Lookup&quot;, a general container for Objects //the spatial is stored inside the JmeSpatials &quot;Lookup&quot;, a general container for Objects
final Spatial realSpatial = jmeSpatial.getLookup&#40;&#41;.lookup&#40;Spatial.class&#41;; final Spatial realSpatial = jmeSpatial.getLookup&#40;&#41;.lookup&#40;Spatial.class&#41;;
@ -76,23 +36,9 @@ for &#40;JmeSpatial jmeSpatial : items&#41; &#123;
&#125; &#125;
&#125;&#41;; &#125;&#41;;
return; return;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="requesting_the_scene">Requesting the Scene</a></h2><div
class="level2"><p> If your plugin wants to use the scene by itself, it first has to implement SceneListener and register at the scene and then send a SceneRequest to the SceneApplication. When the SceneRequest has been approved and the current Scene has been closed, the SceneListener (your class) is called with its own SceneRequest as a parameter. When another plugin sends a SceneRequest it is also reported to you and its a hint that your RootNode has been removed from the Scene and you are no longer in control of it. You could also hook into the SceneRequests of other plugins to see if/when they are activated to display add-on plugins for that plugin.</p><p> <br/> The SceneRequest object has to contain several things. A thing that you must supply is a jme &quot;Node&quot; wrapped into a &quot;JmeNode&quot; object. This is your rootNode that you use to display and build your scene. As soon as you control the scene, you will have to control the camera etc. yourself.</p><pre>com.jme3.scene.Node rootNode = new com.jme3.scene.Node&#40;&quot;MyRootNode&quot;&#41;;
<h2><a>Requesting the Scene</a></h2>
<div>
<p>
If your plugin wants to use the scene by itself, it first has to implement SceneListener and register at the scene and then send a SceneRequest to the SceneApplication. When the SceneRequest has been approved and the current Scene has been closed, the SceneListener (your class) is called with its own SceneRequest as a parameter. When another plugin sends a SceneRequest it is also reported to you and its a hint that your RootNode has been removed from the Scene and you are no longer in control of it. You could also hook into the SceneRequests of other plugins to see if/when they are activated to display add-on plugins for that plugin.
</p>
<p>
<br/>
The SceneRequest object has to contain several things. A thing that you must supply is a jme “Node” wrapped into a “JmeNode” object. This is your rootNode that you use to display and build your scene. As soon as you control the scene, you will have to control the camera etc. yourself.
</p>
<pre>com.jme3.scene.Node rootNode = new com.jme3.scene.Node&#40;&quot;MyRootNode&quot;&#41;;
&nbsp; &nbsp;
private void registerSceneListener&#40;&#41;&#123; private void registerSceneListener&#40;&#41;&#123;
SceneApplication.getApplication&#40;&#41;.addSceneListener&#40;this&#41;; SceneApplication.getApplication&#40;&#41;.addSceneListener&#40;this&#41;;
@ -123,25 +69,12 @@ public boolean sceneClose&#40;SceneRequest request&#41; &#123;
&#125; &#125;
&#125; &#125;
return true; return true;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="undo_redo_support">Undo/Redo support</a></h2><div
class="level2"><p> jMP has a global undo/redo queue that activates the undo/redo buttons. To use it in your TopComponent, add the following method:</p><pre>@Override
<h2><a>Undo/Redo support</a></h2>
<div>
<p>
jMP has a global undo/redo queue that activates the undo/redo buttons. To use it in your TopComponent, add the following method:
</p>
<pre>@Override
public UndoRedo getUndoRedo&#40;&#41; &#123; public UndoRedo getUndoRedo&#40;&#41; &#123;
return Lookup.getDefault&#40;&#41;.lookup&#40;SceneUndoRedoManager.class&#41;; return Lookup.getDefault&#40;&#41;.lookup&#40;SceneUndoRedoManager.class&#41;;
&#125;</pre> &#125; </pre><p> To add a undo/redo event that modifies objects on the Scenegraph, theres a special version of AbstractUndoableEdit which executes the undo/redo calls on the scene thread. Simply implement that class and add it to the queue like this:</p><pre>Lookup.getDefault&#40;&#41;.lookup&#40;SceneUndoRedoManager.class&#41;.addEdit&#40;this, new AbstractUndoableSceneEdit&#40;&#41; &#123;
<p>
To add a undo/redo event that modifies objects on the Scenegraph, theres a special version of AbstractUndoableEdit which executes the undo/redo calls on the scene thread. Simply implement that class and add it to the queue like this:
</p>
<pre>Lookup.getDefault&#40;&#41;.lookup&#40;SceneUndoRedoManager.class&#41;.addEdit&#40;this, new AbstractUndoableSceneEdit&#40;&#41; &#123;
&nbsp; &nbsp;
@Override @Override
public void sceneUndo&#40;&#41; &#123; public void sceneUndo&#40;&#41; &#123;
@ -162,37 +95,5 @@ public void awtUndo&#40;&#41; &#123;
public void awtRedo&#40;&#41; &#123; public void awtRedo&#40;&#41; &#123;
//redo stuff on awt thread here //redo stuff on awt thread here
&#125; &#125;
&#125;&#41;;</pre> &#125;&#41;;</pre><p> Note: Its important that you use the method addEdit(Object source, UndoableEdit edit);</p></div>
<p>
Note: Its important that you use the method addEdit(Object source, UndoableEdit edit);
</p>
</div>
<h2><a>Handy things in jMonkeyPlatform Core</a></h2>
<div>
<ul>
<li><div> com.jme3.gde.core.scene.controller</div>
<ul>
<li><div> AbstractCameraController → A basic camera control for plugins, used by SimpleSceneComposer and “View Model”</div>
</li>
<li><div> SceneToolController → A basic controller for having selection, cursor etc. displayed in the scene, used by SimpleSceneComposer</div>
</li>
</ul>
</li>
<li><div> com.jme3.gde.core.scene</div>
<ul>
<li><div> OffViewPanel → A panel that renders a 3d scene in a preview and displays it in a lightweight swing panel</div>
</li>
</ul>
</li>
<li><div> com.jme3.gde.core.util</div>
<ul>
<li><div> DataObjectSaveNode → Allows enabling the save all button by using any file and implementing the SvaeCookie yourself.</div>
</li>
</ul>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:scene?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:scene?do=export_xhtmlbody">view online version</a></em></p>

@ -1,44 +1,14 @@
<h1><a
<h1><a>The SceneExplorer</a></h1> name="the_sceneexplorer">The SceneExplorer</a></h1><div
<div> class="level1"></div><h2><a
name="adding_node_types_to_sceneexplorer">Adding Node types to SceneExplorer</a></h2><div
</div> class="level2"><p> If your plugin brings in its own SceneGraph objects you can still have them work like any other SceneExplorer item, including its special properties.</p><p> You will have to create your own class that extends org.openide.nodes.Node and implement the interface com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode. Then you register that class by adding</p><pre>@org.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)</pre><p> above the body of your class. Thats all, your Spatial type will automatically be used and displayed in the SceneExplorer. Make sure you register a jar with the used classes in the plugin preferences under &quot;wrapped libraries&quot;, otherwise the IDE cannot access those classes.</p><p> Theres also AbstractSceneExplorerNode which brings some other useful features you might want to include like automatic creation of properly threaded properties etc. JmeSpatial for example bases on it. A simple SceneExplorerNode example for an object extending Spatial would be JmeGeometry (see below). Editors for special variable types can be added using the SceneExplorerPropertyEditor interface, which can be registered as a ServiceProvider as well.</p><p> The SceneExplorerNode can be used for Spatial and Control type objects.</p><ul><li
class="level1"><div
<h2><a>Adding Node types to SceneExplorer</a></h2> class="li"><em>Add the &quot;Nodes <acronym
<div> title="Application Programming Interface">API</acronym>&quot; and &quot;Lookup <acronym
title="Application Programming Interface">API</acronym>&quot; libraries to your project when you want to use this</em></div></li></ul></div><h3><a
<p> name="spatial_example">Spatial Example</a></h3><div
class="level3"><pre>@org.openide.util.lookup.ServiceProvider&#40;service=SceneExplorerNode.class&#41;
If your plugin brings in its own SceneGraph objects you can still have them work like any other SceneExplorer item, including its special properties.
</p>
<p>
You will have to create your own class that extends org.openide.nodes.Node and implement the interface com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode. Then you register that class by adding
</p>
<pre>@org.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)</pre>
<p>
above the body of your class. Thats all, your Spatial type will automatically be used and displayed in the SceneExplorer. Make sure you register a jar with the used classes in the plugin preferences under “wrapped libraries”, otherwise the IDE cannot access those classes.
</p>
<p>
Theres also AbstractSceneExplorerNode which brings some other useful features you might want to include like automatic creation of properly threaded properties etc. JmeSpatial for example bases on it. A simple SceneExplorerNode example for an object extending Spatial would be JmeGeometry (see below). Editors for special variable types can be added using the SceneExplorerPropertyEditor interface, which can be registered as a ServiceProvider as well.
</p>
<p>
The SceneExplorerNode can be used for Spatial and Control type objects.
</p>
<ul>
<li><div><em>Add the “Nodes <acronym title="Application Programming Interface">API</acronym>” and “Lookup <acronym title="Application Programming Interface">API</acronym>” libraries to your project when you want to use this</em></div>
</li>
</ul>
</div>
<h3><a>Spatial Example</a></h3>
<div>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service=SceneExplorerNode.class&#41;
public class JmeGeometry extends JmeSpatial &#123; public class JmeGeometry extends JmeSpatial &#123;
&nbsp; &nbsp;
private static Image smallImage = private static Image smallImage =
@ -98,12 +68,9 @@ public class JmeGeometry extends JmeSpatial &#123;
children.setReadOnly&#40;readOnly&#41;; children.setReadOnly&#40;readOnly&#41;;
return new org.openide.nodes.Node&#91;&#93;&#123;new JmeGeometry&#40;&#40;Geometry&#41; key, children&#41;.setReadOnly&#40;readOnly&#41;&#125;; return new org.openide.nodes.Node&#91;&#93;&#123;new JmeGeometry&#40;&#40;Geometry&#41; key, children&#41;.setReadOnly&#40;readOnly&#41;&#125;;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h3><a
</div> name="control_example">Control Example</a></h3><div
class="level3"><pre>@org.openide.util.lookup.ServiceProvider&#40;service=SceneExplorerNode.class&#41;
<h3><a>Control Example</a></h3>
<div>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service=SceneExplorerNode.class&#41;
public class JmeGhostControl extends AbstractSceneExplorerNode &#123; public class JmeGhostControl extends AbstractSceneExplorerNode &#123;
&nbsp; &nbsp;
private static Image smallImage = private static Image smallImage =
@ -199,25 +166,10 @@ public class JmeGhostControl extends AbstractSceneExplorerNode &#123;
public org.openide.nodes.Node&#91;&#93; createNodes&#40;Object key, DataObject key2, boolean cookie&#41; &#123; public org.openide.nodes.Node&#91;&#93; createNodes&#40;Object key, DataObject key2, boolean cookie&#41; &#123;
return new org.openide.nodes.Node&#91;&#93;&#123;new JmeGhostControl&#40;&#40;GhostControl&#41; key, key2&#41;.setReadOnly&#40;cookie&#41;&#125;; return new org.openide.nodes.Node&#91;&#93;&#123;new JmeGhostControl&#40;&#40;GhostControl&#41; key, key2&#41;.setReadOnly&#40;cookie&#41;&#125;;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h2><a
</div> name="adding_items_to_the_add_and_tools_menus">Adding items to the add and tools menus</a></h2><div
class="level2"><p> For adding Spatials, Contols and for general tools theres premade abstract classes that you can use to extend the options. Undo/Redo is handled by the abstract class. AbstractNewSpatial<strong>Wizard</strong>Action allows you to show an AWT wizard before creating the Spatial. You can also just implement the base ServiceProvider class and return any kind of action (such as a wizard), in this case you have to handle the threading yourself!</p><p><p><div
<h2><a>Adding items to the add and tools menus</a></h2> class="noteimportant">Note that the classes you create are singletons which are used across multiple nodes and you should not store any data in local variables!</div></p></p><p> To add a new Tool, create a new AbstractToolAction:</p><pre>@org.openide.util.lookup.ServiceProvider&#40;service = ToolAction.class&#41;
<div>
<p>
For adding Spatials, Contols and for general tools theres premade abstract classes that you can use to extend the options. Undo/Redo is handled by the abstract class. AbstractNewSpatial<strong>Wizard</strong>Action allows you to show an AWT wizard before creating the Spatial. You can also just implement the base ServiceProvider class and return any kind of action (such as a wizard), in this case you have to handle the threading yourself!
</p>
<p>
<p><div>Note that the classes you create are singletons which are used across multiple nodes and you should not store any data in local variables!
</div></p>
</p>
<p>
To add a new Tool, use the AbstractToolAction:
</p>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service = ToolAction.class&#41;
public class GenerateTangentsTool extends AbstractToolAction &#123; public class GenerateTangentsTool extends AbstractToolAction &#123;
&nbsp; &nbsp;
public GenerateTangentsTool&#40;&#41; &#123; public GenerateTangentsTool&#40;&#41; &#123;
@ -247,11 +199,7 @@ public class GenerateTangentsTool extends AbstractToolAction &#123;
return JmeGeometry.class; return JmeGeometry.class;
&#125; &#125;
&nbsp; &nbsp;
&#125;</pre> &#125;</pre><p> For a new Spatial or Control, use AbstractNewSpatialAction</p><pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewSpatialAction.class&#41;
<p>
For a new Spatial or Control, use AbstractNewSpatialAction
</p>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewSpatialAction.class&#41;
public class NewSpecialSpatialAction extends AbstractNewSpatialAction &#123; public class NewSpecialSpatialAction extends AbstractNewSpatialAction &#123;
&nbsp; &nbsp;
public NewSpecialSpatialAction&#40;&#41; &#123; public NewSpecialSpatialAction&#40;&#41; &#123;
@ -263,13 +211,7 @@ public class NewSpecialSpatialAction extends AbstractNewSpatialAction &#123;
Spatial spatial=new Node&#40;&#41;; Spatial spatial=new Node&#40;&#41;;
return spatial; return spatial;
&#125; &#125;
&#125;</pre> &#125;</pre><p> or AbstractNewControlAction:</p><pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewControlAction.class&#41;
<p>
or AbstractNewControlAction:
</p>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewControlAction.class&#41;
public class NewRigidBodyAction extends AbstractNewControlAction &#123; public class NewRigidBodyAction extends AbstractNewControlAction &#123;
&nbsp; &nbsp;
public NewRigidBodyAction&#40;&#41; &#123; public NewRigidBodyAction&#40;&#41; &#123;
@ -290,21 +232,10 @@ public class NewRigidBodyAction extends AbstractNewControlAction &#123;
&#125; &#125;
return control; return control;
&#125; &#125;
&#125;</pre> &#125;</pre></div><h4><a
</div> name="adding_using_a_wizard">Adding using a Wizard</a></h4><div
class="level4"><p> You can create a new wizard using the wizard template in the <acronym
<h4><a>Adding using a Wizard</a></h4> title="Software Development Kit">SDK</acronym> (New File→Module Development→Wizard). The Action that the template creates can easily be changed to one for adding a Control or Spatial or for applying a Tool. Note that we extend AbstractNewSpatial<strong>Wizard</strong>Action here.</p><p> A good example is the &quot;Add SkyBox&quot; Wizard:</p><pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewSpatialAction.class&#41;
<div>
<p>
You can create a new wizard using the wizard template in the <acronym title="Software Development Kit">SDK</acronym>. The Action the wizard creates can easily be changed to a Wizard for adding a Control or Spatial or for applying a Tool. Note that we extend AbstractNewSpatial<strong>Wizard</strong>Action here.
</p>
<p>
A good example is the “Add SkyBox” Wizard:
</p>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewSpatialAction.class&#41;
public class AddSkyboxAction extends AbstractNewSpatialWizardAction &#123; public class AddSkyboxAction extends AbstractNewSpatialWizardAction &#123;
&nbsp; &nbsp;
private WizardDescriptor.Panel&#91;&#93; panels; private WizardDescriptor.Panel&#91;&#93; panels;
@ -389,12 +320,6 @@ public class AddSkyboxAction extends AbstractNewSpatialWizardAction &#123;
&#125; &#125;
return panels; return panels;
&#125; &#125;
&#125;</pre> &#125;</pre><p><p><div
<p> class="notetip">The abstract spatial and control actions implement undo/redo automatically, for the ToolActions you have to implement it yourself.</div></p></p></div>
The
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:sceneexplorer?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:sceneexplorer?do=export_xhtmlbody">view online version</a></em></p>

@ -1,118 +1,85 @@
<h1><a
<h1><a>Creating a jMP plugin</a></h1> name="creating_a_jmp_plugin">Creating a jMP plugin</a></h1><div
<div> class="level1"><p> Note that the creation of a Module Suite is only necessary if you want to upload your plugin to the contribution update center.</p></div><h3><a
name="using_jmp_for_development_preferred">Using jMP for development (preferred)</a></h3><div
<p> class="level3"><ul><li
Note that the creation of a Module Suite is only necessary if you want to upload your plugin to the contribution update center. class="level1"><div
class="li"> Install the &quot;Netbeans Plugin Development&quot;, &quot;NetBeans <acronym
</p> title="Application Programming Interface">API</acronym> Documentation&quot; and &quot;<acronym
title="Graphical User Interface">GUI</acronym> Builder&quot; plugins via Tools→Plugins</div></li><li
</div> class="level1"><div
class="li"> Create a new &quot;Module Suite&quot; project (can be any name, this will be your local &quot;collection&quot; of plugins that you create)</div></li><li
<h3><a>Using jMP for development (preferred)</a></h3> class="level1"><div
<div> class="li"> Open the suite, right-click the &quot;Modules&quot; folder and select &quot;Add new..&quot;</div></li><li
<ul> class="level1"><div
<li><div> Install the “Netbeans Plugin Development”, “NetBeans <acronym title="Application Programming Interface">API</acronym> Documentation” and “<acronym title="Graphical User Interface">GUI</acronym> Builder” plugins via Tools→Plugins</div> class="li"> For &quot;Project Name&quot; enter an all-lowercase name without spaces like <code>my-library</code></div></li><li
</li> class="level1"><div
<li><div> Create a new “Module Suite” project (can be any name, this will be your local “collection” of plugins that you create)</div> class="li"> Make sure the &quot;Project Location&quot; is inside the module suite folder and press &quot;Next&quot;</div></li><li
</li> class="level1"><div
<li><div> Open the suite, right-click the “Modules” folder and select “Add new..”</div> class="li"> Enter the base java package for your plugin in &quot;Code Name Base&quot; like <code>com.mycompany.plugins.mylibrary</code></div></li><li
</li> class="level1"><div
<li><div> For “Project Name” enter an all-lowercase name without spaces like <code>my-library</code></div> class="li"> Enter a &quot;Module Display Name&quot; for your plugin like &quot;My Library&quot;</div></li><li
</li> class="level1"><div
<li><div> Make sure the “Project Location” is inside the module suite folder and press “Next”</div> class="li"> Check the &quot;Generate <acronym
</li> title="Extensible Markup Language">XML</acronym> Layer&quot; checkbox</div></li><li
<li><div> Enter the base java package for your plugin in “Code Name Base” like <code>com.mycompany.plugins.mylibrary</code></div> class="level1"><div
</li> class="li"> Press Finish</div></li><li
<li><div> Enter a “Module Display Name” for your plugin like “My Library”</div> class="level1"><div
</li> class="li"> To use core jMP or jME3 functions, add &quot;jMonkeyPlatfom Core&quot; and &quot;jMonkeyPlatform Core jME3&quot; via &quot;Module Properties→Library→Add Dependency&quot;</div></li><li
<li><div> Check the “Generate <acronym title="Extensible Markup Language">XML</acronym> Layer” checkbox</div> class="level1"><div
</li> class="li"> Write your plugin</div></li></ul></div><h3><a
<li><div> Press Finish</div> name="using_netbeans_for_development">Using NetBeans for development</a></h3><div
</li> class="level3"><ul><li
<li><div> To use core jMP or jME3 functions, add “jMonkeyPlatfom Core” and “jMonkeyPlatform Core jME3” via “Module Properties→Library→Add Dependency”</div> class="level1"><div
</li> class="li"> Download the jMP source from svn, then open and compile the project</div></li><li
<li><div> Write your plugin </div> class="level1"><div
</li> class="li"> Create a new &quot;Module Suite&quot; project (can be any name, this will be your local &quot;collection&quot; of plugins that you create)</div></li><li
</ul> class="level1"><div
class="li"> In the Suites Properties, under &quot;Libraries&quot;, press &quot;Add Project&quot; and select the jMP project folder.</div></li><li
</div> class="level1"><div
class="li"> Open the suite, right-click the &quot;Modules&quot; folder and select &quot;Add new..&quot;</div></li><li
<h3><a>Using NetBeans for development</a></h3> class="level1"><div
<div> class="li"> For &quot;Project Name&quot; enter an all-lowercase name for your plugin without spaces like <code>my-library</code></div></li><li
<ul> class="level1"><div
<li><div> Download the jMP source from svn, then open and compile the project</div> class="li"> Make sure the &quot;Project Location&quot; is inside the module suite folder and press &quot;Next&quot;</div></li><li
</li> class="level1"><div
<li><div> Create a new “Module Suite” project (can be any name, this will be your local “collection” of plugins that you create)</div> class="li"> Enter the base java package for your plugin in &quot;Code Name Base&quot; like <code>com.mycompany.plugins.mylibrary</code></div></li><li
</li> class="level1"><div
<li><div> In the Suites Properties, under “Libraries”, press “Add Project” and select the jMP project folder.</div> class="li"> Enter a &quot;Module Display Name&quot; for your plugin like &quot;My Library&quot;</div></li><li
</li> class="level1"><div
<li><div> Open the suite, right-click the “Modules” folder and select “Add new..”</div> class="li"> Check the &quot;Generate <acronym
</li> title="Extensible Markup Language">XML</acronym> Layer&quot; checkbox</div></li><li
<li><div> For “Project Name” enter an all-lowercase name for your plugin without spaces like <code>my-library</code></div> class="level1"><div
</li> class="li"> Press Finish</div></li><li
<li><div> Make sure the “Project Location” is inside the module suite folder and press “Next”</div> class="level1"><div
</li> class="li"> To use core jMP or jME3 functions, add &quot;jMonkeyPlatfom Core&quot; and &quot;jMonkeyPlatform Core jME3&quot; via &quot;Module Properties→Library→Add Dependency&quot;</div></li><li
<li><div> Enter the base java package for your plugin in “Code Name Base” like <code>com.mycompany.plugins.mylibrary</code></div> class="level1"><div
</li> class="li"> Write your plugin</div></li></ul></div><h3><a
<li><div> Enter a “Module Display Name” for your plugin like “My Library”</div> name="jmp_contributions_update_center">jMP Contributions Update Center</a></h3><div
</li> class="level3"><p> If you want your plugin to appear in the &quot;jMP Contributions Update Center&quot; so users can download, install and update it easily via the plugin manager, you can host your plugin in the contributions update center svn repository. The contributions update center is based on a googlecode project for contributed plugins which will be automatically compiled, version-labeled and added to the contributions update center like the core jMP plugins.</p><p> <br/> To add your plugin to the repository, do the following:</p><ul><li
<li><div> Check the “Generate <acronym title="Extensible Markup Language">XML</acronym> Layer” checkbox</div> class="level1"><div
</li> class="li"> Make sure the plugin is part of a &quot;Module Suite&quot; and that its located in the folder of the suite (this saves you from problems with the svn and local version not being configured the same)</div></li><li
<li><div> Press Finish</div> class="level1"><div
</li> class="li"> In &quot;Module Properties→Sources&quot; set the &quot;Source Level&quot; to 1.5 if possible (jMP is compatible to Java 1.5)</div></li><li
<li><div> To use core jMP or jME3 functions, add “jMonkeyPlatfom Core” and “jMonkeyPlatform Core jME3” via “Module Properties→Library→Add Dependency”</div> class="level1"><div
</li> class="li"> In &quot;Module Properties→<acronym
<li><div> Write your plugin </div> title="Application Programming Interface">API</acronym> Versioning&quot; set a specification version for your plugin (like 0.8.1)</div></li><li
</li> class="level1"><div
</ul> class="li"> Set the &quot;implementation version&quot; to &quot;0&quot; and select &quot;append implementation versions automatically&quot;</div></li><li
class="level1"><div
</div> class="li"> Ask the managers or developers for access to the gc project</div></li><li
class="level1"><div
<h3><a>jMP Contributions Update Center</a></h3> class="li"> Commit <strong>only the module project</strong> to trunk:</div><ul><li
<div> class="level2"><div
class="li"> Right click the Plugin Project and select &quot;Versioning → Import into Subversion Repository&quot;</div></li><li
<p> class="level2"><div
If you want your plugin to appear in the “jMP Contributions Update Center” so users can download, install and update it easily via the plugin manager, you can host your plugin in the contributions update center svn repository. The contributions update center is based on a googlecode project for contributed plugins which will be automatically compiled, version-labeled and added to the contributions update center like the core jMP plugins. class="li"> Enter <code><a
</p> href="https://jmonkeyplatform-contributions.googlecode.com/svn/trunk">https://jmonkeyplatform-contributions.googlecode.com/svn/trunk</a></code> in the <acronym
title="Uniform Resource Locator">URL</acronym> field</div></li><li
<p> class="level2"><div
<br/> class="li"> Enter your googlecode username and commit password (different than login pass!) and press &quot;Next&quot;</div></li><li
class="level2"><div
To add your plugin to the repository, do the following: class="li"> Check that the &quot;Repository Folder&quot; is <code>trunk/mypluginfolder</code> and enter an import message</div></li><li
</p> class="level2"><div
<ul> class="li"> Press &quot;Finish&quot;</div></li></ul></li></ul><p> And thats it, from now on each time you commit changes to your module it will be built and added to the contributions center automatically and the version number will be extended by the svn revision number (e.g. 0.8.1.1234)</p></div>
<li><div> Make sure the plugin is part of a “Module Suite” and that its located in the folder of the suite (this saves you from problems with the svn and local version not being configured the same)</div>
</li>
<li><div> In “Module Properties→Sources” set the “Source Level” to 1.5 if possible (jMP is compatible to Java 1.5)</div>
</li>
<li><div> In “Module Properties→<acronym title="Application Programming Interface">API</acronym> Versioning” set a specification version for your plugin (like 0.8.1)</div>
</li>
<li><div> Set the “implementation version” to “0” and select “append implementation versions automatically”</div>
</li>
<li><div> Ask the managers or developers for access to the gc project</div>
</li>
<li><div> Commit <strong>only the module project</strong> to trunk:</div>
<ul>
<li><div> Right click the Plugin Project and select “Versioning → Import into Subversion Repository”</div>
</li>
<li><div> Enter <code><object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://jmonkeyplatform-contributions.googlecode.com/svn/trunk"><param name="text" value="<html><u>https://jmonkeyplatform-contributions.googlecode.com/svn/trunk</u></html>"><param name="textColor" value="blue"></object></code> in the <acronym title="Uniform Resource Locator">URL</acronym> field</div>
</li>
<li><div> Enter your googlecode username and commit password (different than login pass!) and press “Next”</div>
</li>
<li><div> Check that the “Repository Folder” is <code>trunk/mypluginfolder</code> and enter an import message</div>
</li>
<li><div> Press “Finish”</div>
</li>
</ul>
</li>
</ul>
<p>
And thats it, from now on each time you commit changes to your module it will be built and added to the contributions center automatically and the version number will be extended by the svn revision number (e.g. 0.8.1.1234)
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:setup?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:setup?do=export_xhtmlbody">view online version</a></em></p>

@ -1,108 +1,52 @@
<h1><a
<h1><a>The Material Editor</a></h1> name="the_material_editor">The Material Editor</a></h1><div
<div> class="level1"></div><h2><a
name="materials">Materials</a></h2><div
</div> class="level2"><p> The jMonkeyEngine uses a special Material format, which comes in .j3m files. You use .j3m files to store sets of material properties that you use repeatedly. This enables you write one short line of code that simply loads the presets from a custom j3m file. Without a .j3m file you need to write several lines of material property setters every time when you want to use a non-default material.</p></div><h2><a
name="creating_j3m_materials">Creating .j3m Materials</a></h2><div
<h2><a>Materials</a></h2> class="level2"><p> <a
<div> href="/wiki/lib/exe/detail.php/sdk:material-editor.png?id=sdk%3Amaterial_editing"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/material-editor.png?w=306&amp;h=395" class="mediaright" align="right" alt="" width="306" height="395" /></a></p><p> To create new .j3m files,</p><ol><li
<p> class="level1"><div
class="li"> Right-click the <code>assets/Materials</code> directory and choose New… &gt; Other.</div></li><li
The jMonkeyEngine uses a special Material format, which comes in .j3m files. You use .j3m files to store sets of material properties that you use repeatedly. This enables you write one short line of code that simply loads the presets from a custom j3m file. Without a .j3m file you need to write several lines of material property setters every time when you want to use a non-default material. class="level1"><div
class="li"> In the New File Wizard, choose Material &gt; Empty Material File, and click Next.</div></li><li
</p> class="level1"><div
class="li"> Give the file a name, for example <code>mat_wall</code> for a wall material.</div></li><li
</div> class="level1"><div
class="li"> A new file <code>mat_wall.j3m</code> is created in the Materials directory and opens in the Material Editor.</div></li></ol><p> You can edit the source of the material, or use the user-friendly visual editor to set the properties of the material. Set the properties to the same values as you would otherwise specify with setters on a Material object in Java code:</p><pre>Material mat_wall = new Material&#40;
<h2><a>Creating .j3m Materials</a></h2>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/material-editor.png">
</p>
<p>
To create new .j3m files,
</p>
<ol>
<li><div> Right-click the <code>assets/Materials</code> directory and choose New… &gt; Other.</div>
</li>
<li><div> In the New File Wizard, choose Material &gt; Empty Material File, and click Next.</div>
</li>
<li><div> Give the file a name, for example <code>mat_wall</code> for a wall material.</div>
</li>
<li><div> A new file <code>mat_wall.j3m</code> is created in the Materials directory and opens in the Material Editor.</div>
</li>
</ol>
<p>
You can edit the source of the material, or use the user-friendly visual editor to set the properties of the material. Set the properties to the same values as you would otherwise specify with setters on a Material object in Java code:
</p>
<pre>Material mat_wall = new Material&#40;
assetManager, &quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;; assetManager, &quot;Common/MatDefs/Light/Lighting.j3md&quot;&#41;;
mat_wall.setTexture&#40;&quot;DiffuseMap&quot;, mat_wall.setTexture&#40;&quot;DiffuseMap&quot;,
assetManager.loadTexture&#40;&quot;Textures/wall.png&quot;&#41;&#41;; assetManager.loadTexture&#40;&quot;Textures/wall.png&quot;&#41;&#41;;
mat_wall.setTexture&#40;&quot;NormalMap&quot;, mat_wall.setTexture&#40;&quot;NormalMap&quot;,
assetManager.loadTexture&#40;&quot;Textures/wall-normals.png&quot;&#41;&#41;; assetManager.loadTexture&#40;&quot;Textures/wall-normals.png&quot;&#41;&#41;;
mat_wall.setFloat&#40;&quot;Shininess&quot;, 5f&#41;;</pre> mat_wall.setFloat&#40;&quot;Shininess&quot;, 5f&#41;;</pre><p> The source code of the j3m file is always accessible and can be modified in the &quot;source&quot; tab of the editor.</p></div><h2><a
<p> name="using_j3m_materials">Using .j3m Materials</a></h2><div
The source code of the j3m file is always accessible and can be modified in the “source” tab of the editor. class="level2"><p> <a
</p> href="/wiki/lib/exe/detail.php/sdk:applymaterial.jpg?id=sdk%3Amaterial_editing"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/applymaterial.jpg?w=180&amp;h=300" class="mediaright" align="right" title="applymaterial.jpg" alt="applymaterial.jpg" width="180" height="300" /></a></p><p> When the material is ready and saved into your projects assets directory, you can assign the .j3m to a Geometry.</p><p> In the jMonkeyPlatform</p><ol><li
</div> class="level1"><div
class="li"> Right-click the j3o file and select &quot;Edit in SceneComposer&quot;</div></li><li
<h2><a>Using .j3m Materials</a></h2> class="level1"><div
<div> class="li"> Open the SceneExplorer window</div></li><li
class="level1"><div
<p> class="li"> In the SceneExplorer, click the geometry to which you want to assign the material.</div></li><li
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/applymaterial.jpg"> class="level1"><div
</p> class="li"> Open the Properties window</div></li><li
class="level1"><div
<p> class="li"> Assign the .j3m material to the .j3o in the Properties&gt;Geometry&gt;Material section</div></li><li
When the material is ready and saved into your projects assets directory, you can assign the .j3m to a Geometry. class="level1"><div
</p> class="li"> Save the j3o and load it into you game.</div></li></ol><p> Or in your Java code</p><ul><li
class="level1"><div
<p> class="li"> Use a loader and a setter to assign the material to a Geometry</div></li></ul><pre>mywall.setMaterial&#40;assetManager.loadAsset&#40; &quot;Materials/mat_wall.j3m&quot;&#41;&#41;;</pre><hr
In the jMonkeyPlatform /><p> See also</p><ul><li
</p> class="level1"><div
<ol> class="li"> <a
<li><div> Right-click the j3o file and select “Edit in SceneComposer”</div> href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></div></li><li
</li> class="level1"><div
<li><div> Open the SceneExplorer window</div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></div></li><li
<li><div> In the SceneExplorer, click the geometry to which you want to assign the material.</div> class="level1"><div
</li> class="li"> <a
<li><div> Open the Properties window</div> href="/com/jme3/gde/core/docs/sdk/neotexture.html">Neotexture</a> (Procedural textures)</div></li></ul></div>
</li>
<li><div> Assign the .j3m material to the .j3o in the Properties&gt;Geometry&gt;Material section</div>
</li>
<li><div> Save the j3o and load it into you game.</div>
</li>
</ol>
<p>
Or in your Java code
</p>
<ul>
<li><div> Use a loader and a setter to assign the material to a Geometry</div>
</li>
</ul>
<pre>mywall.setMaterial&#40;assetManager.loadAsset&#40; &quot;Materials/mat_wall.j3m&quot;&#41;&#41;;</pre><hr />
<p>
See also
</p>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/beginner/hello_material.html">Hello Material</a></div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a></div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/sdk/neotexture.html">Neotexture</a> (Procedural textures)</div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:material_editing?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:material_editing?do=export_xhtmlbody">view online version</a></em></p>

@ -1,169 +1,72 @@
<h1><a
<h1><a>jMonkeyPlatform: Importing and Viewing Models</a></h1> name="jmonkeyplatformimporting_and_viewing_models">jMonkeyPlatform: Importing and Viewing Models</a></h1><div
<div> class="level1"><p> JMonkeyPlatform imports models from your project and stores them in the assets folder. The imported models are converted to a jME3 compatible binary format called .j3o. Double-click .j3o files in the jMonkeyPlatform to display them in the SceneViewer, or load them in-game using the AssetManager.</p><p> Presently, <a
href="http://www.blender.org/">Blender 3D</a> is the preferred modelling tool for jME3 as it is also Open-Source Software and an exporter for OgreXML files exists. Note that the OgreXML exporter is not yet compatible with Blender 2.5alpha!</p><p> Also, see this <a
<p> href="http://www.youtube.com/watch?v=nL7woH40i5c">demo video</a> on importing models.</p></div><h3><a
name="installing_the_ogrexml_exporter_in_blender">Installing the OgreXML Exporter in Blender</a></h3><div
JMonkeyPlatform imports models from your project and stores them in the assets folder. The imported models are converted to a jME3 compatible binary format called .j3o. Double-click .j3o files in the jMonkeyPlatform to display them in the SceneViewer, or load them in-game using the AssetManager. class="level3"><p> jMonkeyPlatform includes a tool to install the correct exporter tools in Blender to export OgreXML files. To install the exporter, do the following:</p><ol><li
</p> class="level1"><div
class="li"> Select &quot;Tools&quot;&quot;OgreXML&quot;&quot;Install Blender OgreXML&quot; in the jMonkeyPlatform Menu</div></li><li
<p> class="level1"><div
Presently, <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.blender.org/"><param name="text" value="<html><u>Blender 3D</u></html>"><param name="textColor" value="blue"></object> is the preferred modelling tool for jME3 as it is also Open-Source Software and an exporter for OgreXML files exists. Note that the OgreXML exporter is not yet compatible with Blender 2.5alpha! class="li"> If you are presented a filechooser, select the folder where your blender scripts reside</div></li><li
</p> class="level1"><div
class="li"> Press &quot;Install&quot; in the window that opens</div></li></ol></div><h2><a
<p> name="importing_and_viewing_a_model">Importing and Viewing a Model</a></h2><div
Also, see this <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://www.youtube.com/watch?v=nL7woH40i5c"><param name="text" value="<html><u>demo video</u></html>"><param name="textColor" value="blue"></object> on importing models. class="level2"></div><h3><a
</p> name="using_the_model_importer_tool">Using the Model Importer Tool</a></h3><div
class="level3"><p> jMonkeyPlatform includes a model importer tool that allows you to preview and import supported models into your jMonkeyEngine3 project.</p><p> <a
</div> href="/wiki/lib/exe/detail.php/wp-uploads:2010:11:jmonkeyplatform003-300x117.jpg?id=sdk%3Amodel_loader_and_viewer"><img
src="nbdocs:/com/jme3/gde/core/docs/wp-uploads/2010/11/jmonkeyplatform003-300x117.jpg" class="media" title="jmonkeyplatform003-300x117.jpg" alt="jmonkeyplatform003-300x117.jpg" /></a> <a
<h3><a>Installing the OgreXML Exporter in Blender</a></h3> href="/wiki/lib/exe/detail.php/wp-uploads:2010:11:jmonkeyplatform002-300x218.jpg?id=sdk%3Amodel_loader_and_viewer"><img
<div> src="nbdocs:/com/jme3/gde/core/docs/wp-uploads/2010/11/jmonkeyplatform002-300x218.jpg" class="mediaright" align="right" title="jmonkeyplatform002-300x218.jpg" alt="jmonkeyplatform002-300x218.jpg" /></a></p><ol><li
class="level1"><div
<p> class="li"> Select the project you want to import your model to</div></li><li
class="level1"><div
jMonkeyPlatform includes a tool to install the correct exporter tools in Blender to export OgreXML files. To install the exporter, do the following: class="li"> Click the &quot;Import Model&quot; button in the toolbar</div></li><li
class="level1"><div
</p> class="li"> Click &quot;open model..&quot; and select the main model file</div></li><li
<ol> class="level1"><div
<li><div> Select “Tools”→“OgreXML”→“Install Blender OgreXML” in the jMonkeyPlatform Menu</div> class="li"> Check the preview and file list and press &quot;Next&quot;</div></li><li
</li> class="level1"><div
<li><div> If you are presented a filechooser, select the folder where your blender scripts reside</div> class="li"> Check and change the import path if necessary</div></li><li
</li> class="level1"><div
<li><div> Press “Install” in the window that opens</div> class="li"> If you want to copy the original model files as well, check the checkbox</div></li><li
</li> class="level1"><div
</ol> class="li"> Press &quot;finish&quot;</div></li></ol><p> The model is converted to j3o and all necessary files are copied to the project assets folder. If you have specified the corresponding option, all original model files will also be copied to your assets folder.</p></div><h3><a
name="using_the_model_files_directly">Using the model files directly</a></h3><div
</div> class="level3"><p> <a
href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-2.png?id=sdk%3Amodel_loader_and_viewer"><img
<h2><a>Importing and Viewing a Model</a></h2> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-2.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><ol><li
<div> class="level1"><div
class="li"> Create a separate folder for each model in the <code>assets</code> folder of your project.</div></li><li
</div> class="level1"><div
class="li"> Export the model from Blender as OgreXML into its subfolder in <strong>the <code>asset</code> folder of your project</strong>,</div></li><li
<h3><a>Using the Model Importer Tool</a></h3> class="level1"><div
<div> class="li"> Make sure that the OgreXML material file has the same name as the exported mesh or scene file!</div></li><li
class="level1"><div
<p> class="li"> In the Projects Explorer Assets node, select the model that you want to import.</div></li><li
jMonkeyPlatform includes a model importer tool that allows you to preview and import supported models into your jMonkeyEngine3 project. class="level1"><div
</p> class="li"> Double-click the model or right-click and select &quot;Convert to JME binary&quot; from the context-menu.</div></li><li
class="level1"><div
<p> class="li"> In the Projects Explorer Assets node you should see your model j3o file.</div></li><li
<img src="nbdocs:/com/jme3/gde/core/docs/wp-uploads/2010/11/jmonkeyplatform003-300x117.jpg"> class="level1"><div
<img src="nbdocs:/com/jme3/gde/core/docs/wp-uploads/2010/11/jmonkeyplatform002-300x218.jpg"> class="li"> Double-click it to view it in the SceneViewer.</div></li><li
class="level1"><div
</p> class="li"> Click on the lightbulb to turn on the light if you cannot see your model</div></li></ol><p> Note: It is important that you copy the model file and its textures to the correct assets folder before creating the j3o file because the paths for textures (and possibly other things) will be stored as absolute (to the assets folder root) when you convert that model. This means the texture location should not change after the import.</p></div><h2><a
<ol> name="working_with_a_model">Working With a Model</a></h2><div
<li><div> Select the project you want to import your model to</div> class="level2"><ul><li
</li> class="level1"><div
<li><div> Click the “Import Model” button in the toolbar</div> class="li"> Open Windows&gt;SceneExplorer to view sub-nodes of the model</div></li><li
</li> class="level1"><div
<li><div> Click “open model..” and select the main model file</div> class="li"> Open Windows&gt;Properties to view the properties of the model&#039;s nodes.</div></li><li
</li> class="level1"><div
<li><div> Check the preview and file list and press “Next”</div> class="li"> Click the cube button in the SceneViewer to toggle between Wireframe mode and Textured mode.</div></li><li
</li> class="level1"><div
<li><div> Check and change the import path if necessary</div> class="li"> Click the lightbulb to view Materials that require a light source</div></li></ul></div><h2><a
</li> name="notes_about_model_assets">Notes About Model Assets</a></h2><div
<li><div> If you want to copy the original model files as well, check the checkbox</div> class="level2"><p> The original OgreXML <code>.mesh.xml</code>, <code>.scene</code>, <code>.material</code> and <code>.skeleton.xml</code> model files <strong>will not be included</strong> in the distribution <code>assets.jar</code> file of your distributed game, they are only available in the assets folder so you are able to recreate the <code>.j3o</code> file from the original if you ever come to change it in blender and have to export it again.</p></div><h2><a
</li> name="about_the_sceneviewer_and_sceneexplorer_window">About the SceneViewer and SceneExplorer window</a></h2><div
<li><div> Press “finish”</div> class="level2"><p> The SceneViewer and SceneExplorer windows are shared among plugins to save system resources. This means that you will have to keep an eye on what plugin is using the scene right now and what you are actually modifying in these windows.</p><p> Most plugins will deliver their own UI elements to modify the scene so the SceneExplorer is more of a global tool. The simple SceneComposer however heavily relies on its functions as other plugins might too in the future.</p></div><h3><a
</li> name="about_the_projects_assetmanager">About the projects AssetManager</a></h3><div
</ol> class="level3"><p> Each jMP project has its own internal AssetManager that has the projects assets folder registered as a FileLocator. When the project is run, the assets folder is compressed into a jar file and added to the projects main jar classpath. This way the editors in jMP and the running game have the same asset folder structure.</p><p> You might wonder why jMP requires you to copy the model that is to be converted to j3o into the assets folder before. The Model Import Tool also copies the model and associated files to the project directory before converting. To load the model it needs to be in a folder (or jar etc..) that belongs to the projects AssetManager root. To load a model from some other folder of the filesystem, that folder would have to be added to the AssetManager root. If every folder that contains a model was in the root of the AssetManager, all textures named &quot;hull.jpg&quot; for example would be the same for the AssetManager and it would only deliver the texture of the first model folder that was added.</p><p> To have a valid jME3 object, the paths to textures and other assets belonging to the model have to be read with the correct, final path that can then be stored in the j3o object. The j3o object will use those paths when it is loaded with the AssetManager and it requires the AssetManager to deliver the assets on those paths, this is why the folder structure while converting has to be the same as when loading.</p></div>
<p>
The model is converted to j3o and all necessary files are copied to the project assets folder. If you have specified the corresponding option, all original model files will also be copied to your assets folder.
</p>
</div>
<h3><a>Using the model files directly</a></h3>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-2.png">
</p>
<ol>
<li><div> Create a separate folder for each model in the <code>assets</code> folder of your project.</div>
</li>
<li><div> Export the model from Blender as OgreXML into its subfolder in <strong>the <code>asset</code> folder of your project</strong>, </div>
</li>
<li><div> Make sure that the OgreXML material file has the same name as the exported mesh or scene file!</div>
</li>
<li><div> In the Projects Explorer Assets node, select the model that you want to import.</div>
</li>
<li><div> Double-click the model or right-click and select “Convert to JME binary” from the context-menu.</div>
</li>
<li><div> In the Projects Explorer Assets node you should see your model j3o file.</div>
</li>
<li><div> Double-click it to view it in the SceneViewer.</div>
</li>
<li><div> Click on the lightbulb to turn on the light if you cannot see your model</div>
</li>
</ol>
<p>
Note: It is important that you copy the model file and its textures to the correct assets folder before creating the j3o file because the paths for textures (and possibly other things) will be stored as absolute (to the assets folder root) when you convert that model. This means the texture location should not change after the import.
</p>
</div>
<h2><a>Working With a Model</a></h2>
<div>
<ul>
<li><div> Open Windows&gt;SceneExplorer to view sub-nodes of the model</div>
</li>
<li><div> Open Windows&gt;Properties to view the properties of the model&#039;s nodes.</div>
</li>
<li><div> Click the cube button in the SceneViewer to toggle between Wireframe mode and Textured mode.</div>
</li>
<li><div> Click the lightbulb to view Materials that require a light source</div>
</li>
</ul>
</div>
<h2><a>Notes About Model Assets</a></h2>
<div>
<p>
The original OgreXML <code>.mesh.xml</code>, <code>.scene</code>, <code>.material</code> and <code>.skeleton.xml</code> model files <strong>will not be included</strong> in the distribution <code>assets.jar</code> file of your distributed game, they are only available in the assets folder so you are able to recreate the <code>.j3o</code> file from the original if you ever come to change it in blender and have to export it again.
</p>
</div>
<h2><a>About the SceneViewer and SceneExplorer window</a></h2>
<div>
<p>
The SceneViewer and SceneExplorer windows are shared among plugins to save system resources. This means that you will have to keep an eye on what plugin is using the scene right now and what you are actually modifying in these windows.
</p>
<p>
Most plugins will deliver their own UI elements to modify the scene so the SceneExplorer is more of a global tool. The simple SceneComposer however heavily relies on its functions as other plugins might too in the future.
</p>
</div>
<h3><a>About the projects AssetManager</a></h3>
<div>
<p>
Each jMP project has its own internal AssetManager that has the projects assets folder registered as a FileLocator. When the project is run, the assets folder is compressed into a jar file and added to the projects main jar classpath. This way the editors in jMP and the running game have the same asset folder structure.
</p>
<p>
You might wonder why jMP requires you to copy the model that is to be converted to j3o into the assets folder before. The Model Import Tool also copies the model and associated files to the project directory before converting. To load the model it needs to be in a folder (or jar etc..) that belongs to the projects AssetManager root. To load a model from some other folder of the filesystem, that folder would have to be added to the AssetManager root. If every folder that contains a model was in the root of the AssetManager, all textures named “hull.jpg” for example would be the same for the AssetManager and it would only deliver the texture of the first model folder that was added.
</p>
<p>
To have a valid jME3 object, the paths to textures and other assets belonging to the model have to be read with the correct, final path that can then be stored in the j3o object. The j3o object will use those paths when it is loaded with the AssetManager and it requires the AssetManager to deliver the assets on those paths, this is why the folder structure while converting has to be the same as when loading.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:model_loader_and_viewer?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:model_loader_and_viewer?do=export_xhtmlbody">view online version</a></em></p>

@ -1,259 +1,151 @@
<h1><a
<h1><a>jMonkeyPlatform: Creating Projects</a></h1> name="jmonkeyplatformcreating_projects">jMonkeyPlatform: Creating Projects</a></h1><div
<div> class="level1"><p> The jMonkeyPlatform makes it easy to get started with developing 3-D games based on the jMonkeyEngine.</p></div><h2><a
name="creating_a_new_jmonkeyengine_project">Creating a New jMonkeyEngine Project</a></h2><div
<p> class="level2"><ol><li
class="level1"><div
The jMonkeyPlatform makes it easy to get started with developing 3-D games based on the jMonkeyEngine. class="li"> Choose File &gt; New Project from the main menu.</div></li><li
</p> class="level1"><div
class="li"> In the New Project Wizard, select the template JME3 &gt; Basic Game</div></li><li
</div> class="level1"><div
class="li"> Click next to specify a project name, and the path where to store your new project.</div></li><li
<h2><a>Creating a New jMonkeyEngine Project</a></h2> class="level1"><div
<div> class="li"> Click Finish. A skeleton application is created and opens in the Project Explorer.</div><ul><li
<ol> class="level2"><div
<li><div> Choose File &gt; New Project from the main menu.</div> class="li"> This basic jme3 application is based on the SimpleApplication class to allow an easy start with jme3.</div></li><li
</li> class="level2"><div
<li><div> In the New Project Wizard, select the template JME3 &gt; Basic Game</div> class="li"> You can click the run button to run it: You will see a jMonkey cube.</div></li></ul></li></ol></div><h4><a
</li> name="project_structure">Project Structure</a></h4><div
<li><div> Click next to specify a project name, and the path where to store your new project.</div> class="level4"><p> <a
</li> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-4.png?id=sdk%3Aproject_creation"><img
<li><div> Click Finish. A skeleton application is created and opens in the Project Explorer.</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-4.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><p> Let&#039;s have a look at the abstract project structure in the Project Explorer (ctrl-1).</p><ul><li
<ul> class="level1"><div
<li><div> This basic jme3 application is based on the SimpleApplication class to allow an easy start with jme3.</div> class="li"> <strong>Project Assets node:</strong> These directories have been created for you to store your games assets, such as fonts, materials, models, shaders, sounds, and textures. For a newly created project, these directories are empty.</div></li><li
</li> class="level1"><div
<li><div> You can click the run button to run it: You will see a jMonkey cube.</div> class="li"> <strong>Source Packages node:</strong> This is where you manage your packages and classes. For a newly created project, it contains one package and one class, <code>Main.java</code>. Double click <code>Main.java</code> to open it in the editor.</div></li><li
</li> class="level1"><div
</ul> class="li"> <strong>Libraries node:</strong> An overview of all libraies on your game&#039;s classpath. The classpath is already set-up for the jme3 framework (including LWJGL, JOGG, JOAL, JOGL, etc).</div></li></ul></div><h4><a
</li> name="directory_structure">Directory Structure</a></h4><div
</ol> class="level4"><p> Now let&#039;s have a look at the project&#039;s file structure in the File Explorer (ctrl-2). This explorer shows the physical directory structure on your hard drive.</p><ul><li
class="level1"><div
</div> class="li"> <strong>assets</strong> – This directory corresponds to the Project Assets node. It is needed for the assetManager. This is the recommended internal structure:</div><ul><li
class="level2"><div
<h4><a>Project Structure</a></h4> class="li"> <code>assets/Interface</code></div></li><li
<div> class="level2"><div
class="li"> <code>assets/MatDefs</code></div></li><li
<p> class="level2"><div
class="li"> <code>assets/Materials</code></div></li><li
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-4.png"> class="level2"><div
</p> class="li"> <code>assets/Models</code></div></li><li
class="level2"><div
<p> class="li"> <code>assets/Scenes</code></div></li><li
Let&#039;s have a look at the abstract project structure in the Project Explorer (ctrl-1). class="level2"><div
class="li"> <code>assets/Shaders</code></div></li><li
</p> class="level2"><div
<ul> class="li"> <code>assets/Sounds</code></div></li><li
<li><div> <strong>Project Assets node:</strong> These directories have been created for you to store your games assets, such as fonts, materials, models, shaders, sounds, and textures. For a newly created project, these directories are empty.</div> class="level2"><div
</li> class="li"> <code>assets/Textures</code></div></li></ul></li><li
<li><div> <strong>Source Packages node:</strong> This is where you manage your packages and classes. For a newly created project, it contains one package and one class, <code>Main.java</code>. Double click <code>Main.java</code> to open it in the editor.</div> class="level1"><div
</li> class="li"> <strong>src</strong> – This directory corresponds to the Source Packages node. Your sources code goes here.</div></li><li
<li><div> <strong>Libraries node:</strong> An overview of all libraies on your game&#039;s classpath. The classpath is already set-up for the jme3 framework (including LWJGL, JOGG, JOAL, JOGL, etc).</div> class="level1"><div
</li> class="li"> <strong>nbproject</strong> – This is meta data used by the jMonkeyPlatform (don&#039;t edit).</div></li><li
</ul> class="level1"><div
class="li"> <strong>build.xml</strong> – This is an Ant build script that is hooked up to the clean/build/run/test actions in the jMonkeyPlatform. It loads a default build script, and allows you to further customize the build process. The Ant script also assures that you are able to clean/build/run/test your application outside of the jMonkeyPlatform – e.g. from the command line.</div></li><li
</div> class="level1"><div
class="li"> <strong>build</strong> – This directory contains the compiled classes. (Will be generated by the jMonkeyPlatform when you build the project.)</div></li><li
<h4><a>Directory Structure</a></h4> class="level1"><div
<div> class="li"> <strong>dist</strong> – This directory contains the executable JAR files. (Will be generated by the jMonkeyPlatform when you build the project.)</div></li><li
class="level1"><div
<p> class="li"> <strong>test</strong> – The jMonkeyPlatform will store JUnit tests here if you create any. (Optional.)</div></li></ul></div><h2><a
name="working_with_your_game_project">Working With Your Game Project</a></h2><div
Now let&#039;s have a look at the project&#039;s file structure in the File Explorer (ctrl-2). This explorer shows the physical directory structure on your hard drive. class="level2"></div><h3><a
name="project_configuration">Project Configuration</a></h3><div
</p> class="level3"><p> Right-Click the project to open the Project properties.</p><ul><li
<ul> class="level1"><div
<li><div> <strong>assets</strong> – This directory corresponds to the Project Assets node. It is needed for the assetManager. This is the recommended internal structure:</div> class="li"> In the Run section, specify the main class of your project.</div></li><li
<ul> class="level1"><div
<li><div> <code>assets/Interface</code></div> class="li"> In the Run section, you can optionally configure JVM options and command line parameters.</div></li><li
</li> class="level1"><div
<li><div> <code>assets/MatDefs</code></div> class="li"> In the Application section, specify the game title (by default the game will be named <code>BasicGame</code>).</div></li><li
</li> class="level1"><div
<li><div> <code>assets/Materials</code></div> class="li"> In the Application section, specify the vendor name (your name), a short description, your project&#039;s homepage, and a splash screen.</div></li></ul></div><h3><a
</li> name="adding_external_jar_libraries">Adding external jar libraries</a></h3><div
<li><div> <code>assets/Models</code></div> class="level3"><p> Add the library to the global library list:</p><ul><li
</li> class="level1"><div
<li><div> <code>assets/Scenes</code></div> class="li"> Select Tools→Libraries in the main menu.</div></li><li
</li> class="level1"><div
<li><div> <code>assets/Shaders</code></div> class="li"> Click &quot;New Library&quot;, enter a name for the library and press OK</div></li><li
</li> class="level1"><div
<li><div> <code>assets/Sounds</code></div> class="li"> In the &quot;Classpath&quot; tab, press &quot;Add JAR/Folder&quot; and select the jar file(s) needed for the library</div></li><li
</li> class="level1"><div
<li><div> <code>assets/Textures</code></div> class="li"> In the &quot;JavaDoc&quot; tab, press &quot;Add ZIP/Folder&quot; and select the javadoc for the library (zipped or folder)</div></li><li
</li> class="level1"><div
</ul> class="li"> In the &quot;Sources&quot; tab you can select a folder or jar file containing the source files of the library if available</div></li><li
</li> class="level1"><div
<li><div> <strong>src</strong> – This directory corresponds to the Source Packages node. Your sources code goes here.</div> class="li"> Press OK</div></li><li
</li> class="level1"><div
<li><div> <strong>nbproject</strong> – This is meta data used by the jMonkeyPlatform (don&#039;t edit).</div> class="li"> Right-Click your project</div></li></ul><p> Add the library to a project:</p><ul><li
</li> class="level1"><div
<li><div> <strong>build.xml</strong> – This is an Ant build script that is hooked up to the clean/build/run/test actions in the jMonkeyPlatform. It loads a default build script, and allows you to further customize the build process. The Ant script also assures that you are able to clean/build/run/test your application outside of the jMonkeyPlatform – e.g. from the command line.</div> class="li"> Right-Click your project and select &quot;Properties&quot;</div></li><li
</li> class="level1"><div
<li><div> <strong>build</strong> – This directory contains the compiled classes. (Will be generated by the jMonkeyPlatform when you build the project.)</div> class="li"> Select &quot;Libaries&quot; on the left and then press &quot;Add Library&quot;</div></li><li
</li> class="level1"><div
<li><div> <strong>dist</strong> – This directory contains the executable JAR files. (Will be generated by the jMonkeyPlatform when you build the project.)</div> class="li"> Select the library from the list and press OK</div></li></ul><p> Thats it, your project can now use the external library.</p></div><h3><a
</li> name="development_process">Development Process</a></h3><div
<li><div> <strong>test</strong> – The jMonkeyPlatform will store JUnit tests here if you create any. (Optional.)</div> class="level3"><ul><li
</li> class="level1"><div
</ul> class="li"> <strong>Creating new files and packages:</strong> Select the Source Packages node (or any of its subnodes), and press ctrl-N (File&gt;New File): Use the New File wizard to create new Java classes, Java packages, Java beans, Swing forms, Junit files, JME3 Materials and Models, and many more.</div></li><li
class="level1"><div
</div> class="li"> <strong>Editing files:</strong> Open the Projects Explorer and double-click a Java file from the Source Packages to open it in the Editor. The <a
href="/com/jme3/gde/core/docs/sdk/code_editor.html">jMonkeyPlatform Editor</a> assists you in many ways, including Syntactic and semantic code coloring, code completion, and javadoc. <a
<h2><a>Working With Your Game Project</a></h2> href="/com/jme3/gde/core/docs/sdk/code_editor.html">(More...)</a></div></li><li
<div> class="level1"><div
class="li"> <strong>Adding Assets:</strong></div><ul><li
</div> class="level2"><div
class="li"> You can <a
<h3><a>Project Configuration</a></h3> href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">import models, scenes, and materials</a> as assets into your project.</div></li><li
<div> class="level2"><div
class="li"> To add sound files and images, use your operating system&#039;s file explorer and copy the files into your project&#039;s asset directory.</div></li></ul></li><li
<p> class="level1"><div
class="li"> <strong>ToDo List:</strong> The tasks window automatically lists all lines containing errors and warnings, and all lines that you have marked with comment keywords such as <code
Right-Click the project to open the Project properties. class="code html4strict">FIXME</code>, @todo, TODO.</div></li><li
</p> class="level1"><div
<ul> class="li"> <strong>Integrated tools:</strong> <a
<li><div> In the Run section, specify the main class of your project. </div> href="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">Debugging, Testing, Profiling</a>.</div></li></ul></div><h3><a
</li> name="clean_build_and_run_cycle">Clean, Build and Run Cycle</a></h3><div
<li><div> In the Run section, you can optionally configure JVM options and command line parameters.</div> class="level3"><p> <a
</li> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-5.png?id=sdk%3Aproject_creation"><img
<li><div> In the Application section, specify the game title (by default the game will be named <code>BasicGame</code>).</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-5.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><ul><li
</li> class="level1"><div
<li><div> In the Application section, specify the vendor name (your name), a short description, your project&#039;s homepage, and a splash screen.</div> class="li"> Right-Click the project and use the context-menu to clean all generated classes and JARs.</div></li><li
</li> class="level1"><div
</ul> class="li"> Right-Click individual files with a main method to build and run them. (Shift-F6)</div></li><li
class="level1"><div
</div> class="li"> Press the Run button (green arrow in the toolbar) to build and run the project. (F6)</div></li></ul><p> <strong>More than one project open?</strong> The toolbar buttons and the F-keys are bound to the main project, which is shown in bold in the Project Explorer. Right-click a project and select Set As Main Project to make it respond to the toolbar buttons and F-keys.</p><p> <strong>Worried About Proprietary Lock-in?</strong> You are never locked into the jMonkeyPlatform: At any time, you can change into your project directory on the command line, and clean, build, and run your project, using non-proprietary Apache Ant commands:</p><pre>ant clean; ant jar; ant run;</pre></div><h3><a
name="application_deployment">Application Deployment</a></h3><div
<h3><a>Adding external jar libraries</a></h3> class="level3"><ul><li
<div> class="level1"><div
class="li"> You can <a
<p> href="/com/jme3/gde/core/docs/sdk/application_deployment.html">deploy</a> your game as desktop application (JAR), browser applet, WebStart (JNLP), or on the Android platform. <a
href="/com/jme3/gde/core/docs/sdk/application_deployment.html">(More...)</a></div></li></ul></div><h2><a
Add the library to the global library list: name="running_sample_projects">Running Sample Projects</a></h2><div
</p> class="level2"><ol><li
<ul> class="level1"><div
<li><div> Select Tools→Libraries in the main menu.</div> class="li"> Choose File &gt; New Project from the main menu.</div></li><li
</li> class="level1"><div
<li><div> Click “New Library”, enter a name for the library and press OK</div> class="li"> In the New Project Wizard, select JME3 &gt; JME3 Tests</div></li><li
</li> class="level1"><div
<li><div> In the “Classpath” tab, press “Add JAR/Folder” and select the jar file(s) needed for the library</div> class="li"> Click next to pick a path where to store the <code>JME3Tests</code> project.</div></li><li
</li> class="level1"><div
<li><div> In the “JavaDoc” tab, press “Add ZIP/Folder” and select the javadoc for the library (zipped or folder)</div> class="li"> Click Finish. The sample project opens.</div></li><li
</li> class="level1"><div
<li><div> In the “Sources” tab you can select a folder or jar file containing the source files of the library if available</div> class="li"> Right-click the <code>JME3Tests</code> project and choose Run.</div><ul><li
</li> class="level2"><div
<li><div> Press OK</div> class="li"> Use the TestChooser to try out the included jMonkeyEngine demos!</div></li></ul></li><li
</li> class="level1"><div
<li><div> Right-Click your project</div> class="li"> Open the Source Packages node of the sample&#039;s project.</div><ul><li
</li> class="level2"><div
</ul> class="li"> Browse a demo&#039;s source code to learn how a feature is implemented.</div></li><li
class="level2"><div
<p> class="li"> Feel free to modify the code samples and experiment! If you break something, you can always recreate the packaged samples from the <code>JME3 Tests</code> template.</div></li></ul></li></ol></div>
Add the library to a project:
</p>
<ul>
<li><div> Right-Click your project and select “Properties”</div>
</li>
<li><div> Select “Libaries” on the left and then press “Add Library”</div>
</li>
<li><div> Select the library from the list and press OK</div>
</li>
</ul>
<p>
Thats it, your project can now use the external library.
</p>
</div>
<h3><a>Development Process</a></h3>
<div>
<ul>
<li><div> <strong>Creating new files and packages:</strong> Select the Source Packages node (or any of its subnodes), and press ctrl-N (File&gt;New File): Use the New File wizard to create new Java classes, Java packages, Java beans, Swing forms, Junit files, JME3 Materials and Models, and many more.</div>
</li>
<li><div> <strong>Editing files:</strong> Open the Projects Explorer and double-click a Java file from the Source Packages to open it in the Editor. The <a href="/com/jme3/gde/core/docs/sdk/code_editor.html">jMonkeyPlatform Editor</a> assists you in many ways, including Syntactic and semantic code coloring, code completion, and javadoc. <a href="/com/jme3/gde/core/docs/sdk/code_editor.html">(More...)</a></div>
</li>
<li><div> <strong>Adding Assets:</strong></div>
<ul>
<li><div> You can <a href="/com/jme3/gde/core/docs/sdk/model_loader_and_viewer.html">import models, scenes, and materials</a> as assets into your project.</div>
</li>
<li><div> To add sound files and images, use your operating system&#039;s file explorer and copy the files into your project&#039;s asset directory.</div>
</li>
</ul>
</li>
<li><div> <strong>ToDo List:</strong> The tasks window automatically lists all lines containing errors and warnings, and all lines that you have marked with comment keywords such as <code>FIXME</code>, @todo, TODO.</div>
</li>
<li><div> <strong>Integrated tools:</strong> <a href="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">Debugging, Testing, Profiling</a>.</div>
</li>
</ul>
</div>
<h3><a>Clean, Build and Run Cycle</a></h3>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-5.png">
</p>
<ul>
<li><div> Right-Click the project and use the context-menu to clean all generated classes and JARs.</div>
</li>
<li><div> Right-Click individual files with a main method to build and run them. (Shift-F6)</div>
</li>
<li><div> Press the Run button (green arrow in the toolbar) to build and run the project. (F6)</div>
</li>
</ul>
<p>
<strong>More than one project open?</strong> The toolbar buttons and the F-keys are bound to the main project, which is shown in bold in the Project Explorer. Right-click a project and select Set As Main Project to make it respond to the toolbar buttons and F-keys.
</p>
<p>
<strong>Worried About Proprietary Lock-in?</strong> You are never locked into the jMonkeyPlatform: At any time, you can change into your project directory on the command line, and clean, build, and run your project, using non-proprietary Apache Ant commands:
</p>
<pre>ant clean; ant jar; ant run;</pre>
</div>
<h3><a>Application Deployment</a></h3>
<div>
<ul>
<li><div> You can <a href="/com/jme3/gde/core/docs/sdk/application_deployment.html">deploy</a> your game as desktop application (JAR), browser applet, WebStart (JNLP), or on the Android platform. <a href="/com/jme3/gde/core/docs/sdk/application_deployment.html">(More...)</a> </div>
</li>
</ul>
</div>
<h2><a>Running Sample Projects</a></h2>
<div>
<ol>
<li><div> Choose File &gt; New Project from the main menu.</div>
</li>
<li><div> In the New Project Wizard, select JME3 &gt; JME3 Tests</div>
</li>
<li><div> Click next to pick a path where to store the <code>JME3Tests</code> project.</div>
</li>
<li><div> Click Finish. The sample project opens. </div>
</li>
<li><div> Right-click the <code>JME3Tests</code> project and choose Run.</div>
<ul>
<li><div> Use the TestChooser to try out the included jMonkeyEngine demos!</div>
</li>
</ul>
</li>
<li><div> Open the Source Packages node of the sample&#039;s project.</div>
<ul>
<li><div> Browse a demo&#039;s source code to learn how a feature is implemented.</div>
</li>
<li><div> Feel free to modify the code samples and experiment! If you break something, you can always recreate the packaged samples from the <code>JME3 Tests</code> template.</div>
</li>
</ul>
</li>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:project_creation?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:project_creation?do=export_xhtmlbody">view online version</a></em></p>

@ -1,198 +1,74 @@
<h1><a
<h1><a>Scene Composer</a></h1> name="scene_composer">Scene Composer</a></h1><div
<div> class="level1"><p> SceneComposer allows you to edit scenes stored in j3o files and add content or modify existing content. Please note that the Scene Composer and Explorer are a work in progress and will provide more powerful functions in the future. Also other plugins will allow creation of more specific game type scenes in jMP.</p><p> Most buttons in the SceneComposer have tooltips that appear when you hover the mouse over the button for a short while.</p></div><h3><a
name="mouse_cursor_controls">Mouse/Cursor Controls</a></h3><div
<p> class="level3"><ul><li
class="level1"><div
SceneComposer allows you to edit scenes stored in j3o files and add content or modify existing content. Please note that the Scene Composer and Explorer are a work in progress and will provide more powerful functions in the future. Also other plugins will allow creation of more specific game type scenes in jMP. class="li"> Left-click and drag to rotate the camera around the cam center</div></li><li
</p> class="level1"><div
class="li"> Right-click and drag to move the cam center</div></li><li
<p> class="level1"><div
Most buttons in the SceneComposer have tooltips that appear when you hover the mouse over the button for a short while. class="li"> Scoll the mouse wheel to zoom in/out the cam center</div></li><li
</p> class="level1"><div
class="li"> Left-click a geometry to select it</div></li><li
</div> class="level1"><div
class="li"> Right-click a geometry to place the cursor</div></li></ul><p> In the SceneComposer toolbar are buttons to snap the camera to the cursor, snap the cursor to the selection and etc.</p></div><h3><a
<h3><a>Mouse/Cursor Controls</a></h3> name="creating_a_scene_file">Creating a scene file</a></h3><div
<div> class="level3"><p> jMP stores the scene in a j3o file, this binary file contains the whole scenegraph including all settings for spatials, materials, physics, effects etc. Textures are not stored in the j3o file but as absolute locators to the textures.</p><p> To create a blank scene file do the following:</p><ol><li
<ul> class="level1"><div
<li><div> Left-click and drag to rotate the camera around the cam center</div> class="li"> Right click the &quot;Scenes&quot; folder in your Project Assets and select &quot;New→Other&quot;</div></li><li
</li> class="level1"><div
<li><div> Right-click and drag to move the cam center</div> class="li"> Select &quot;Scene&quot; to the left then select &quot;Empty jME3 Scene&quot; and press &quot;Next&quot;</div></li><li
</li> class="level1"><div
<li><div> Scoll the mouse wheel to zoom in/out the cam center</div> class="li"> Enter a file name for your scene like &quot;MyScene&quot; and press &quot;OK&quot;</div></li></ol></div><h3><a
</li> name="loading_the_scene">Loading the scene</a></h3><div
<li><div> Left-click a geometry to select it</div> class="level3"><p> <a
</li> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-2.png?id=sdk%3Ascene_composer"><img
<li><div> Right-click a geometry to place the cursor</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-2.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><p> To open a scene</p><ol><li
</li> class="level1"><div
</ul> class="li"> In the Project Explorer, right-click the *.j3o file of the scene</div></li><li
class="level1"><div
<p> class="li"> Choose &quot;Open in SceneComposer&quot;</div></li></ol><p> Now the SceneComposer window opens at the bottom and displays the scene in the SceneViewer. The SceneExplorer displays the contained scene graph as a tree and when selecting a node, you can edit the properties of the corresponding scene graph object in the Properties window.</p><p> For now, you only see the cursor in the SceneViewer and a single node (the root node of the scene) in the SceneExplorer.</p></div><h3><a
name="adding_light_to_the_scene">Adding light to the scene</a></h3><div
In the SceneComposer toolbar are buttons to snap the camera to the cursor, snap the cursor to the selection and etc. class="level3"><ol><li
</p> class="level1"><div
class="li"> Select the root node in the SceneExplorer</div></li><li
</div> class="level1"><div
class="li"> Select &quot;Directional Light&quot; in the SceneComposer window</div></li><li
<h3><a>Creating a scene file</a></h3> class="level1"><div
<div> class="li"> Press the &quot;+&quot; button in the SceneComposer window</div></li></ol><p> A directional light has been added to your scene, you can see it in the SceneExplorer.</p></div><h3><a
name="adding_effects_etc_to_the_scene">Adding effects etc. to the scene</a></h3><div
<p> class="level3"><p> You can add a variety of special objects with the SceneComposer, including lights, effects, audio etc.</p><ol><li
class="level1"><div
jMP stores the scene in a j3o file, this binary file contains the whole scenegraph including all settings for spatials, materials, physics, effects etc. Textures are not stored in the j3o file but as absolute locators to the textures. class="li"> Select root Node in the SceneExplorer</div></li><li
</p> class="level1"><div
class="li"> Select the object type in the list displayed in the SceneComposer window</div></li><li
<p> class="level1"><div
To create a blank scene file do the following: class="li"> Press the &quot;+ cursor&quot; button in the SceneComposer window</div></li></ol></div><h3><a
</p> name="adding_models_to_the_scene">Adding Models to the scene</a></h3><div
<ol> class="level3"><p> <a
<li><div> Right click the “Scenes” folder in your Project Assets and select “New→Other”</div> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-docu-3.png?id=sdk%3Ascene_composer"><img
</li> src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-3.png?w=421&amp;h=298" class="mediaright" align="right" alt="" width="421" height="298" /></a></p><p> You can directly import 3d models to your scene so that they will be part of your scene file. To be able to import for example an OgreXML file, first export it from your 3D editor to a separate folder in the assets folder of your project (e.g. assets/Models/MyModel/).</p><ol><li
<li><div> Select “Scene” to the left then select “Empty jME3 Scene” and press “Next”</div> class="level1"><div
</li> class="li"> Place the SceneComposer cursor where you want the model to be</div></li><li
<li><div> Enter a file name for your scene like “MyScene” and press “OK”</div> class="level1"><div
</li> class="li"> Select the parent Node for the model in the SceneExplorer</div></li><li
</ol> class="level1"><div
class="li"> In the Project Explorer right-click the model file you want to import</div></li><li
</div> class="level1"><div
class="li"> Choose &quot;Add to SceneComposer&quot;</div></li></ol><p> Note that when importing a model the texture paths are stored absolute, so the folder you import the model from will later only be a textures folder because the original model file is not included in the release.</p><p> Also note that when adding models this way, changes in the original model file will not be reflected in the scene file as its a complete copy of the original file. If you change the original model, delete the models node from the scene and import it again.</p></div><h3><a
<h3><a>Loading the scene</a></h3> name="linking_models_to_the_scene">Linking Models to the scene</a></h3><div
<div> class="level3"><p> You can also link models/objects into your scene, this way they are reloaded dynamically from the other/original file.</p><ol><li
class="level1"><div
<p> class="li"> Place the SceneComposer cursor where you want the model to be</div></li><li
class="level1"><div
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-2.png"> class="li"> Select the parent Node for the model in the SceneExplorer</div></li><li
</p> class="level1"><div
class="li"> In the Project Explorer right-click the model file you want to link</div></li><li
<p> class="level1"><div
To open a scene class="li"> Choose &quot;Link in SceneComposer&quot;</div></li></ol><p> Note that when linking objects this way, you cannot edit them as part of the scene. To change the model you have to change the original j3o file.</p><p> Also note that although it its possible to directly link external model files (OgreXML, OBJ etc.), this is not recommended. Convert the original file to a j3o file by right-clicking it and selecting &quot;Convert to jME Binary&quot; before linking it. This is required because the original model files are not included in the release version of the application.</p></div><h3><a
</p> name="saving_the_scene">Saving the Scene</a></h3><div
<ol> class="level3"><ol><li
<li><div> In the Project Explorer, right-click the *.j3o file of the scene</div> class="level1"><div
</li> class="li"> When a scene has been changed, press the &quot;save&quot; button in the main toolbar or press [Ctrl-S] / [Apple-S] to save it.</div></li></ol></div>
<li><div> Choose “Open in SceneComposer”</div>
</li>
</ol>
<p>
Now the SceneComposer window opens at the bottom and displays the scene in the SceneViewer. The SceneExplorer displays the contained scene graph as a tree and when selecting a node, you can edit the properties of the corresponding scene graph object in the Properties window.
</p>
<p>
For now, you only see the cursor in the SceneViewer and a single node (the root node of the scene) in the SceneExplorer.
</p>
</div>
<h3><a>Adding light to the scene</a></h3>
<div>
<ol>
<li><div> Select the root node in the SceneExplorer</div>
</li>
<li><div> Select “Directional Light” in the SceneComposer window</div>
</li>
<li><div> Press the ”+” button in the SceneComposer window</div>
</li>
</ol>
<p>
A directional light has been added to your scene, you can see it in the SceneExplorer.
</p>
</div>
<h3><a>Adding effects etc. to the scene</a></h3>
<div>
<p>
You can add a variety of special objects with the SceneComposer, including lights, effects, audio etc.
</p>
<ol>
<li><div> Select root Node in the SceneExplorer</div>
</li>
<li><div> Select the object type in the list displayed in the SceneComposer window</div>
</li>
<li><div> Press the ”+ cursor” button in the SceneComposer window</div>
</li>
</ol>
</div>
<h3><a>Adding Models to the scene</a></h3>
<div>
<p>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-docu-3.png">
</p>
<p>
You can directly import 3d models to your scene so that they will be part of your scene file. To be able to import for example an OgreXML file, first export it from your 3D editor to a separate folder in the assets folder of your project (e.g. assets/Models/MyModel/).
</p>
<ol>
<li><div> Place the SceneComposer cursor where you want the model to be</div>
</li>
<li><div> Select the parent Node for the model in the SceneExplorer</div>
</li>
<li><div> In the Project Explorer right-click the model file you want to import</div>
</li>
<li><div> Choose “Add to SceneComposer”</div>
</li>
</ol>
<p>
Note that when importing a model the texture paths are stored absolute, so the folder you import the model from will later only be a textures folder because the original model file is not included in the release.
</p>
<p>
Also note that when adding models this way, changes in the original model file will not be reflected in the scene file as its a complete copy of the original file. If you change the original model, delete the models node from the scene and import it again.
</p>
</div>
<h3><a>Linking Models to the scene</a></h3>
<div>
<p>
You can also link models/objects into your scene, this way they are reloaded dynamically from the other/original file.
</p>
<ol>
<li><div> Place the SceneComposer cursor where you want the model to be</div>
</li>
<li><div> Select the parent Node for the model in the SceneExplorer</div>
</li>
<li><div> In the Project Explorer right-click the model file you want to link</div>
</li>
<li><div> Choose “Link in SceneComposer”</div>
</li>
</ol>
<p>
Note that when linking objects this way, you cannot edit them as part of the scene. To change the model you have to change the original j3o file.
</p>
<p>
Also note that although it its possible to directly link external model files (OgreXML, OBJ etc.), this is not recommended. Convert the original file to a j3o file by right-clicking it and selecting “Convert to jME Binary” before linking it. This is required because the original model files are not included in the release version of the application.
</p>
</div>
<h3><a>Saving the Scene</a></h3>
<div>
<ol>
<li><div> When a scene has been changed, press the “save” button in the main toolbar or press [Ctrl-S] / [Apple-S] to save it.</div>
</li>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:scene_composer?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:scene_composer?do=export_xhtmlbody">view online version</a></em></p>

@ -1,65 +1,26 @@
<h1><a
<h1><a>jMonkeyPlatform: Scene Explorer</a></h1> name="jmonkeyplatformscene_explorer">jMonkeyPlatform: Scene Explorer</a></h1><div
<div> class="level1"></div><h2><a
name="about_the_sceneexplorer_window">About the SceneExplorer window</a></h2><div
</div> class="level2"><p> The SceneExplorer gives you a structural overview of the currently edited scene and is active among all plugins</p><p> Most plugins will deliver their own UI elements to modify the scene so the SceneExplorer is more of a global tool. The simple SceneComposer however heavily relies on its functions as other plugins might too in the future.</p></div><h2><a
name="using_the_sceneexplorer">Using the SceneExplorer</a></h2><div
<h2><a>About the SceneExplorer window</a></h2> class="level2"><p> <a
<div> href="/wiki/lib/exe/detail.php/sdk:jmonkeyplatform-sceneexplorer-add.jpg?id=sdk%3Ascene_explorer"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-sceneexplorer-add.jpg" class="mediaright" align="right" title="jmonkeyplatform-sceneexplorer-add.jpg" alt="jmonkeyplatform-sceneexplorer-add.jpg" /></a> The SceneExplorer displays Nodes in a tree that represents the tree of Spatials in your scene. Spatial controls, lights and geometry meshes are also displayed in the tree.</p></div><h3><a
<p> name="editing_objects_in_the_scene">Editing Objects in the scene</a></h3><div
The SceneExplorer gives you a structural overview of the currently edited scene and is active among all plugins class="level3"><ol><li
</p> class="level1"><div
class="li"> Select a node in the SceneExplorer window (Open via Window→SceneExplorer if not open)</div></li><li
<p> class="level1"><div
Most plugins will deliver their own UI elements to modify the scene so the SceneExplorer is more of a global tool. The simple SceneComposer however heavily relies on its functions as other plugins might too in the future. class="li"> Edit the node in the Properties window (Open via Window→Properties if not open)</div></li><li
class="level1"><div
</p> class="li"> You can rename a Spatial by right clicking it or by slowly double-clicking the node</div></li></ol></div><h3><a
name="reorganizing_objects_in_the_scene">Reorganizing Objects in the scene</a></h3><div
</div> class="level3"><ol><li
class="level1"><div
<h2><a>Using the SceneExplorer</a></h2> class="li"> You can cut, copy and paste Nodes in the SceneExplorer with the normal keyboard commands or the right-click menu of the Nodes</div></li><li
<div> class="level1"><div
class="li"> You can move single object within the SceneExplorer tree by dragging&amp;dropping them</div></li></ol></div><h3><a
<p> name="adding_objects_to_the_scene">Adding Objects to the scene</a></h3><div
class="level3"><p> Right-click a Spatial or Node in the SceneExplorer to add other Spatials like ParticleEmitters or Lights, you can also add UserData to a Spatial that can be read during runtime.</p></div>
<img src="nbdocs:/com/jme3/gde/core/docs/sdk/jmonkeyplatform-sceneexplorer-add.jpg">
The SceneExplorer displays Nodes in a tree that represents the tree of Spatials in your scene. Spatial controls, lights and geometry meshes are also displayed in the tree.
</p>
</div>
<h3><a>Editing Objects in the scene</a></h3>
<div>
<ol>
<li><div> Select a node in the SceneExplorer window (Open via Window→SceneExplorer if not open)</div>
</li>
<li><div> Edit the node in the Properties window (Open via Window→Properties if not open)</div>
</li>
<li><div> You can rename a Spatial by right clicking it or by slowly double-clicking the node</div>
</li>
</ol>
</div>
<h3><a>Reorganizing Objects in the scene</a></h3>
<div>
<ol>
<li><div> You can cut, copy and paste Nodes in the SceneExplorer with the normal keyboard commands or the right-click menu of the Nodes</div>
</li>
<li><div> You can move single object within the SceneExplorer tree by dragging&amp;dropping them</div>
</li>
</ol>
</div>
<h3><a>Adding Objects to the scene</a></h3>
<div>
<p>
Right-click a Spatial or Node in the SceneExplorer to add other Spatials like ParticleEmitters or Lights, you can also add UserData to a Spatial that can be read during runtime.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:scene_explorer?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:scene_explorer?do=export_xhtmlbody">view online version</a></em></p>

@ -1,162 +1,74 @@
<h1><a
<h1><a>Overview</a></h1> name="overview">Overview</a></h1><div
<div> class="level1"><p> The terrain lets you create, modify, and paint terrain.</p></div><h1><a
name="controls">Controls</a></h1><div
<p> class="level1"><p> Terrain controls are the same as the Scene Composer, you rotate the camera with the left mouse button and pan the camera with the right mouse button. Until you select one of the terrain tools in the toolbar, then the controls change for that tool. Then left mouse button will use that tool: painting, raising/lowering terrain, etc. The right mouse button might do something, depending on the tool.</p></div><h1><a
The terrain lets you create, modify, and paint terrain. name="add_light_to_your_scene">Add light to your scene</a></h1><div
</p> class="level1"><p> In order to see the terrain, you will need to add light to your scene. To do this you will need to head to the Scene Composer:<br/> <a
href="/wiki/lib/exe/detail.php/sdk:tut-selectscenecomposer.png?id=sdk%3Aterrain_editor"><img
</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/tut-selectscenecomposer.png" class="media" alt="" /></a><br/> Then, from the Palette list, select &#039;Directional Light&#039;<br/> <a
href="/wiki/lib/exe/detail.php/sdk:tut-scenecomposerdirlight.png?id=sdk%3Aterrain_editor"><img
<h1><a>Controls</a></h1> src="nbdocs:/com/jme3/gde/core/docs/sdk/tut-scenecomposerdirlight.png" class="media" alt="" /></a><br/> Then, hit the &#039;add selected item&#039; button.<br/> <a
<div> href="/wiki/lib/exe/detail.php/sdk:tut-scenecomposeradd.png?id=sdk%3Aterrain_editor"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/tut-scenecomposeradd.png" class="media" alt="" /></a><br/> Save your scene.<br/> You now have light in your scene and will be able to see your terrain.</p></div><h1><a
<p> name="creating_terrain">Creating Terrain</a></h1><div
Terrain controls are the same as the Scene Composer, you rotate the camera with the left mouse button and pan the camera with the right mouse button. Until you select one of the terrain tools in the toolbar, then the controls change for that tool. Then left mouse button will use that tool: painting, raising/lowering terrain, etc. The right mouse button might do something, depending on the tool. class="level1"><p> To create terrain, first select a node (probably your root node) in your scene.<br/> <a
</p> href="/wiki/lib/exe/detail.php/sdk:tut-selectnode.png?id=sdk%3Aterrain_editor"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/tut-selectnode.png" class="media" alt="" /></a><br/> Then click the add terrain button.<br/> <a
</div> href="/wiki/lib/exe/detail.php/sdk:tut-addterrain.png?id=sdk%3Aterrain_editor"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/tut-addterrain.png" class="media" alt="" /></a><br/> This will pop up the Create Terrain wizard that will walk you through the steps for creating terrain. Make sure you decide now how large you want your terrain to be and how detailed you want the textures to be as you cannot change it later on!</p></div><h5><a
<h1><a>Creating Terrain</a></h1> name="step_1terrain_size">Step 1: Terrain Size</a></h5><div
<div> class="level5"><p> Here you determine the size of your terrain, the total size and the patch size. You should probably leave the patch size alone. But the total size should be defined; this is how big your terrain is.</p></div><h5><a
name="step_2heightmap">Step 2: Heightmap</a></h5><div
<p> class="level5"><p> Here you can select a heightmap generation technique to give you a default/random look of the terrain. You can also select a heightmap image to pre-define how your terrain looks.
To create terrain, first select a node (probably your root node) in your scene. Then click the add terrain button. By default, it will give you a flat terrain.</p></div><h5><a
This will pop up the Create Terrain wizard that will walk you through the steps for creating terrain. Make sure you decide now how large you want your terrain to be and how detailed you want the textures to be as you cannot change it later on! name="step_3alpha_image_detail">Step 3: Alpha Image Detail</a></h5><div
</p> class="level5"><p> This step determines how large the alpha blend images are for your terrain. The smaller the alpha image, the less detailed you can paint the terrain. Play around with this to see how big you need it to be. Remember that terrain does not have to be that detailed, and is often covered by vegetation, rocks, and other items. So having a really detailed texture is not always necessary.</p></div><h1><a
name="modifying_terrain">Modifying Terrain</a></h1><div
</div> class="level1"><p> Right now there are two terrain modification tools: raise and lower terrain.<br/> <a
href="/wiki/lib/exe/detail.php/sdk:terrain-raise-lower.png?id=sdk%3Aterrain_editor"><img
<h5><a>Step 1: Terrain Size</a></h5> src="nbdocs:/com/jme3/gde/core/docs/sdk/terrain-raise-lower.png" class="media" alt="" /></a><br/> There are two sliders that affect how these tools operate:</p><ul><li
<div> class="level1"><div
class="li"> Radius: how big the brush is</div></li><li
<p> class="level1"><div
Here you determine the size of your terrain, the total size and the patch size. You should probably leave the patch size alone. But the total size should be defined; this is how big your terrain is. class="li"> Weight/Height: how much impact the brush has</div></li></ul><p> Once a tool is selected, you will see the tool marker (now an ugly wire sphere) on the map where your mouse is. Click and drag on the terrain to see the tool change the height of the terrain.</p></div><h1><a
</p> name="painting_terrain">Painting Terrain</a></h1><div
class="level1"><p> Your terrain comes with one diffuse default texture, and you can have up to 12 total diffuse textures. It also allows you to add normal maps to each texture layer.
</div>
<h5><a>Step 2: Heightmap</a></h5>
<div>
<p>
Here you can select a heightmap generation technique to give you a default/random look of the terrain. You can also select a heightmap image to pre-define how your terrain looks.
By default, it will give you a flat terrain.
</p>
</div>
<h5><a>Step 3: Alpha Image Detail</a></h5>
<div>
<p>
This step determines how large the alpha blend images are for your terrain. The smaller the alpha image, the less detailed you can paint the terrain. Play around with this to see how big you need it to be. Remember that terrain does not have to be that detailed, and is often covered by vegetation, rocks, and other items. So having a really detailed texture is not always necessary.
</p>
</div>
<h1><a>Modifying Terrain</a></h1>
<div>
<p>
Right now there are two terrain modification tools: raise and lower terrain.
There are two sliders that affect how these tools operate:
</p>
<ul>
<li><div> Radius: how big the brush is</div>
</li>
<li><div> Weight/Height: how much impact the brush has</div>
</li>
</ul>
<p>
Once a tool is selected, you will see the tool marker (now an ugly wire sphere) on the map where your mouse is. Click and drag on the terrain to see the tool change the height of the terrain.
</p>
</div>
<h1><a>Painting Terrain</a></h1>
<div>
<p>
Your terrain comes with one diffuse default texture, and you can have up to 12 total diffuse textures. It also allows you to add normal maps to each texture layer.
All of the textures can be controlled in the Texture Layer table by clicking on the textures. All of the textures can be controlled in the Texture Layer table by clicking on the textures.
</p> There are two sliders that affect how the paint tool operates:</p><ul><li
class="level1"><div
<p> class="li"> Radius: how big the brush is</div></li><li
There are two sliders that affect how the paint tool operates: class="level1"><div
</p> class="li"> Weight/Height: how much impact the brush has</div></li></ul></div><h5><a
<ul> name="adding_a_new_texture_layer">Adding a new texture layer</a></h5><div
<li><div> Radius: how big the brush is</div> class="level5"><p> Adds a new texture layer to the terrain. The will be drawn over top of the other texture layers listed above it in the list.<br/> <a
</li> href="/wiki/lib/exe/detail.php/sdk:terrain-addtexture.png?id=sdk%3Aterrain_editor"><img
<li><div> Weight/Height: how much impact the brush has</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/terrain-addtexture.png" class="media" alt="" /></a><br/></p></div><h5><a
</li> name="changing_the_diffuse_texture">Changing the diffuse texture</a></h5><div
</ul> class="level5"><p> Click on the diffuse texture image in the texture table. This will pop up a window with the available textures in your assets directory.<br/> <a
href="/wiki/lib/exe/detail.php/sdk:terrain-editdiffuse.png?id=sdk%3Aterrain_editor"><img
</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/terrain-editdiffuse.png" class="media" alt="" /></a><br/></p></div><h5><a
name="adding_a_normal_map_to_the_texture_layer">Adding a normal map to the texture layer</a></h5><div
<h5><a>Adding a new texture layer</a></h5> class="level5"><p> When you add a texture layer, by default it does not add a normal map for you. To add one, click on the button next to the diffuse texture for that texture layer. This will pop up the texture browser. Select a texture and hit Ok, and you are done.<br/> <a
<div> href="/wiki/lib/exe/detail.php/sdk:terrain-addnormaltexture.png?id=sdk%3Aterrain_editor"><img
src="nbdocs:/com/jme3/gde/core/docs/sdk/terrain-addnormaltexture.png" class="media" alt="" /></a><br/></p></div><h5><a
</div> name="removing_a_normal_map_from_the_texture_layer">Removing a normal map from the texture layer</a></h5><div
class="level5"><p> To remove a normal map from the texture layer, hit the normal map button for that texture layer again, and deselect the texture. Then hit Ok and the texture should be removed.</p></div><h5><a
<h5><a>Changing the diffuse texture</a></h5> name="changing_the_texture_scale">Changing the texture scale</a></h5><div
<div> class="level5"><p> The field in the table to the right of the diffuse and normal textures for your texture layer is the scale. Changing that value changes the scale of the texture.<br/> <a
href="/wiki/lib/exe/detail.php/sdk:terrain-texturescale.png?id=sdk%3Aterrain_editor"><img
</div> src="nbdocs:/com/jme3/gde/core/docs/sdk/terrain-texturescale.png" class="media" alt="" /></a><br/> You will notice that the scale changes when you switch between Tri-Planar and normal texture mapping. Tri-planar mapping does not use the texture coordinates of the geometry, but real world coordinates. And because of this, in order for the texture to look the same when you switch between the two texture mapping methods, the terrain editor will automatically convert the scales for you.
Essentially if your scale in normal texture coordinates is 16, then for tri-planar gets converted like this: 1/terrainSize/16</p></div><h5><a
<h5><a>Adding a normal map to the texture layer</a></h5> name="tri-planar_texture_mapping">Tri-planar texture mapping</a></h5><div
<div> class="level5"><p> Tri-planar texture mapping is recommended if you have lots of near-vertical terrain. With normal texture mapping the textures can look stretched because it is rendered on the one plane: X-Z. Tri-planar mapping renders the textures on three planes: X-Z, X-Y, Z-Y; and blends them together based on what plane the normal of the triangle is facing most on.
</div>
<h5><a>Removing a normal map from the texture layer</a></h5>
<div>
</div>
<h5><a>Changing the texture scale</a></h5>
<div>
<p>
The field in the table to the right of the diffuse and normal textures for your texture layer is the scale. Changing that value changes the scale of the texture.
You will notice that the scale changes when you switch between Tri-Planar and normal texture mapping. Tri-planar mapping does not use the texture coordinates of the geometry, but real world coordinates. And because of this, in order for the texture to look the same when you switch between the two texture mapping methods, the terrain editor will automatically convert the scales for you.
Essentially if your scale in normal texture coordinates is 16, then for tri-planar gets converted like this: 1/terrainSize/16
</p>
</div>
<h5><a>Tri-planar texture mapping</a></h5>
<div>
<p>
Tri-planar texture mapping is recommended if you have lots of near-vertical terrain. With normal texture mapping the textures can look stretched because it is rendered on the one plane: X-Z. Tri-planar mapping renders the textures on three planes: X-Z, X-Y, Z-Y; and blends them together based on what plane the normal of the triangle is facing most on.
This makes the terrain look much better, but it does have a performance hit! This makes the terrain look much better, but it does have a performance hit!
Here is an article on tri-planar mapping: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html"><param name="text" value="<html><u>http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html</u></html>"><param name="textColor" value="blue"></object> Here is an article on tri-planar mapping: <a
</p> href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html">http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html</a></p></div><h5><a
name="total_texture_count">Total texture count</a></h5><div
</div> class="level5"><p> Terrain will support a maximum of 12 diffuse texture. And a combined total of 13 diffuse and normal maps.
Most video cards are limited to 16 texture units (textures), and 3 are used behind the scenes of the terrain material for alpha blending of the textures, so you are left with a maximum of 13 textures.</p></div><h1><a
<h5><a>Total texture count</a></h5> name="generating_terrain_entropies_for_lod">Generating Terrain Entropies for LOD</a></h1><div
<div> class="level1"><p> If you are using the recommended PerspectiveLodCalculator for calculating LOD levels of the terrain, then you will want to pre-generate the entropy levels for the terrain. This is a slow process. If they are not pre-generated, the LOD control will generate them for you, but this will lag the user when they load the scene, and the terrain will flicker.
<p>
Terrain will support a maximum of 12 diffuse texture. And a combined total of 13 diffuse and normal maps.
Most video cards are limited to 16 texture units (textures), and 3 are used behind the scenes of the terrain material for alpha blending of the textures, so you are left with a maximum of 13 textures.
</p>
</div>
<h1><a>Generating Terrain Entropies for LOD</a></h1>
<div>
<p>
If you are using the recommended PerspectiveLodCalculator for calculating LOD levels of the terrain, then you will want to pre-generate the entropy levels for the terrain. This is a slow process. If they are not pre-generated, the LOD control will generate them for you, but this will lag the user when they load the scene, and the terrain will flicker.
Use the &#039;Generate Entropies&#039; button to pre-generate the entropies for the terrain, they will be saved with it. Use the &#039;Generate Entropies&#039; button to pre-generate the entropies for the terrain, they will be saved with it.
Note that whenever you modify the height of the terrain, you should re-generate the entropies. Of course, don&#039;t do this every time, but maybe just before you are ready to send the map out for testing. Note that whenever you modify the height of the terrain, you should re-generate the entropies. Of course, don&#039;t do this every time, but maybe just before you are ready to send the map out for testing.</p></div>
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:terrain_editor?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:terrain_editor?do=export_xhtmlbody">view online version</a></em></p>

@ -1,17 +1,8 @@
<h2><a
<h2><a>Troubleshooting jMonkeyEngine3 SDK</a></h2> name="troubleshooting_jmonkeyengine3_sdk">Troubleshooting jMonkeyEngine3 SDK</a></h2><div
<div> class="level2"></div><h3><a
name="specifying_the_jdk_location">Specifying the JDK location</a></h3><div
</div> class="level3"><p> If jMonkeyPlatform cannot find a valid <acronym
title="Java Development Kit">JDK</acronym> although you have it installed you have to specify the location manually.
<h3><a>Specifying the JDK location</a></h3> To do that edit the file <code>jmonkeyplatform.conf</code> in the <code>etc</code> directory of your jMonkeyPlatform installation location. Mac users have to right-click the application and select &quot;Show package contents&quot; and then navigate to <code>Contents/Resources/jmonkeyplatform</code>.</p></div>
<div>
<p>
If jMonkeyPlatform cannot find a valid <acronym title="Java Development Kit">JDK</acronym> although you have it installed you have to specify the location manually.
To do that edit the file <code>jmonkeyplatform.conf</code> in the <code>etc</code> directory of your jMonkeyPlatform installation location. Mac users have to right-click the application and select “Show package contents” and then navigate to <code>Contents/Resources/jmonkeyplatform</code>.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:troubleshooting?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:troubleshooting?do=export_xhtmlbody">view online version</a></em></p>

@ -1,38 +1,35 @@
<h2><a
<h2><a>How to integrate your own jME3 compile in jMP projects</a></h2> name="how_to_integrate_your_own_jme3_compile_in_jmp_projects">How to integrate your own jME3 compile in jMP projects</a></h2><div
<div> class="level2"><ol><li
<ol> class="level1"><div
<li><div> <a href="/com/jme3/gde/core/docs/jme3/build_jme3_sources_with_netbeans.html">Download jme3 project from svn</a></div> class="li"> <a
</li> href="/com/jme3/gde/core/docs/jme3/build_jme3_sources_with_netbeans.html">Download jme3 project from svn</a></div></li><li
<li><div> Make your changes</div> class="level1"><div
</li> class="li"> Make your changes</div></li><li
<li><div> Compile jme3 project</div> class="level1"><div
</li> class="li"> Compile jme3 project</div></li><li
<li><div> Go to Tools → Libraries</div> class="level1"><div
</li> class="li"> Go to Tools → Libraries</div></li><li
<li><div> Press “New Library”</div> class="level1"><div
</li> class="li"> Press &quot;New Library&quot;</div></li><li
<li><div> Name it “jme3-modified”</div> class="level1"><div
</li> class="li"> Name it &quot;jme3-modified&quot;</div></li><li
<li><div> Press “Add Jar/Folder”</div> class="level1"><div
</li> class="li"> Press &quot;Add Jar/Folder&quot;</div></li><li
<li><div> Select <code>jMonkeyEngine3.jar</code> from the <code>dist</code> dir of the compiled jme3 version</div> class="level1"><div
</li> class="li"> Select <code>jMonkeyEngine3.jar</code> from the <code>dist</code> dir of the compiled jme3 version</div></li><li
<li><div> Add the <code>src</code> folder of the jme3 project in the “sources” tab</div> class="level1"><div
</li> class="li"> Add the <code>src</code> folder of the jme3 project in the &quot;sources&quot; tab</div></li><li
<li><div> Optionally javadoc in the “javadoc” tab</div> class="level1"><div
</li> class="li"> Optionally javadoc in the &quot;javadoc&quot; tab</div></li><li
<li><div> Press “OK”</div> class="level1"><div
</li> class="li"> Press &quot;OK&quot;</div></li><li
<li><div> Right-click your project and select “Properties”</div> class="level1"><div
</li> class="li"> Right-click your project and select &quot;Properties&quot;</div></li><li
<li><div> Select “Libraries” to the left</div> class="level1"><div
</li> class="li"> Select &quot;Libraries&quot; to the left</div></li><li
<li><div> Remove the “jme3” library</div> class="level1"><div
</li> class="li"> Remove the &quot;jme3&quot; library</div></li><li
<li><div> Press “Add Library” and select the “jme3-modified” library</div> class="level1"><div
</li> class="li"> Press &quot;Add Library&quot; and select the &quot;jme3-modified&quot; library</div></li></ol></div>
</ol>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:use_own_jme?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:use_own_jme?do=export_xhtmlbody">view online version</a></em></p>

@ -1,46 +1,16 @@
<h2><a
<h2><a>Vehicle Creator</a></h2> name="vehicle_creator">Vehicle Creator</a></h2><div
<div> class="level2"><p> Best results when car is facing in z direction (towards you)</p><p> Usage:</p><ol><li
class="level1"><div
<p> class="li"> Select a j3o that contains a vehicle model and press the vehicle button (or right-click → edit vehicle)</div></li><li
class="level1"><div
Best results when car is facing in z direction (towards you) class="li"> The VehicleCreator automatically adds a PhysicsVehicleControl to the rootNode of the model if there is none</div></li><li
</p> class="level1"><div
class="li"> Select the Geometry or Node that contains the chassis in the SceneExplorer and press &quot;create hull shape from selected&quot;</div></li><li
<p> class="level1"><div
Usage: class="li"> Select a Geometry that contains a wheel and press &quot;make selected spatial wheel&quot;, select the &quot;front wheel&quot; checkboxes for front wheels</div></li><li
</p> class="level1"><div
<ol> class="li"> Do so for all wheels</div></li></ol><p> New wheels will get the current suspension settings, you can edit single wheels via the SceneExplorer (update VehicleControl if wheels dont show up) or apply settings created with the settings generator to wheel groups.</p><p> Press the &quot;test vehicle&quot; button to drive the vehicle, use WASD to control, Enter to reset.</p><p> Known Issues: Dont save while testing the vehicle, you will save the location and acceleration info in the j3o.</p><p> Code Example to load vehicle:</p><pre>//load vehicle and access VehicleControl
<li><div> Select a j3o that contains a vehicle model and press the vehicle button (or right-click → edit vehicle)</div>
</li>
<li><div> The VehicleCreator automatically adds a PhysicsVehicleControl to the rootNode of the model if there is none</div>
</li>
<li><div> Select the Geometry or Node that contains the chassis in the SceneExplorer and press “create hull shape from selected”</div>
</li>
<li><div> Select a Geometry that contains a wheel and press “make selected spatial wheel”, select the “front wheel” checkboxes for front wheels</div>
</li>
<li><div> Do so for all wheels</div>
</li>
</ol>
<p>
New wheels will get the current suspension settings, you can edit single wheels via the SceneExplorer (update VehicleControl if wheels dont show up) or apply settings created with the settings generator to wheel groups.
</p>
<p>
Press the “test vehicle” button to drive the vehicle, use WASD to control, Enter to reset.
</p>
<p>
Known Issues: Dont save while testing the vehicle, you will save the location and acceleration info in the j3o.
</p>
<p>
Code Example to load vehicle:
</p>
<pre>//load vehicle and access VehicleControl
Spatial car=assetManager.loadModel&#40;&quot;Models/MyCar.j3o&quot;&#41;; Spatial car=assetManager.loadModel&#40;&quot;Models/MyCar.j3o&quot;&#41;;
VehicleControl control=car.getControl&#40;VehicleControl.class&#41;; VehicleControl control=car.getControl&#40;VehicleControl.class&#41;;
rootNode.attachChild&#40;car&#41;; rootNode.attachChild&#40;car&#41;;
@ -48,6 +18,5 @@ physicsSpace.add&#40;control&#41;;
   
//then use the control to control the vehicle: //then use the control to control the vehicle:
control.setPhysicsLocation&#40;new Vector3f&#40;10,2,10&#41;&#41;; control.setPhysicsLocation&#40;new Vector3f&#40;10,2,10&#41;&#41;;
control.accelerate&#40;100&#41;;</pre> control.accelerate&#40;100&#41;;</pre></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:vehicle_creator?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:vehicle_creator?do=export_xhtmlbody">view online version</a></em></p>

@ -1,214 +1,100 @@
<h1><a
<h1><a>jMonkeyPlatform: Version Control</a></h1> name="jmonkeyplatformversion_control">jMonkeyPlatform: Version Control</a></h1><div
<div> class="level1"><p> Whether you work in a development team or alone: File versioning is a handy method to keep your code consistent, compare files line-by-line, and even roll back unwanted changes. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s integrated version control features for Subversion, Mercurial, and <acronym
title="Concurrent Versions System">CVS</acronym>.</p><p> <br/></p><p> Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the &quot;see also links&quot;).</p></div><h2><a
<p> name="version_control_systems">Version Control Systems</a></h2><div
class="level2"><p> The jMonkeyPlatform supports various Version Control Systems such as Subversion, Mercurial, and <acronym
Whether you work in a development team or alone: File versioning is a handy method to keep your code consistent, compare files line-by-line, and even roll back unwanted changes. This documentation shows you how to make the most of the jMonkeyPlatform&#039;s integrated version control features for Subversion, Mercurial, and <acronym title="Concurrent Versions System">CVS</acronym>. title="Concurrent Versions System">CVS</acronym>. No matter which of them you use, they all share a common user interface.</p><p> You can use file versioning alone or in a team. The advantages are that you can keep track of changes (who did it, when, and why), you can compare versions line-by-line, you can revert changes to files and lines, merge multiple changes to one file, and you can even undelete files.</p></div><h2><a
</p> name="creating_a_repository_upload">Creating a Repository (Upload)</a></h2><div
class="level2"><p> Requirements:</p><ul><li
<p> class="level1"><div
<br/> class="li"> You must have a project that you want to version.</div></li><li
class="level1"><div
</p> class="li"> You must have version control software installed (Subversion, Mercurial, or <acronym
title="Concurrent Versions System">CVS</acronym>) and have initialized a repository.</div><ul><li
<p> class="level2"><div
Note: Since the jMonkeyPlatform is based on the NetBeans Platform framework, you can learn about certain jMonkeyPlatform features by reading the corresponding NetBeans IDE tutorials (in the “see also links”). class="li"> Tip: For Subversion, the init command looks like this example: <code>svnadmin create /home/joe/mysvnrepo</code></div></li></ul></li><li
</p> class="level1"><div
class="li"> The computer where the repository is to be hosted must be available in your network, or you will only be able to use your repo locally.</div><ul><li
</div> class="level2"><div
class="li"> Tip: Hosts such as SourceForge, GoogleCode, dev.java.net offer free version control services for open-source projects.</div></li></ul></li></ul><p> Now you create a repository to store your project&#039;s files.</p><ol><li
<h2><a>Version Control Systems</a></h2> class="level1"><div
<div> class="li"> In the jMonkeyPlatform, right-click the project in the Projects window and choose Versioning &gt; Import Into <acronym
title="Concurrent Versions System">CVS</acronym>/Subversion Repository (or initialize Mercurial Project, respectively).</div><ul><li
<p> class="level2"><div
class="li"> Tip: If you haven&#039;t evaluated yet which system to choose, start with Subversion for now.</div></li></ul></li><li
The jMonkeyPlatform supports various Version Control Systems such as Subversion, Mercurial, and <acronym title="Concurrent Versions System">CVS</acronym>. No matter which of them you use, they all share a common user interface. class="level1"><div
</p> class="li"> Go through the wizard and fill in the fields to set up the repository.</div></li></ol></div><h2><a
name="checking_out_a_repository_download">Checking Out a Repository (Download)</a></h2><div
<p> class="level2"><p> You and your team mates check out (download) the repository to their individual workstations.</p><ol><li
You can use file versioning alone or in a team. The advantages are that you can keep track of changes (who did it, when, and why), you can compare versions line-by-line, you can revert changes to files and lines, merge multiple changes to one file, and you can even undelete files. class="level1"><div
</p> class="li"> Go to the Team menu and choose Subversion &gt; Checkout (or <acronym
title="Concurrent Versions System">CVS</acronym>/Mercurial&gt;Checkout respectively)</div></li><li
</div> class="level1"><div
class="li"> Fill in your repo data into the wizard and click Finish.</div><ul><li
<h2><a>Creating a Repository (Upload)</a></h2> class="level2"><div
<div> class="li"> A typical repository <acronym
title="Uniform Resource Locator">URL</acronym> looks like this example: <code><a
<p> href="http://jmonkeyengine.googlecode.com/svn/trunk/engine">http://jmonkeyengine.googlecode.com/svn/trunk/engine</a></code></div></li><li
class="level2"><div
Requirements: class="li"> If you want to be able to submit changes, you must have a username and password to this repository. Otherwise leave these fields blank.</div></li></ul></li><li
</p> class="level1"><div
<ul> class="li"> The repository is downloaded and stored in the location you chose.</div></li><li
<li><div> You must have a project that you want to version. </div> class="level1"><div
</li> class="li"> Use the File &gt; Open Project menu to open the checkout as project and start working.</div><ul><li
<li><div> You must have version control software installed (Subversion, Mercurial, or <acronym title="Concurrent Versions System">CVS</acronym>) and have initialized a repository.</div> class="level2"><div
<ul> class="li"> If the checkout is not recognized you need to choose File &gt; New Project from Existing Sources</div></li></ul></li></ol><p> <br/> Of course you can also check out existing repositories and access code from other open-source projects (e.g. SourceForge, GoogleCode, dev.java.net).</p></div><h2><a
<li><div> Tip: For Subversion, the init command looks like this example: <code>svnadmin create /home/joe/mysvnrepo</code></div> name="updating_and_committing_changes_send_and_receive">Updating and Committing Changes (Send and Receive)</a></h2><div
</li> class="level2"><p> Receiving the latest changes from the team&#039;s repository is referred to as <code>updating</code>. Sending your changes to the team&#039;s repository is refered to as <code>commiting</code>.</p><ol><li
</ul> class="level1"><div
</li> class="li"> Before making changes, right-click the project and select Subversion &gt; Update to make sure you have the latest revision.</div><ul><li
<li><div> The computer where the repository is to be hosted must be available in your network, or you will only be able to use your repo locally.</div> class="level2"><div
<ul> class="li"> Get in the habit of updating regularly, always before you edit a version controlled file. It will spare you much grief.</div></li></ul></li><li
<li><div> Tip: Hosts such as SourceForge, GoogleCode, dev.java.net offer free version control services for open-source projects.</div> class="level1"><div
</li> class="li"> After making changes to the project, make certain your change did not break anything.</div><ol><li
</ul> class="level2"><div
</li> class="li"> Update, build, run, test.</div></li><li
</ul> class="level2"><div
class="li"> Look at the red/green/blue marks in the editor to review what you have deleted/added/changed. Click the marks to review all differences in a file.</div></li><li
<p> class="level2"><div
class="li"> Choose Subversion &gt; Show Changes to see all files that were recently changed – by you and other team members.</div></li><li
Now you create a repository to store your project&#039;s files. class="level2"><div
class="li"> <em>Update again</em> in case your team mates made changes while you were reviewing.</div></li></ol></li><li
</p> class="level1"><div
<ol> class="li"> If there are no conflicts and you want to commit your changes, choose Subversion &gt; Commit from the menu.</div></li><li
<li><div> In the jMonkeyPlatform, right-click the project in the Projects window and choose Versioning &gt; Import Into <acronym title="Concurrent Versions System">CVS</acronym>/Subversion Repository (or initialize Mercurial Project, respectively). </div> class="level1"><div
<ul> class="li"> Write a commit message describing what you changed.</div><ul><li
<li><div> Tip: If you haven&#039;t evaluated yet which system to choose, start with Subversion for now.</div> class="level2"><div
</li> class="li"> Remember, you are writing &quot;a message to your future self&quot;. Never write redundant stuff like &quot;I changed something&quot;.</div></li></ul></li></ol></div><h2><a
</ul> name="comparing_and_reverting_changes">Comparing and Reverting Changes</a></h2><div
</li> class="level2"><ul><li
<li><div> Go through the wizard and fill in the fields to set up the repository.</div> class="level1"><div
</li> class="li"> If you and another committer edited the same line, there is a conflict, and the jMonkeyPlatform will show an error message.</div><ul><li
</ol> class="level2"><div
class="li"> Right-click a file Choose Subversion &gt; Resolve Conflict</div><ol><li
</div> class="level3"><div
class="li"> Compare the conflicting versions. Press the buttons to accept or reject each change individually.</div></li><li
<h2><a>Checking Out a Repository (Download)</a></h2> class="level3"><div
<div> class="li"> After the resolver shows green, save the resolution.</div></li><li
class="level3"><div
<p> class="li"> Build and test the resolution, update, and commit.</div></li></ol></li></ul></li><li
class="level1"><div
You and your team mates check out (download) the repository to their individual workstations. class="li"> Right-click a file and choose Subversion &gt; Search History.</div><ul><li
class="level2"><div
</p> class="li"> You can inspect a file&#039;s history and see who changed what, why, and when.</div></li><li
<ol> class="level2"><div
<li><div> Go to the Team menu and choose Subversion &gt; Checkout (or <acronym title="Concurrent Versions System">CVS</acronym>/Mercurial&gt;Checkout respectively)</div> class="li"> You can roll back a file to a historic version if necessary.</div></li></ul></li><li
</li> class="level1"><div
<li><div> Fill in your repo data into the wizard and click Finish.</div> class="li"> In general, you can choose Subversion &gt; Diff for any file to see two versions of a file next to each other.</div></li></ul></div><h2><a
<ul> name="no_version_control_local_history">No Version Control? Local History!</a></h2><div
<li><div> A typical repository <acronym title="Uniform Resource Locator">URL</acronym> looks like this example: <code><object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://jmonkeyengine.googlecode.com/svn/trunk/engine"><param name="text" value="<html><u>http://jmonkeyengine.googlecode.com/svn/trunk/engine</u></html>"><param name="textColor" value="blue"></object></code></div> class="level2"><p> If you do not use any version control, you can still track changes in projects to a certain degree.</p><ul><li
</li> class="level1"><div
<li><div> If you want to be able to submit changes, you must have a username and password to this repository. Otherwise leave these fields blank.</div> class="li"> Right-click a file or directory and choose Local History to show or revert changes, or undelete files.</div></li><li
</li> class="level1"><div
</ul> class="li"> You can also select any two files in the Project window and choose Tools &gt; Diff to compare them.</div></li><li
</li> class="level1"><div
<li><div> The repository is downloaded and stored in the location you chose. </div> class="li"> Local History only works for files edited in jMonkeyPlatform Projects (It does not work for other files, e.g. in the Favorites window.)</div></li></ul><p> <br/> See also:</p><ul><li
</li> class="level1"><div
<li><div> Use the File &gt; Open Project menu to open the checkout as project and start working. </div> class="li"> <a
<ul> href="http://netbeans.org/kb/docs/ide/subversion.html">Source Code Management with Subversion</a></div></li></ul></div>
<li><div> If the checkout is not recognized you need to choose File &gt; New Project from Existing Sources</div>
</li>
</ul>
</li>
</ol>
<p>
<br/>
Of course you can also check out existing repositories and access code from other open-source projects (e.g. SourceForge, GoogleCode, dev.java.net).
</p>
</div>
<h2><a>Updating and Committing Changes (Send and Receive)</a></h2>
<div>
<p>
Receiving the latest changes from the team&#039;s repository is referred to as <code>updating</code>. Sending your changes to the team&#039;s repository is refered to as <code>commiting</code>.
</p>
<ol>
<li><div> Before making changes, right-click the project and select Subversion &gt; Update to make sure you have the latest revision.</div>
<ul>
<li><div> Get in the habit of updating regularly, always before you edit a version controlled file. It will spare you much grief.</div>
</li>
</ul>
</li>
<li><div> After making changes to the project, make certain your change did not break anything.</div>
<ol>
<li><div> Update, build, run, test.</div>
</li>
<li><div> Look at the red/green/blue marks in the editor to review what you have deleted/added/changed. Click the marks to review all differences in a file.</div>
</li>
<li><div> Choose Subversion &gt; Show Changes to see all files that were recently changed – by you and other team members. </div>
</li>
<li><div> <em>Update again</em> in case your team mates made changes while you were reviewing.</div>
</li>
</ol>
</li>
<li><div> If there are no conflicts and you want to commit your changes, choose Subversion &gt; Commit from the menu.</div>
</li>
<li><div> Write a commit message describing what you changed. </div>
<ul>
<li><div> Remember, you are writing “a message to your future self”. Never write redundant stuff like “I changed something”.</div>
</li>
</ul>
</li>
</ol>
</div>
<h2><a>Comparing and Reverting Changes</a></h2>
<div>
<ul>
<li><div> If you and another committer edited the same line, there is a conflict, and the jMonkeyPlatform will show an error message. </div>
<ul>
<li><div> Right-click a file Choose Subversion &gt; Resolve Conflict</div>
<ol>
<li><div> Compare the conflicting versions. Press the buttons to accept or reject each change individually. </div>
</li>
<li><div> After the resolver shows green, save the resolution.</div>
</li>
<li><div> Build and test the resolution, update, and commit.</div>
</li>
</ol>
</li>
</ul>
</li>
<li><div> Right-click a file and choose Subversion &gt; Search History.</div>
<ul>
<li><div> You can inspect a file&#039;s history and see who changed what, why, and when. </div>
</li>
<li><div> You can roll back a file to a historic version if necessary.</div>
</li>
</ul>
</li>
<li><div> In general, you can choose Subversion &gt; Diff for any file to see two versions of a file next to each other.</div>
</li>
</ul>
</div>
<h2><a>No Version Control? Local History!</a></h2>
<div>
<p>
If you do not use any version control, you can still track changes in projects to a certain degree.
</p>
<ul>
<li><div> Right-click a file or directory and choose Local History to show or revert changes, or undelete files.</div>
</li>
<li><div> You can also select any two files in the Project window and choose Tools &gt; Diff to compare them.</div>
</li>
<li><div> Local History only works for files edited in jMonkeyPlatform Projects (It does not work for other files, e.g. in the Favorites window.)</div>
</li>
</ul>
<p>
<br/>
See also:
</p>
<ul>
<li><div> <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://netbeans.org/kb/docs/ide/subversion.html"><param name="text" value="<html><u>Source Code Management with Subversion</u></html>"><param name="textColor" value="blue"></object></div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:version_control?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:version_control?do=export_xhtmlbody">view online version</a></em></p>

@ -1,39 +1,14 @@
<h1><a
<h1><a>Compression</a></h1> name="compression">Compression</a></h1><div
<div> class="level1"><p><p><div
class="notewarning">This article covers a deprecated <acronym
<p> title="Application Programming Interface">API</acronym>! See <a
<p><div>This article covers a deprecated <acronym title="Application Programming Interface">API</acronym>! See <a href="/com/jme3/gde/core/docs/jme3/advanced/networking.html">networking</a> for current documentation. href="/com/jme3/gde/core/docs/jme3/advanced/networking.html">networking</a> for current documentation.</div></p> Now this is going to be a real simply tutorial but still I wanted this in a separate article. Why you may ask? Simply because it&#039;s a feature that requires some explanation, since it has some caveats that I&#039;ll discuss. Also, I&#039;ll cover writing your own compression message.</p><p> First off - there are two compression types in SpiderMonkey, they are GZip and Zip. Could&#039;ve added more, but didn&#039;t want to have a dependency for just a compression method. Both are used by wrapping your message in the appropriate compression message:</p><pre>MyMessage msg = new MyMessage&#40;&#41;;
</div></p>
Now this is going to be a real simply tutorial but still I wanted this in a separate article. Why you may ask? Simply because it&#039;s a feature that requires some explanation, since it has some caveats that I&#039;ll discuss. Also, I&#039;ll cover writing your own compression message.
</p>
<p>
First off - there are two compression types in SpiderMonkey, they are GZip and Zip. Could&#039;ve added more, but didn&#039;t want to have a dependency for just a compression method. Both are used by wrapping your message in the appropriate compression message:
</p>
<pre>MyMessage msg = new MyMessage&#40;&#41;;
client.send&#40;new GZIPCompressedMessage&#40;msg&#41;&#41;; client.send&#40;new GZIPCompressedMessage&#40;msg&#41;&#41;;
// or // or
client.send&#40;new ZIPCompressedMessage&#40;msg&#41;&#41;;</pre> client.send&#40;new ZIPCompressedMessage&#40;msg&#41;&#41;;</pre><p> Really simple, but ZIP requires some explanation. The ZIPCompressedMessage class also has two extra methods; setLevel(int) and getLevel(). These methods are for setting the compression level, where 1 is best compression but slowest, and where 9 is weakest compression but fastest. Please note that 9 is <strong>not</strong> the so called &#039;store&#039; ZIP method, which simply stores file in the ZIP, instead of compressing it. This &#039;store&#039; feature is not in SpiderMonkey since otherwise it would not have been called compression.</p></div><h3><a
<p> name="writing_your_own">Writing your own</a></h3><div
class="level3"><p> Now of course I&#039;d love to see more compression methods in SpiderMonkey, so I&#039;ll discuss how to write your own. Let&#039;s just take GZIPCompressedMessage as example, since that one is the most straightforward. What I&#039;ve done, is I&#039;ve just created a GZIPCompressedMessage which extends CompressedMessage. It does not contain any extra messages, so the GZIPCompressedMessage class is practically &#039;empty&#039;. The magic happens at the serializer, which is called the GZIPSerializer (you can read about writing your own serializer <a
Really simple, but ZIP requires some explanation. The ZIPCompressedMessage class also has two extra methods; setLevel(int) and getLevel(). These methods are for setting the compression level, where 1 is best compression but slowest, and where 9 is weakest compression but fastest. Please note that 9 is <strong>not</strong> the so called &#039;store&#039; ZIP method, which simply stores file in the ZIP, instead of compressing it. This &#039;store&#039; feature is not in SpiderMonkey since otherwise it would not have been called compression. href="/com/jme3/gde/core/docs/spidermonkey/tutorial/serializing.html">here</a>). Then I just registered the GZIPSerializer to GZIPCompressedMessage and presto - you&#039;re done. Don&#039;t forget that in the Serializer you need to use writeClassAndObject first and then compress that data, and for read you&#039;d need to use readClassAndObject after you&#039;ve uncompressed (inflated) the message. For this to be clear, it may be useful to read <a
</p> href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/networking/com/jme3/network/serializing/serializers/GZIPSerializer.java">the GZIPSerializer class</a>.</p><p> That&#039;s that! Next tutorial we&#039;re going to discuss how to use the Service system.</p></div>
</div>
<h3><a>Writing your own</a></h3>
<div>
<p>
Now of course I&#039;d love to see more compression methods in SpiderMonkey, so I&#039;ll discuss how to write your own. Let&#039;s just take GZIPCompressedMessage as example, since that one is the most straightforward. What I&#039;ve done, is I&#039;ve just created a GZIPCompressedMessage which extends CompressedMessage. It does not contain any extra messages, so the GZIPCompressedMessage class is practically &#039;empty&#039;. The magic happens at the serializer, which is called the GZIPSerializer (you can read about writing your own serializer <a href="/com/jme3/gde/core/docs/spidermonkey/tutorial/serializing.html">here</a>). Then I just registered the GZIPSerializer to GZIPCompressedMessage and presto - you&#039;re done. Don&#039;t forget that in the Serializer you need to use writeClassAndObject first and then compress that data, and for read you&#039;d need to use readClassAndObject after you&#039;ve uncompressed (inflated) the message. For this to be clear, it may be useful to read <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/networking/com/jme3/network/serializing/serializers/GZIPSerializer.java"><param name="text" value="<html><u>the GZIPSerializer class</u></html>"><param name="textColor" value="blue"></object>.
</p>
<p>
That&#039;s that! Next tutorial we&#039;re going to discuss how to use the Service system.
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/spidermonkey:tutorial:compression?do=export_xhtmlbody">view online version</a></em></p> <p><em><a href="http://jmonkeyengine.org/wiki/doku.php/spidermonkey:tutorial:compression?do=export_xhtmlbody">view online version</a></em></p>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save