Przeglądaj źródła

Merge pull request #4 from jMonkeyEngine/master

update from jMonkeyEngine/wiki
Yan 7 lat temu
rodzic
commit
ed4e98d131
34 zmienionych plików z 1009 dodań i 736 usunięć
  1. 44 1
      src/docs/asciidoc/jme3/advanced/animation.adoc
  2. 119 84
      src/docs/asciidoc/jme3/advanced/debugging.adoc
  3. 1 1
      src/docs/asciidoc/jme3/advanced/jme3_srgbpipeline.adoc
  4. 3 3
      src/docs/asciidoc/jme3/advanced/level_of_detail.adoc
  5. 28 23
      src/docs/asciidoc/jme3/advanced/mixamo.adoc
  6. 1 1
      src/docs/asciidoc/jme3/advanced/pbr_part1.adoc
  7. 2 2
      src/docs/asciidoc/jme3/advanced/pbr_part3.adoc
  8. 21 21
      src/docs/asciidoc/jme3/advanced/terrain_collision.adoc
  9. 16 16
      src/docs/asciidoc/jme3/beginner/hello_asset.adoc
  10. 13 13
      src/docs/asciidoc/jme3/beginner/hello_collision.adoc
  11. 163 149
      src/docs/asciidoc/jme3/beginner/hello_input_system.adoc
  12. 18 17
      src/docs/asciidoc/jme3/beginner/hello_main_event_loop.adoc
  13. 91 88
      src/docs/asciidoc/jme3/beginner/hello_node.adoc
  14. 41 36
      src/docs/asciidoc/jme3/beginner/hello_simpleapplication.adoc
  15. 3 0
      src/docs/asciidoc/jme3/build_jme3_sources_with_netbeans.adoc
  16. 95 0
      src/docs/asciidoc/jme3/build_sources_netbeans_svn.adoc
  17. 1 1
      src/docs/asciidoc/jme3/contributions.adoc
  18. 203 141
      src/docs/asciidoc/jme3/external/blender.adoc
  19. 12 12
      src/docs/asciidoc/jme3/intermediate/appsettings.adoc
  20. 21 21
      src/docs/asciidoc/jme3/intermediate/best_practices.adoc
  21. 19 11
      src/docs/asciidoc/jme3/intermediate/file_types.adoc
  22. 23 21
      src/docs/asciidoc/jme3/maven.adoc
  23. 7 7
      src/docs/asciidoc/jme3/setting_up_jme3_in_eclipse.adoc
  24. 14 14
      src/docs/asciidoc/jme3/setting_up_netbeans_and_jme3.adoc
  25. 1 1
      src/docs/asciidoc/jme3/simpleapplication_from_the_commandline.adoc
  26. 49 51
      src/docs/asciidoc/sdk/project_creation.adoc
  27. BIN
      src/docs/images/jme3/external/monkey.png
  28. BIN
      src/docs/images/jme3/external/monkey_bump.png
  29. BIN
      src/docs/images/jme3/external/monkey_bump2.png
  30. BIN
      src/docs/images/jme3/external/monkey_bump2_invert.png
  31. BIN
      src/docs/images/jme3/external/monkey_final.gif
  32. BIN
      src/docs/images/jme3/external/monkeyprev1.png
  33. 0 1
      src/docs/resources/Scenes/Town/removeme.txt
  34. BIN
      src/docs/resources/Scenes/Town/town.zip

+ 44 - 1
src/docs/asciidoc/jme3/advanced/animation.adoc

@@ -82,6 +82,35 @@ There often are situations where you want to run several animation sequences at
 To reset a Control, call `control.clearChannels()`.
 
 
+=== Skeleton Control
+
+
+The Skeleton control deforms a model according to a skeleton. Use it to attach other geometries to your model such as clothing, weapons, accessories or a particle emitter effect. You access the control the same way as you would the AnimControl. 
+
+.Control resides in the main node of your model
+[source,java]
+----
+
+SkeletonControl skeletonControl;
+
+skeletonControl = player.getControl(SkeletonControl.class);
+
+----
+
+.Control rsides somewhere other than main node
+[source,java]
+----
+player.depthFirstTraversal(new SceneGraphVisitorAdapter() {
+    @Override
+    public void visit(Node node) {
+        if (node.getControl(SkeletonControl.class) != null) {
+            skeletonControl = node.getControl(SkeletonControl.class);
+        }
+    }
+});
+----
+
+
 == Animation Control Properties
 
 The following information is available for an AnimControl.
@@ -143,6 +172,21 @@ a|Usage
 a|getSkeleton()
 a|The Skeleton object controlled by this Control.
 
+|===
+
+== Skeleton Control Properties
+
+The following information is available for an SkeletonControl.
+
+[cols="2", options="header"]
+|===
+
+a|SkeletonControl Property
+a|Usage
+
+a|getSkeleton()
+a|The Skeleton object controlled by this Control.
+
 a|getTargets()
 a|The Skin objects controlled by this Control, as Mesh array.
 
@@ -151,7 +195,6 @@ a|Returns the attachment node of a bone. Attach models and effects to this node
 
 |===
 
-
 == Animation Channel Properties
 
 The following properties are set per AnimChannel.

+ 119 - 84
src/docs/asciidoc/jme3/advanced/debugging.adoc

@@ -9,7 +9,7 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 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's collision shape really where you think it is? Is the skeleton of the animated character moving like you think it should? This document shows you how to activate visual debug aides.
 
-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, and a “hasslefree unshaded material or wireframe: No model, no light source, no materials are needed to see them in your test scene.
+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, and a "`hasslefree`" unshaded material or wireframe: No model, no light source, no materials are needed to see them in your test scene.
 
 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 either the model (where is its origin coordinate?), or the light (too dark? too bright? missing?), or the model's material (missing?) – and not the positioning code.
 
@@ -25,33 +25,31 @@ image::jme3/advanced/debug-shapes.png[debug-shapes.png,width="600",height="220",
 
 === Coordinate Axes
 
-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.
+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.
 
 [source,java]
 ----
 
-private void attachCoordinateAxes(Vector3f pos){
-  Arrow arrow = new Arrow(Vector3f.UNIT_X);
-  arrow.setLineWidth(4); // make arrow thicker
-  putShape(arrow, ColorRGBA.Red).setLocalTranslation(pos);
+private void attachCoordinateAxes(Vector3f pos) {
+    Arrow arrow = new Arrow(Vector3f.UNIT_X);
+    putShape(arrow, ColorRGBA.Red).setLocalTranslation(pos);
 
-  arrow = new Arrow(Vector3f.UNIT_Y);
-  arrow.setLineWidth(4); // make arrow thicker
-  putShape(arrow, ColorRGBA.Green).setLocalTranslation(pos);
+    arrow = new Arrow(Vector3f.UNIT_Y);
+    putShape(arrow, ColorRGBA.Green).setLocalTranslation(pos);
 
-  arrow = new Arrow(Vector3f.UNIT_Z);
-  arrow.setLineWidth(4); // make arrow thicker
-  putShape(arrow, ColorRGBA.Blue).setLocalTranslation(pos);
+    arrow = new Arrow(Vector3f.UNIT_Z);
+    putShape(arrow, ColorRGBA.Blue).setLocalTranslation(pos);
 }
 
-private Geometry putShape(Mesh shape, ColorRGBA color){
-  Geometry g = new Geometry("coordinate axis", shape);
-  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-  mat.getAdditionalRenderState().setWireframe(true);
-  mat.setColor("Color", color);
-  g.setMaterial(mat);
-  rootNode.attachChild(g);
-  return g;
+private Geometry putShape(Mesh shape, ColorRGBA color) {
+    Geometry g = new Geometry("coordinate axis", shape);
+    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+    mat.getAdditionalRenderState().setWireframe(true);
+    mat.getAdditionalRenderState().setLineWidth(4);
+    mat.setColor("Color", color);
+    g.setMaterial(mat);
+    rootNode.attachChild(g);
+    return g;
 }
 ----
 
@@ -63,15 +61,15 @@ Use a wireframe grid (com.jme3.scene.debug.Grid) as a ruler or simple floor.
 [source,java]
 ----
 
-private Geometry attachGrid(Vector3f pos, float size, ColorRGBA color){
-  Geometry g = new Geometry("wireframe grid", new Grid(size, size, 0.2f) );
-  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-  mat.getAdditionalRenderState().setWireframe(true);
-  mat.setColor("Color", color);
-  g.setMaterial(mat);
-  g.center().move(pos);
-  rootNode.attachChild(g);
-  return g;
+private Geometry attachGrid(Vector3f pos, int size, ColorRGBA color) {
+    Geometry g = new Geometry("wireframe grid", new Grid(size, size, 0.2f));
+    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+    mat.getAdditionalRenderState().setWireframe(true);
+    mat.setColor("Color", color);
+    g.setMaterial(mat);
+    g.center().move(pos);
+    rootNode.attachChild(g);
+    return g;
 }
 ----
 
@@ -83,15 +81,15 @@ Use a wireframe cube (com.jme3.scene.debug.WireBox) as a stand-in object to see
 [source,java]
 ----
 
-public Geometry attachWireBox(Vector3f pos, float size, ColorRGBA color){
-  Geometry g = new Geometry("wireframe cube", new WireBox(size, size, size));
-  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-  mat.getAdditionalRenderState().setWireframe(true);
-  mat.setColor("Color", color);
-  g.setMaterial(mat);
-  g.setLocalTranslation(pos);
-  rootNode.attachChild(g);
-  return g;
+public Geometry attachWireBox(Vector3f pos, float size, ColorRGBA color) {
+    Geometry g = new Geometry("wireframe cube", new WireBox(size, size, size));
+    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+    mat.getAdditionalRenderState().setWireframe(true);
+    mat.setColor("Color", color);
+    g.setMaterial(mat);
+    g.setLocalTranslation(pos);
+    rootNode.attachChild(g);
+    return g;
 }
 ----
 
@@ -103,15 +101,15 @@ Use a wireframe sphere (com.jme3.scene.debug.WireSphere) as a stand-in object to
 [source,java]
 ----
 
-private Geometry attachWireSphere(Vector3f pos, float size, ColorRGBA color){
-  Geometry g = new Geometry("wireframe sphere", new WireSphere(size));
-  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-  mat.getAdditionalRenderState().setWireframe(true);
-  mat.setColor("Color", color);
-  g.setMaterial(mat);
-  g.setLocalTranslation(pos);
-  rootNode.attachChild(g);
-  return g;
+private Geometry attachWireSphere(Vector3f pos, float size, ColorRGBA color) {
+    Geometry g = new Geometry("wireframe sphere", new WireSphere(size));
+    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+    mat.getAdditionalRenderState().setWireframe(true);
+    mat.setColor("Color", color);
+    g.setMaterial(mat);
+    g.setLocalTranslation(pos);
+    rootNode.attachChild(g);
+    return g;
 }
 ----
 
@@ -122,7 +120,10 @@ You can display a wireframe of the (usually invisible) collision shape around al
 
 [source,java]
 ----
-physicsSpace.enableDebug(assetManager);
+//Create the physics space.
+bulletAppState = new BulletAppState();
+bulletAppState.setDebugEnabled(true);
+getStateManager().attach(bulletAppState);
 ----
 
 With debugging enabled, colors are used to indicate various types of physical objects:
@@ -138,18 +139,40 @@ With debugging enabled, colors are used to indicate various types of physical ob
 
 Making the skeleton visible inside animated models can be handy for debugging animations. The `control` object is an AnimControl, `player` is the loaded model.
 
+.AnimControl is known to be in the main node
 [source,java]
 ----
 
-     SkeletonDebugger skeletonDebug =
-         new SkeletonDebugger("skeleton", control.getSkeleton());
-     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-     mat.setColor("Color", ColorRGBA.Green);
-     mat.getAdditionalRenderState().setDepthTest(false);
-     skeletonDebug.setMaterial(mat);
-     player.attachChild(skeletonDebug);
+SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
+Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+mat.setColor("Color", ColorRGBA.Green);
+mat.getAdditionalRenderState().setDepthTest(false);
+skeletonDebug.setMaterial(mat);
+player.attachChild(skeletonDebug);
 ----
 
+.AnimControl is nested somewhere
+[source,java]
+----
+private void debugSkeleton(Node player) {
+    player.depthFirstTraversal(new SceneGraphVisitorAdapter() {
+        @Override
+        public void visit(Node node) {
+            if (node.getControl(AnimControl.class) != null) {
+                AnimControl control = node.getControl(AnimControl.class);
+                SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
+                        control.getSkeleton());
+                Material mat = new Material(getApplication().getAssetManager(),
+                        "Common/MatDefs/Misc/Unshaded.j3md");
+                mat.setColor("Color", ColorRGBA.Green);
+                mat.getAdditionalRenderState().setDepthTest(false);
+                skeletonDebug.setMaterial(mat);
+                player.attachChild(skeletonDebug);
+            }
+        }
+    });
+}
+----
 
 == Example: Toggle Wireframe on Model
 
@@ -157,61 +180,67 @@ We assume that you have loaded a model with a material `mat`.
 
 Then you can add a switch to toggle the model's wireframe on and off, like this:
 
-.  Create a key input trigger that switches between the two materials: E.g. we toggle when the T key is pressed:
+.  Create a key input trigger that switches between the two materials: E.g. we toggle when the T key is pressed.
++
 [source,java]
 ----
-    inputManager.addMapping("toggle wireframe", new KeyTrigger(KeyInput.KEY_T));
-    inputManager.addListener(actionListener, "toggle wireframe");
+inputManager.addMapping("toggle wireframe", new KeyTrigger(KeyInput.KEY_T));
+inputManager.addListener(actionListener, "toggle wireframe");
 ----
 
-.  Now add the toggle action to the action listener
+.  Now add the toggle action to the action listener.
++
 [source,java]
 ----
 
-  private ActionListener actionListener = new ActionListener() {
+private ActionListener actionListener = new ActionListener() {
     @Override
     public void onAction(String name, boolean pressed, float tpf) {
-      // toggle wireframe
-      if (name.equals("toggle wireframe") && !pressed) {
-        wireframe = !wireframe; // toggle boolean
-        mat.getAdditionalRenderState().setWireframe(wireframe);
-      }
-      // else ... other input tests.
+        // toggle wireframe
+        if (name.equals("toggle wireframe") && !pressed) {
+            wireframe = !wireframe; // toggle boolean
+            mat.getAdditionalRenderState().setWireframe(wireframe);
+        }
+        // else ... other input tests.
     }
-  };
+};
 ----
 
-.  Alternatively you could traverse over the whole scene and toggle for all Geometry objects in there if you don't want to create a new SceneProcessor
+.  Alternatively, you could traverse over the whole scene and toggle for all Geometry objects in there if you don't want to create a new SceneProcessor.
++
 [source,java]
 ----
 
-  private ActionListener actionListener = new ActionListener() {
+private ActionListener actionListener = new ActionListener() {
     boolean wireframe = false;
 
     @Override
     public void onAction(String name, boolean pressed, float tpf) {
-      // toggle wireframe
-      if (name.equals("toggle wireframe") && !pressed) {
-        wireframe = !wireframe; // toggle boolean
-        rootNode.depthFirstTraversal(new SceneGraphVisitor() {
-          public void visit(Spatial spatial) {
-            if (spatial instanceof Geometry)
-              ((Geometry)spatial).getMaterial().getAdditionalRenderState().setWireframe(wireframe);
-          }
-        });
-      }
-      // else ... other input tests.
+        // toggle wireframe
+        if (name.equals("toggle wireframe") && !pressed) {
+            wireframe = !wireframe; // toggle boolean
+            rootNode.depthFirstTraversal(new SceneGraphVisitor() {
+                @Override
+                public void visit(Spatial spatial) {
+                    if (spatial instanceof Geometry) {
+                        ((Geometry) spatial).getMaterial()
+                                .getAdditionalRenderState().setWireframe(wireframe);
+                    }
+                }
+            });
+        }
+        // else ... other input tests.
     }
-  };
+};
 ----
 
 
-TIP :: To set the line width of wireframe display, use mesh.setLineWidth(lineWidth). Default line width is 1.
+TIP: To set the line width of wireframe display, use mesh.setLineWidth(lineWidth). Default line width is 1.
 
 
 == Example: Toggle Wireframe on the scene
 
-To display the wireframe of the entire scene instead on one material at a time, first create the following Scene Processor
+To display the wireframe of the entire scene instead on one material at a time, first create the following Scene Processor.
 
 [source,java]
 ----
@@ -226,33 +255,39 @@ public class WireProcessor implements SceneProcessor {
         wireMaterial.getAdditionalRenderState().setWireframe(true);
     }
 
+    @Override
     public void initialize(RenderManager rm, ViewPort vp) {
         renderManager = rm;
     }
 
+    @Override
     public void reshape(ViewPort vp, int w, int h) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    @Override
     public boolean isInitialized() {
         return renderManager != null;
     }
 
+    @Override
     public void preFrame(float tpf) {
     }
 
+    @Override
     public void postQueue(RenderQueue rq) {
         renderManager.setForcedMaterial(wireMaterial);
     }
 
+    @Override
     public void postFrame(FrameBuffer out) {
         renderManager.setForcedMaterial(null);
     }
 
+    @Override
     public void cleanup() {
         renderManager.setForcedMaterial(null);
     }
-
 }
 ----
 

+ 1 - 1
src/docs/asciidoc/jme3/advanced/jme3_srgbpipeline.adoc

@@ -1,4 +1,4 @@
-= Gamma Correction or sRGB pipline
+= Gamma Correction or sRGB pipeline
 :author:
 :revnumber:
 :revdate: 2016/03/17 20:48

+ 3 - 3
src/docs/asciidoc/jme3/advanced/level_of_detail.adoc

@@ -76,7 +76,7 @@ The SDK contains a user-friendly interface to generate LODs for a model (.j3o fi
 image:jme3/advanced/jme-sdk-generate-lod-menu.png[The Tools Generate LOD context menu in the SceneExplorer,width="300",height="180"]
 .  The `Generate LOD` settings wizard opens: +
 image:jme3/advanced/jme-sdk-generate-lod-window.png[The Generate LOD settings wizard,width="300",height="150"]
-.  Choose a reduction method and reduction values for one or more levels. 
+.  Choose a reduction method and reduction values for one or more levels.
 +
 [TIP]
 ====
@@ -111,12 +111,12 @@ lod.bakeLods(reductionMethod,reductionValue);
 
 The LODs are stored inside the Geometry object.
 
-*Example:* How to generate an LOD of myPrettyGeo's mesh with 50% fewer polygons:
+*Example:* How to generate an LOD of myPrettyGeo's mesh with the same settings as used in the SDK example above:
 
 [source,java]
 ----
 LodGenerator lod = new LodGenerator(myPrettyGeo);
-lod.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL,0.5f);
+lod.bakeLods(LodGenerator.TriangleReductionMethod.PROPORTIONAL,0.25, 0.5f, 0.75f);
 ----
 
 

+ 28 - 23
src/docs/asciidoc/jme3/advanced/mixamo.adoc

@@ -202,11 +202,14 @@ If you find yourself in need of baking, the process is as follows.
 
 .  Using the animation file you created in the previous section, from the `Info` header, select `menu:File[Save Copy]`.
 .  Save the file somewhere other than the current folder. This will save you the effort of re-creating the animation file if you need it at some other time.
-.  In the `Info` header, change the `Default` screen layout to `Animation`.
-.  In the `Dope Sheet Editor`, change the `Dope Sheet` mode/context to `Action Editor`.
+.  In the `Info` header, change the `Default` screen layout to `Animation`.
+.  In the `Dope Sheet Editor`, change the `Dope Sheet` mode/context to `Action Editor`.
 .  Click the btn:[Action to be linked] button and select your action.
-.  In the `3d Viewport` header, with the armature selected, select `menu:Object[Animation > Bake Action]`.
-.  In the `Bake Action` dialog, deselect and set the settings as follows:
+.  In the `3d Viewport` header, select the armature.
+*  Depending on the mode selected choose:
+.. Object Mode: `menu:Object[Animation > Bake Action]`.
+.. Pose Mode: `menu:Pose[Animation > Bake Action]`.
+.  In the `Bake Action` dialog, deselect and set the settings as follows:
 Bake Action::
 - [ ] Selected Only
 - [x] Visual Keying
@@ -214,11 +217,11 @@ Bake Action::
 - [ ] Clear Parents
 - [ ] Overwrite Current
 -  Bake Data = Pose
-.  When ready click btn:[OK].
-.  The `Linked Action` in the `Dope Sheet Editor` will change to the newly baked action and is named `Action`. Rename this to the name of the imported animation.
-.  Select the btn:[F] button to save the action.
-.  Save your file.
-.  Clear the old action from the `Linked Action` buffer. See <<jme3/advanced/3d_models#blender-buffer-clearing#,Blender Buffer Clearing>> for more information.
+.  When ready click btn:[OK].
+.  The `Linked Action` in the `Dope Sheet Editor` will change to the newly baked action and is named `Action`. Rename this to the name of the imported animation.
+.  Select the btn:[F] button to save the action.
+.  Save your file.
+.  Clear the old action from the `Linked Action` buffer. See <<jme3/advanced/3d_models#blender-buffer-clearing#,Blender Buffer Clearing>> for more information.
 
 
 == Creating The Rigged Animation File
@@ -231,7 +234,7 @@ You create a rigged animation file only one time per model.
 .  If you have closed the TPose.blend file, open it. In the `Info` header select `menu:File[Save As]` and save the file using the models name with the word `Rigged` added. This will be the only file we add animations to, for this model, from now on. It has our default TPose action which will allow us to start our animation track for `Ogre` animation exporting.
 .  Select your `Armature`.
 Object Tab::
-*  In the `Properties` panel, navigate to the `Object` tab. In the `Display` panel toggle `X-Ray` on.
+..  In the `Properties` panel, navigate to the `Object` tab. In the `Display` panel toggle `X-Ray` on.
 .  With your mouse inside the `3d Viewport`, press kbd:[Num Pad 1] followed by kbd:[Numpad 5].
 .  kbd:[Tab] into `Edit Mode`.
 .  Set the `3d Cursor` to the models origin.
@@ -245,9 +248,9 @@ The models origin and the `Root` bone origin must be at the same location.
 . Scale the bone down or up as needed by selecting the `Tip` (ball at the narrowest part of the bone) and dragging the `Z` arrow (blue arrow) of the manipulator up or down until you are satisfied with its scale. *DO NOT CHANGE THE ANGLE OR MOVE THE BASE OF THE BONE FROM CENTER*.
 .  When satisfied with the scale, select the body of the bone to select the entire bone.
 Bone Tab::
-*  In the `Properties` panel, navigate to the `Bone` tab.
-*  Rename the bone to `Root`.
-*  Deselect the `Deform` panel checkbox.
+..  In the `Properties` panel, navigate to the `Bone` tab.
+..  Rename the bone to `Root`.
+..  Deselect the `Deform` panel checkbox.
 .  In the `3d Viewport`, select the body of the armatures `Hip` bone, the lowest bone in the center of the armature, to select the entire bone.
 .  While holding kbd:[Shift] down, btn:[LMB] select the `Root` bone.
 .  Press kbd:[Ctrl] + kbd:[P].
@@ -255,23 +258,23 @@ Bone Tab::
 .  With the mouse inside the 3d Viewport, kbd:[Tab] out of `Edit Mode`.
 . Select your model.
 Data Tab::
-*  In the `Properties` panel, navigate to the `Data` tab and make sure the `Mesh` has the same name as your model.
+..  In the `Properties` panel, navigate to the `Data` tab and make sure the `Mesh` has the same name as your model.
 Material Tab::
-*  In the `Properties` panel, navigate to the `Material` tab and make sure there is one `Material` in the `Material List` and it is the same name as your model.
-*  In the `Transparency` panel, move the `Alpha` slider to 1.
+..  In the `Properties` panel, navigate to the `Material` tab and make sure there is one `Material` in the `Material List` and it is the same name as your model.
+..  In the `Transparency` panel, move the `Alpha` slider to 1.
 +
 [IMPORTANT]
 ====
 There appears to be a bug where the FBX importer adds an `Alpha` map texture to your model. If the `Alpha` slider is not at one, and you use the Blender importer of the SDK, or convert a .blend file, it will be transparent. `Ogre` export is unaffected.
 ====
 
-*  Deselect the checkbox of the `Transparency` panel.
+..  Deselect the checkbox of the `Transparency` panel.
 Texture Tab::
-*  In the `Properties` panel, navigate to the `Texture` tab, you will note that your texture has duplicate names in the `Texture List`. The bottom texture is actually a transparent `Alpha` texture and appears to be a bug. Select the *second* texture in the `*Texture List*` to highlight it.
-*  While holding down the kbd:[Shift] key, press the btn:[X] button next to the `*Texture Data Block*` to delete it.
-*  Select your remaining texture in the `Texture List` to highlight it. You will note the `Texture Data Block` is now red due to no texture being assigned.
-*  Click on the btn:[Browse Texture to be linked] button next to the `Texture Data Block` and select your texture.
-*  In the `Image` panel, click the btn:[Small Box] button located next to your texture's path to pack the image file.
+..  In the `Properties` panel, navigate to the `Texture` tab, you will note that your texture has duplicate names in the `Texture List`. The bottom texture is actually a transparent `Alpha` texture and appears to be a bug. Select the *second* texture in the `*Texture List*` to highlight it.
+..  While holding down the kbd:[Shift] key, press the btn:[X] button next to the `*Texture Data Block*` to delete it.
+..  Select your remaining texture in the `Texture List` to highlight it. You will note the `Texture Data Block` is now red due to no texture being assigned.
+..  Click on the btn:[Browse Texture to be linked] button next to the `Texture Data Block` and select your texture.
+..  In the `Image` panel, click the btn:[Small Box] button located next to your texture's path to pack the image file.
 .  In the `Info` header, change the layout from `Animation` to `UV Editing`.
 .  With your mouse inside the `3d Viewport` and the model still selected, kbd:[Tab] into edit mode. If your model is not completely orange press kbd:[A] untill all vertices are selected. You will see your UV Mapped mesh appear in the `UV Image Editor` window.
 .  In the `UV Image Editor`, click the btn:[Browse Image to be linked] button and select your UV image.
@@ -279,7 +282,9 @@ Texture Tab::
 .  In the `Info` header, change the layout from `UV Editing` to `Default` and then click the btn:[+] button to create a new layout.
 .  Rename this new layout `NLA Editing`.
 .  Click the `Current Editor Type` button, located at the bottom left (small box) of the `3d Viewport`, and change it from `3d View` to `NLA Editor`. Our TPose action is now visible.
-*  If the action is not visible, navigate to the `Dope Sheet Editor` and from the `Action Editor` context, select the `Action`.
++
+NOTE: If the action is not visible, navigate to the `Dope Sheet Editor` and from the `Action Editor` context, select the `Action`.
+
 .  Click the btn:[Double Down Arrow] button to push the action down into the stack.
 .  Beneath the TPose strip you will see a slider. Drag this slider to the right until your strip is nested up against the left margin of the window.
 . Save your file.

+ 1 - 1
src/docs/asciidoc/jme3/advanced/pbr_part1.adoc

@@ -74,7 +74,7 @@ These parameters are the basics of PBR. Of course, each of them can be stored in
 
 The nice thing is that Metalness, Roughness and AO are grey scaled textures, so basically they only use one channel of a texture. So you can pack those 3 maps in one texture.
 
-You can find an example asset that should work in a typical PBR implementation here. This page showcases pretty well what the textures should look like.
+You can find an example asset that should work in a typical PBR implementation link:http://artisaverb.info/PBT.html[here]. This page showcases pretty well what the textures should look like.
 
 That’s it for PBR from the artist point of view. Next week I’ll explain what’s under the hood for you fellow developers 😉
 

+ 2 - 2
src/docs/asciidoc/jme3/advanced/pbr_part3.adoc

@@ -40,7 +40,7 @@ Here the reflected Ray is our reflection vector.
 
 Unfortunately we can’t take each pixel of the env map and compute light as if it was a direct light source and hope for the best.
 
-There’s crazy math around that topic, and to be honest I ddidn’tget all of it myself. So instead of explaining difficult math equations that may be confusing, I’m gonna go straight to the point : How are we going to compute lighting from the environment map?
+There’s crazy math around that topic, and to be honest I didn’t get all of it myself. So instead of explaining difficult math equations that may be confusing, I’m gonna go straight to the point : How are we going to compute lighting from the environment map?
 
 === IBL Diffuse
 
@@ -79,7 +79,7 @@ What’s that again? I won’t go into explaining them in details (because I can
 
 To put it simple, SH can help us to compute the irradiance map way faster. This article explains that it all boils down to compute only 9 spherical harmonics coefficients to efficiently approximate an irradiance factor.
 
-At this point you can even skip the pre computation of the irradiance map, and use those coefficients directly in your shader for each shaded pixels. That’s fast enough to be real time, and use less memory that a cube map.
+At this point you can even skip the pre computation of the irradiance map, and use those coefficients directly in your shader for each shaded pixels. That’s fast enough to be real time, and use less memory than a cube map.
 
 But still…it’s slower than one texture fetch, so I chose to compute the Irradiance map and use it in the shader.
 

+ 21 - 21
src/docs/asciidoc/jme3/advanced/terrain_collision.adoc

@@ -1,6 +1,6 @@
 = terrain_collision
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: terrain, collision
 :relfileprefix: ../../
@@ -12,7 +12,7 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 == Terrain Collision
 
-This tutorial expands the HelloTerrain tutorial and makes the terrain solid. You combine what you learned in <<jme3/beginner/hello_terrain#,Hello Terrain>> and <<jme3/beginner/hello_collision#,Hello Collision>> and add a CollisionShape to the terrain. The terrain's CollisionShape lets the first-person player (who is also a CollisionShape) collide with the terrain, i.e. walk on it and stand on it. 
+This tutorial expands the HelloTerrain tutorial and makes the terrain solid. You combine what you learned in <<jme3/beginner/hello_terrain#,Hello Terrain>> and <<jme3/beginner/hello_collision#,Hello Collision>> and add a CollisionShape to the terrain. The terrain's CollisionShape lets the first-person player (who is also a CollisionShape) collide with the terrain, i.e. walk on it and stand on it.
 
 
 == Sample Code
@@ -46,7 +46,7 @@ import java.util.List;
 import jme3tools.converters.ImageToAwt;
 
 /**
- * This demo shows a terrain with collision detection, 
+ * This demo shows a terrain with collision detection,
  * that you can walk around in with a first-person perspective.
  * This code combines HelloCollision and HelloTerrain.
  */
@@ -71,14 +71,14 @@ public class HelloTerrainCollision extends SimpleApplication
     /** Set up Physics */
     bulletAppState = new BulletAppState();
     stateManager.attach(bulletAppState);
-    //Uncomment for debugging. 
+    //Uncomment for debugging.
     //bulletAppState.setDebugEnabled(true);
-    
+
     flyCam.setMoveSpeed(100);
     setUpKeys();
 
     /** 1. Create terrain material and load four textures into it. */
-    mat_terrain = new Material(assetManager, 
+    mat_terrain = new Material(assetManager,
             "Common/MatDefs/Terrain/Terrain.j3md");
 
     /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
@@ -113,7 +113,7 @@ public class HelloTerrainCollision extends SimpleApplication
     heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
     heightmap.load();
 
-    /** 3. We have prepared material and heightmap. 
+    /** 3. We have prepared material and heightmap.
      * Now we create the actual terrain:
      * 3.1) Create a TerrainQuad and name it "my terrain".
      * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
@@ -134,12 +134,12 @@ public class HelloTerrainCollision extends SimpleApplication
     cameras.add(getCamera());
     TerrainLodControl control = new TerrainLodControl(terrain, cameras);
     terrain.addControl(control);
-    
-    /** 6. Add physics: */ 
-    // We set up collision detection for the scene by creating a static 
+
+    /** 6. Add physics: */
+    // We set up collision detection for the scene by creating a static
     RigidBodyControl with mass zero.*/
     terrain.addControl(new RigidBodyControl(0));
-    
+
     // We set up collision detection for the player by creating
     // a capsule collision shape and a CharacterControl.
     // The CharacterControl offers extra settings for
@@ -149,9 +149,9 @@ public class HelloTerrainCollision extends SimpleApplication
     player = new CharacterControl(capsuleShape, 0.05f);
     player.setJumpSpeed(20);
     player.setFallSpeed(30);
-    player.setGravity(30);
+    player.setGravity(new Vector3f(0,-30,0));
     player.setPhysicsLocation(new Vector3f(-10, 10, 10));
- 
+
     // We attach the scene and the player to the rootnode and the physics space,
     // to make them appear in the game world.
     bulletAppState.getPhysicsSpace().add(terrain);
@@ -185,7 +185,7 @@ public class HelloTerrainCollision extends SimpleApplication
     } else if (binding.equals("Down")) {
       if (value) { down = true; } else { down = false; }
     } else if (binding.equals("Jump")) {
-      player.jump();
+      player.jump(new Vector3f(0,10,0));
     }
   }
 
@@ -211,7 +211,7 @@ public class HelloTerrainCollision extends SimpleApplication
 }
 ----
 
-To try this code, create a `menu:New Project[JME3 > BasicGame]` using the default settings. Paste the sample code over the pregenerated Main.java class. Change the package to '`mygame`' if necessary. Open the `menu:File[Project Properties > Libraries]` and add the `jme3-test-data` library to make certain you have all the files. 
+To try this code, create a `menu:New Project[JME3 > BasicGame]` using the default settings. Paste the sample code over the pregenerated Main.java class. Change the package to '`mygame`' if necessary. Open the `menu:File[Project Properties > Libraries]` and add the `jme3-test-data` library to make certain you have all the files.
 
 Compile and run the code. You should see a terrain. You can use the WASD keys and the mouse to run up and down the hills.
 
@@ -224,7 +224,7 @@ Compile and run the code. You should see a terrain. You can use the WASD keys an
 Read <<jme3/beginner/hello_terrain#,Hello Terrain>> for details of the following parts that we reuse:
 
 .  The `AbstractHeightMap` is an efficient way to describe the shape of the terrain.
-.  The `Terrain.j3md`-based Material and its texture layers let you colorize rocky mountain, grassy valleys, and a paved path criss-crossing over the landscape. 
+.  The `Terrain.j3md`-based Material and its texture layers let you colorize rocky mountain, grassy valleys, and a paved path criss-crossing over the landscape.
 .  The TerrainQuad is the finished `terrain` Spatial that you attach to the rootNode.
 
 
@@ -235,7 +235,7 @@ Read <<jme3/beginner/hello_collision#,Hello Collision>> for details of the follo
 .  The `BulletAppState` lines activate physics.
 .  The `ActionListener` (`onAction()`) lets you reconfigure the input handling for the first-person player, so it takes collision detection into account.
 .  The custom `setUpKeys()` method loads your reconfigured input handlers. They now don't just walk blindly, but calculate the `walkDirection` vector that we need for collision detection.
-.  `simpleUpdate()` uses the `walkDirection` vector and makes the character walk, while taking obstacles and solid walls/floor into account. 
+.  `simpleUpdate()` uses the `walkDirection` vector and makes the character walk, while taking obstacles and solid walls/floor into account.
 
 [source,java]
 ----
@@ -250,13 +250,13 @@ player.setWalkDirection(walkDirection);
 
 Here are the changed parts to combine the two:
 
-.  You create a static (zero-mass) RigidBodyControl. 
+.  You create a static (zero-mass) RigidBodyControl.
 .  Add the control to the `terrain` to make it physical.
 
 [source,java]
 ----
-/** 6. Add physics: */ 
-    terrain.addControl(new RigidBodyControl(0));  
+/** 6. Add physics: */
+    terrain.addControl(new RigidBodyControl(0));
 
 ----
 

+ 16 - 16
src/docs/asciidoc/jme3/beginner/hello_asset.adoc

@@ -21,7 +21,7 @@ image::jme3/beginner/beginner-assets-models.png[beginner-assets-models.png,320,2
 
 [TIP]
 ====
-<<sdk/sample_code#,Trouble finding the files to run this sample?>> To get the assets (3D models) used in this example, add the included `jME3-testdata.jar` to your classpath. In project created with the jMonkeyEngine SDK (recommended), simply right-click your project, choose “Properties, go to “Libraries, press “Add Library and add the preconfigured “jme3-test-data library.
+<<sdk/sample_code#,Trouble finding the files to run this sample?>> To get the assets (3D models) used in this example, add the included `jME3-testdata.jar` to your classpath. In project created with the jMonkeyEngine SDK (recommended), simply right-click your project, choose "`Properties`", go to "`Libraries`", press "`Add Library`" and add the preconfigured "`jme3-test-data`" library.
 ====
 
 
@@ -95,7 +95,7 @@ public class HelloAssets extends SimpleApplication {
 }
 ----
 
-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.
+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`".
 
 
 == The Asset Manager
@@ -103,9 +103,9 @@ Build and run the code sample. You should see a green Ninja with a colorful teap
 *By game assets we mean all multi-media files, such as models, materials, textures, whole scenes, custom shaders, music and sound files, and custom fonts.* JME3 comes with a handy AssetManager object that helps you access your assets.
 The AssetManager can load files from:
 
-*  the current classpath (the top level of your project directory),
-*  the `assets` directory of your project, and
-*  optionally, custom paths that you register.
+*  The current classpath (the top level of your project directory).
+*  The `assets` directory of your project.
+*  Optionally, custom paths that you register.
 
 The following is the recommended directory structure for storing assets in your project directoy:
 
@@ -150,12 +150,12 @@ rootNode.attachChild(wall);
 
 ----
 
-In this case, you <<jme3/beginner/hello_material#,create your own Material>> and apply it to a Geometry. You base Materials on default material descriptions (such as “Unshaded.j3md), as shown in this example.
+In this case, you <<jme3/beginner/hello_material#,create your own Material>> and apply it to a Geometry. You base Materials on default material descriptions (such as "`Unshaded.j3md`"), as shown in this example.
 
 
 === Loading Text and Fonts
 
-This example displays the text “Hello World in the default font at the bottom edge of the window. You attach text to the `guiNode` – this is a special node for flat (orthogonal) display elements. You display text to show the game score, player health, etc.
+This example displays the text "`Hello World`" in the default font at the bottom edge of the window. You attach text to the `guiNode` – this is a special node for flat (orthogonal) display elements. You display text to show the game score, player health, etc.
 The following code sample goes into the `simpleInitApp()` method.
 
 [source,java]
@@ -197,7 +197,7 @@ rootNode.addLight(sun);
 
 ----
 
-Note that you do not need to create a Material if you exported the model with a material. Remember to add a light source, as shown, otherwise the material (and the whole model) is not visible!
+NOTE: You do not need to create a Material if you exported the model with a material. Remember to add a light source, as shown, otherwise the material (and the whole model) is not visible!
 
 
 === Loading Assets From Custom Paths
@@ -244,9 +244,9 @@ See <<jme3/advanced/3d_models#creating-models-and-scenes#,creating models and sc
 
 JME3 can convert and load
 
-*  Ogre XML models + materials,
-*  Ogre DotScenes,
-*  Wavefront OBJ + MTL models,
+*  Ogre XML models + materials.
+*  Ogre DotScenes.
+*  Wavefront OBJ + MTL models.
 *  .Blend files.
 
 The `loadModel()` method loads these original file formats when you run your code directly from the SDK. If you however build the executables using the default build script, then the original model files (XML, OBJ, etc) _are not included_. This means, when you run the executable outside the SDK, and load any original models directly, you get the following error message:
@@ -267,7 +267,7 @@ But for QA test builds and for the final release build, you use *.j3o files* exc
 
 Open your JME3 Project in the jMonkeyEngine SDK.
 
-.  Right-click a .Blend, .OBJ, or .mesh.xml file in the Projects window, and choose “convert to JME3 binary.
+.  Right-click a .Blend, .OBJ, or .mesh.xml file in the Projects window, and choose "`Convert to j3o Binary`".
 .  The .j3o file appears next to the .mesh.xml file and has the same name.
 .  Update all your `loadModel()` lines accordingly. For example:
 +
@@ -279,7 +279,7 @@ Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.j3o");
 
 [TIP]
 ====
-If your executable throws a “Cannot locate resource runtime exception, check all load paths and make sure you have converted all models to .j3o files!
+If your executable throws a "`Cannot locate resource`" runtime exception, check all load paths and make sure you have converted all models to .j3o files!
 ====
 
 
@@ -290,7 +290,7 @@ If your executable throws a “Cannot locate resource runtime exception, check a
 a| Task?
 a| Solution!
 
-a| Load model W/ materials
+a| Load model W/ materials.
 a| Use the asset manager's `loadModel()` method and attach the Spatial to the rootNode.
 
 [source,java]
@@ -305,7 +305,7 @@ Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
 rootNode.attachChild(elephant);
 ----
 
-a| Load model W/O materials
+a| Load model W/O materials.
 a| If you have a model without materials, you have to give it a material to make it visible.
 
 [source,java]
@@ -316,7 +316,7 @@ teapot.setMaterial(mat);
 rootNode.attachChild(teapot);
 ----
 
-a| Load a scene
+a| Load a scene.
 a| You load scenes just like you load models:
 
 [source,java]

+ 13 - 13
src/docs/asciidoc/jme3/beginner/hello_collision.adoc

@@ -1,6 +1,6 @@
 = jMonkeyEngine 3 Tutorial (9) - Hello Collision
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: beginner, collision, control, intro, documentation, model, physics
 :relfileprefix: ../../
@@ -72,7 +72,7 @@ public class HelloCollision extends SimpleApplication
   private CharacterControl player;
   private Vector3f walkDirection = new Vector3f();
   private boolean left = false, right = false, up = false, down = false;
-  
+
   //Temporary vectors used on each frame.
   //They here to avoid instanciating new vectors on each frame
   private Vector3f camDir = new Vector3f();
@@ -116,7 +116,7 @@ public class HelloCollision extends SimpleApplication
     player = new CharacterControl(capsuleShape, 0.05f);
     player.setJumpSpeed(20);
     player.setFallSpeed(30);
-    player.setGravity(30);
+    player.setGravity(new Vector3f(0,-30f,0));
     player.setPhysicsLocation(new Vector3f(0, 10, 0));
 
     // We attach the scene and the player to the rootnode and the physics space,
@@ -165,7 +165,7 @@ public class HelloCollision extends SimpleApplication
     } else if (binding.equals("Down")) {
       down = isPressed;
     } else if (binding.equals("Jump")) {
-      if (isPressed) { player.jump(); }
+      if (isPressed) { player.jump(new Vector3f(0,10,0)); }
     }
   }
 
@@ -304,7 +304,7 @@ To use collision detection, you add a RigidBodyControl to the `sceneModel` Spati
 
 *  JME3 offers a `CollisionShapeFactory` that precalculates a mesh-accurate collision shape for a Spatial. You choose to generate a `CompoundCollisionShape` (which has MeshCollisionShapes as its children) because this type of collision shape is optimal for immobile objects, such as terrain, houses, and whole shooter levels.
 *  You set the mass to zero since a scene is static and its mass is irrevelant.
-*  Add the control to the Spatial to give it physical properties. 
+*  Add the control to the Spatial to give it physical properties.
 *  As always, attach the sceneModel to the rootNode to make it visible.
 
 [TIP]
@@ -341,7 +341,7 @@ Again, you create a CollisionShape: This time you choose a CapsuleCollisionShape
 
 [TIP]
 ====
-“Does that CollisionShape make me look fat? If you ever get confusing physics behaviour, remember to have a look at the collision shapes. Add the following line after the bulletAppState initialization to make the shapes visible: 
+“Does that CollisionShape make me look fat? If you ever get confusing physics behaviour, remember to have a look at the collision shapes. Add the following line after the bulletAppState initialization to make the shapes visible:
 
 [source,java]
 ----
@@ -359,7 +359,7 @@ Now you use the CollisionShape to create a `CharacterControl` that represents th
 
     player.setJumpSpeed(20);
     player.setFallSpeed(30);
-    player.setGravity(30);
+    player.setGravity(new Vector3f(0,-30f,0));
 
 ----
 
@@ -372,7 +372,7 @@ Apart from step height and character size, the `CharacterControl` lets you confi
 
 ----
 
-Finally we put the player in its starting position and update its state – remember to use `setPhysicsLocation()` instead of `setLocalTranslation()` now, since you are dealing with a physical object. 
+Finally we put the player in its starting position and update its state – remember to use `setPhysicsLocation()` instead of `setLocalTranslation()` now, since you are dealing with a physical object.
 
 
 === PhysicsSpace
@@ -440,7 +440,7 @@ Remember that this class implements the `ActionListener` interface, so you can c
     } else if (binding.equals("Down")) {
       if (value) { down = true; } else { down = false; }
     } else if (binding.equals("Jump")) {
-      player.jump();
+      player.jump(new Vector3f(0,10,0));
     }
   }
 ----
@@ -483,8 +483,8 @@ This last and most important code snippet goes into the `simpleUpdate()` method.
 This is how the walking is triggered:
 
 .  Initialize the vector `walkDirection` to zero. This is where you want to store the calculated walk direction.
-..  Add to `walkDirection` the recent motion vectors that you polled from the camera. This way it is posible for a character to move forward and to the left simultaneously, for example! 
-..  This one last line does the “walking magic: 
+..  Add to `walkDirection` the recent motion vectors that you polled from the camera. This way it is posible for a character to move forward and to the left simultaneously, for example!
+..  This one last line does the “walking magic:
 +
 [source,java]
 ----
@@ -512,7 +512,7 @@ Again, do not use `setLocalTranslation()` to walk the player around. You will ge
 You have learned how to load a “solid physical scene model and walk around in it with a first-person perspective.
 You learned to speed up the physics calculations by using the CollisionShapeFactory to create efficient CollisionShapes for complex Geometries. You know how to add PhysicsControls to your collidable geometries and you register them to the PhysicsSpace. You also learned to use `player.setWalkDirection(walkDirection)` to move collision-aware characters around, and not `setLocalTranslation()`.
 
-Terrains are another type of scene in which you will want to walk around. Let's proceed with learning <<jme3/beginner/hello_terrain#,how to generate terrains>> now. 
+Terrains are another type of scene in which you will want to walk around. Let's proceed with learning <<jme3/beginner/hello_terrain#,how to generate terrains>> now.
 
 '''
 

+ 163 - 149
src/docs/asciidoc/jme3/beginner/hello_input_system.adoc

@@ -1,17 +1,18 @@
 = jMonkeyEngine 3 Tutorial (5) - Hello Input System
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: input, intro, beginner, documentation, keyinput, click
 :relfileprefix: ../../
 :imagesdir: ../..
+:experimental:
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
 Previous: <<jme3/beginner/hello_main_event_loop#,Hello Update Loop>>,
 Next: <<jme3/beginner/hello_material#,Hello Material>>
 
-By default, SimpleApplication sets up a camera control 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? 
+By default, SimpleApplication sets up a camera control that allows you to steer the camera with the kbd:[W] kbd:[A] kbd:[S] kbd:[D] 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?
 
 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.
 
@@ -36,97 +37,104 @@ import com.jme3.input.controls.AnalogListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.input.controls.MouseButtonTrigger;
 
-/** Sample 5 - how to map keys and mousebuttons to actions */
+/**
+ * Sample 5 - how to map keys and mousebuttons to actions
+ */
 public class HelloInput extends SimpleApplication {
 
-  public static void main(String[] args) {
-    HelloInput app = new HelloInput();
-    app.start();
-  }
-  protected Geometry player;
-  Boolean isRunning=true;
-
-  @Override
-  public void simpleInitApp() {
-    Box b = new Box(1, 1, 1);
-    player = new Geometry("Player", b);
-    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.Blue);
-    player.setMaterial(mat);
-    rootNode.attachChild(player);
-    initKeys(); // load my custom keybinding
-  }
-
-  /** Custom Keybinding: Map named actions to inputs. */
-  private void initKeys() {
-    // You can map one or several inputs to one named action
-    inputManager.addMapping("Pause",  new KeyTrigger(KeyInput.KEY_P));
-    inputManager.addMapping("Left",   new KeyTrigger(KeyInput.KEY_J));
-    inputManager.addMapping("Right",  new KeyTrigger(KeyInput.KEY_K));
-    inputManager.addMapping("Rotate", new KeyTrigger(KeyInput.KEY_SPACE),
-                                      new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
-    // Add the names to the action listener.
-    inputManager.addListener(actionListener,"Pause");
-    inputManager.addListener(analogListener,"Left", "Right", "Rotate");
-    
-  }
+    public static void main(String[] args) {
+        HelloInput app = new HelloInput();
+        app.start();
+    }
 
-  private ActionListener actionListener = new ActionListener() {
-    public void onAction(String name, boolean keyPressed, float tpf) {
-      if (name.equals("Pause") && !keyPressed) {
-        isRunning = !isRunning;
-      }
+    protected Geometry player;
+    private boolean isRunning = true;
+
+    @Override
+    public void simpleInitApp() {
+        Box b = new Box(1, 1, 1);
+        player = new Geometry("Player", b);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", ColorRGBA.Blue);
+        player.setMaterial(mat);
+        rootNode.attachChild(player);
+        initKeys(); // load my custom keybinding
     }
-  };
 
-  private AnalogListener analogListener = new AnalogListener() {
-    public void onAnalog(String name, float value, float tpf) {
-      if (isRunning) {
-        if (name.equals("Rotate")) {
-          player.rotate(0, value*speed, 0);
-        }
-        if (name.equals("Right")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x + value*speed, v.y, v.z);
+    /**
+     * Custom Keybinding: Map named actions to inputs.
+     */
+    private void initKeys() {
+        // You can map one or several inputs to one named action
+        inputManager.addMapping("Pause",  new KeyTrigger(KeyInput.KEY_P));
+        inputManager.addMapping("Left",   new KeyTrigger(KeyInput.KEY_J));
+        inputManager.addMapping("Right",  new KeyTrigger(KeyInput.KEY_K));
+        inputManager.addMapping("Rotate", new KeyTrigger(KeyInput.KEY_SPACE),
+                                          new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
+        // Add the names to the action listener.
+        inputManager.addListener(actionListener, "Pause");
+        inputManager.addListener(analogListener, "Left", "Right", "Rotate");
+
+    }
+
+    private final ActionListener actionListener = new ActionListener() {
+        @Override
+        public void onAction(String name, boolean keyPressed, float tpf) {
+            if (name.equals("Pause") && !keyPressed) {
+                isRunning = !isRunning;
+            }
         }
-        if (name.equals("Left")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x - value*speed, v.y, v.z);
+    };
+
+    private final AnalogListener analogListener = new AnalogListener() {
+        @Override
+        public void onAnalog(String name, float value, float tpf) {
+            if (isRunning) {
+                if (name.equals("Rotate")) {
+                    player.rotate(0, value * speed, 0);
+                }
+                if (name.equals("Right")) {
+                    Vector3f v = player.getLocalTranslation();
+                    player.setLocalTranslation(v.x + value * speed, v.y, v.z);
+                }
+                if (name.equals("Left")) {
+                    Vector3f v = player.getLocalTranslation();
+                    player.setLocalTranslation(v.x - value * speed, v.y, v.z);
+                }
+            } else {
+                System.out.println("Press P to unpause.");
+            }
         }
-      } else {
-        System.out.println("Press P to unpause.");
-      }
-    }
-  };
+    };
 }
 
 ----
 
 Build and run the example.
 
-*  Press the Spacebar or click to rotate the cube. 
-*  Press the J and K keys to move the cube.
-*  Press P to pause and unpause the game. While paused, the game should not respond to any input, other than `P`.
+*  Press the Spacebar or click to rotate the cube.
+*  Press the kbd:[J] and kbd:[K] keys to move the cube.
+*  Press kbd:[P] to pause and unpause the game. While paused, the game should not respond to any input, other than kbd:[P].
 
 
 == Defining Mappings and Triggers
 
 First you register each mapping name with its trigger(s). Remember the following:
 
-*  An input trigger can be a key press or mouse action. +
-For example a mouse movement, a mouse click, or pressing the letter “P.
-*  The mapping name is a string that you can choose. +
-The name should describe the action (e.g. “Rotate), and not the trigger. Because the trigger can change.
-*  One named mapping can have several triggers. +
-For example, the “Rotate action can be triggered by a click and by pressing the spacebar.
+*  An input trigger can be a key press or mouse action.
+**  For example a mouse movement, a mouse click, or pressing the letter kbd:[P] .
+*  The mapping name is a string that you can choose.
+**  The name should describe the action (e.g. "`Rotate`"), and not the trigger. Because the trigger can change.
+*  One named mapping can have several triggers.
+**  For example, the "`Rotate`" action can be triggered by a click and by pressing the spacebar.
 
 Have a look at the code:
 
-.  You register the mapping named “Rotate to the Spacebar key trigger. +
-`new KeyTrigger(KeyInput.KEY_SPACE)`). 
-.  In the same line, you also register “Rotate to an alternative mouse click trigger. +
+.  You register the mapping named "`Rotate`" to the Spacebar key trigger. +
+`new KeyTrigger(KeyInput.KEY_SPACE)`).
+.  In the same line, you also register "`Rotate`" to an alternative mouse click trigger. +
 `new MouseButtonTrigger(MouseInput.BUTTON_LEFT)`
-.  You map the `Pause`, `Left`, `Right` mappings to the P, J, K keys, respectively. 
+.  You map the `Pause`, `Left`, `Right` mappings to the P, J, K keys, respectively.
 +
 [source,java]
 ----
@@ -142,7 +150,7 @@ Have a look at the code:
 
 Now you need to register your trigger mappings.
 
-.  You register the pause action to the ActionListener, because it is an “on/off action.
+.  You register the pause action to the ActionListener, because it is an "`on/off`" action.
 .  You register the movement actions to the AnalogListener, because they are gradual actions.
 +
 [source,java]
@@ -161,82 +169,88 @@ This code goes into the `simpleInitApp()` method. But since we will likely add m
 
 You have mapped action names to input triggers. Now you specify the actions themselves.
 
-The two important methods here are the `ActionListener` with its `onAction()` method, and the `AnalogListener` with its `onAnalog()` method. In these two methods, you test for each named mapping, and call the game action you want to trigger. 
+The two important methods here are the `ActionListener` with its `onAction()` method, and the `AnalogListener` with its `onAnalog()` method. In these two methods, you test for each named mapping, and call the game action you want to trigger.
 
-In this example, we trigger the following actions: 
+In this example, we trigger the following actions:
 
-.  The _Rotate_ mapping triggers the action `player.rotate(0, value, 0)`. 
-.  The _Left_ and _Right_ mappings increase and decrease the player's x coordinate. 
-.  The _Pause_ mapping flips a boolean `isRunning`. 
+.  The _Rotate_ mapping triggers the action `player.rotate(0, value, 0)`.
+.  The _Left_ and _Right_ mappings increase and decrease the player's x coordinate.
+.  The _Pause_ mapping flips a boolean `isRunning`.
 .  We also want to check the boolean `isRunning` before any action (other than unpausing) is executed.
 
 [source,java]
 ----
 
-  private ActionListener actionListener = new ActionListener() {
-    public void onAction(String name, boolean keyPressed, float tpf) {
-      if (name.equals("Pause") && !keyPressed) {
-        isRunning = !isRunning;
-      }
-    }
-  };
 
-  private AnalogListener analogListener = new AnalogListener() {
-    public void onAnalog(String name, float value, float tpf) {
-      if (isRunning) {
-        if (name.equals("Rotate")) {
-          player.rotate(0, value*speed, 0);
-        }
-        if (name.equals("Right")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x + value*speed, v.y, v.z);
+    private final ActionListener actionListener = new ActionListener() {
+        @Override
+        public void onAction(String name, boolean keyPressed, float tpf) {
+            if (name.equals("Pause") && !keyPressed) {
+                isRunning = !isRunning;
+            }
         }
-        if (name.equals("Left")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x - value*speed, v.y, v.z);
+    };
+
+    private final AnalogListener analogListener = new AnalogListener() {
+        @Override
+        public void onAnalog(String name, float value, float tpf) {
+            if (isRunning) {
+                if (name.equals("Rotate")) {
+                    player.rotate(0, value * speed, 0);
+                }
+                if (name.equals("Right")) {
+                    Vector3f v = player.getLocalTranslation();
+                    player.setLocalTranslation(v.x + value * speed, v.y, v.z);
+                }
+                if (name.equals("Left")) {
+                    Vector3f v = player.getLocalTranslation();
+                    player.setLocalTranslation(v.x - value * speed, v.y, v.z);
+                }
+            } else {
+                System.out.println("Press P to unpause.");
+            }
         }
-      } else {
-        System.out.println("Press P to unpause.");
-      }
-    }
-  };
+    };
 ----
 
-You can also combine both listeners into one, the engine will send the appropriate events to each method (onAction or onAnalog). For example:
+You can also combine both listeners into one, the engine will send the appropriate events to each method (onAction or onAnalog).
+
+For example:
 
 [source,java]
 ----
 
-  private MyCombinedListener combinedListener = new MyCombinedListener();
+private class MyCombinedListener implements AnalogListener, ActionListener {
 
-  private static class MyCombinedListener implements AnalogListener, ActionListener {
+    @Override
     public void onAction(String name, boolean keyPressed, float tpf) {
-      if (name.equals("Pause") && !keyPressed) {
-        isRunning = !isRunning;
-      }
+        if (name.equals("Pause") && !keyPressed) {
+            isRunning = !isRunning;
+        }
     }
-    
+
+    @Override
     public void onAnalog(String name, float value, float tpf) {
-      if (isRunning) {
-        if (name.equals("Rotate")) {
-          player.rotate(0, value*speed, 0);
+        if (isRunning) {
+            if (name.equals("Rotate")) {
+                player.rotate(0, value * speed, 0);
+            }
+            if (name.equals("Right")) {
+                Vector3f v = player.getLocalTranslation();
+                player.setLocalTranslation(v.x + value * speed, v.y, v.z);
+            }
+            if (name.equals("Left")) {
+                Vector3f v = player.getLocalTranslation();
+                player.setLocalTranslation(v.x - value * speed, v.y, v.z);
+            }
+        } else {
+            System.out.println("Press P to unpause.");
         }
-        if (name.equals("Right")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x + value*speed, v.y, v.z);
-        }
-        if (name.equals("Left")) {
-          Vector3f v = player.getLocalTranslation();
-          player.setLocalTranslation(v.x - value*speed, v.y, v.z);
-        }
-      } else {
-        System.out.println("Press P to unpause.");
-      }
     }
-  }
+}
 // ...
 inputManager.addListener(combinedListener, new String[]{"Pause", "Left", "Right", "Rotate"});
-  
+
 ----
 
 It'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.
@@ -244,22 +258,22 @@ It's okay to use only one of the two Listeners, and not implement the other one,
 
 == Analog, Pressed, or Released?
 
-Technically, every input can be either an “analog or a “digital action. Here is how you find out which listener is the right one for which type of input.
+Technically, every input can be either an "`analog`" or a "`digital`" action. Here is how you find out which listener is the right one for which type of input.
 
 Mappings registered to the *AnalogListener* are triggered repeatedly and gradually.
 
-*  Parameters: 
+*  Parameters:
 ..  JME gives you access to the name of the triggered action.
 ..  JME gives you access to a gradual value showing the strength of that input. In the case of a keypress that will be the tpf value for which it was pressed since the last frame. For other inputs such as a joystick which give analogue control though then the value will also indicate the strength of the input premultiplied by tpf. For an example on this go to <<jme3/beginner/hello_input_system/timekeypressed#,jMonkeyEngine 3 Tutorial (5) - Hello Input System - Variation over time key is pressed>>
 
 
 In order to see the total time that a key has been pressed for then the incoming value can be accumulated. The analogue listener may also need to be combined with an action listener so that you are notified when the key is released.
 
-*  Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously. 
+*  Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously.
 
-Mappings registered to the *ActionListener* are digital either-or actions – “Pressed or released? On or off?
+Mappings registered to the *ActionListener* are digital either-or actions – "`Pressed`" or "`Peleased`"? "`On`" or "`Off`"?
 
-*  Parameters: 
+*  Parameters:
 ..  JME gives you access to the name of the triggered action.
 ..  JME gives you access to a boolean whether the key is pressed or not.
 
@@ -284,33 +298,33 @@ You can find the list of input constants in the files `src/core/com/jme3/input/K
 [cols="2", options="header"]
 |===
 
-a| Trigger 
-a| Code 
+a| Trigger
+a| Code
 
-a| Mouse button: Left Click 
-a| MouseButtonTrigger(MouseInput.BUTTON_LEFT) 
+a| Mouse button: Left Click
+a| MouseButtonTrigger(MouseInput.BUTTON_LEFT)
 
-a| Mouse button: Right Click 
-a| MouseButtonTrigger(MouseInput.BUTTON_RIGHT) 
+a| Mouse button: Right Click
+a| MouseButtonTrigger(MouseInput.BUTTON_RIGHT)
 
-a| Keyboard: Characters and Numbers 
-a| KeyTrigger(KeyInput.KEY_X) 
+a| Keyboard: Characters and Numbers
+a| KeyTrigger(KeyInput.KEY_X)
 
-<a| Keyboard: Spacebar  
-a| KeyTrigger(KeyInput.KEY_SPACE) 
+<a| Keyboard: Spacebar
+a| KeyTrigger(KeyInput.KEY_SPACE)
 
-a| Keyboard: Return, Enter 
+a| Keyboard: Return, Enter
 <a| KeyTrigger(KeyInput.KEY_RETURN), +
-KeyTrigger(KeyInput.KEY_NUMPADENTER)  
+KeyTrigger(KeyInput.KEY_NUMPADENTER)
 
-a| Keyboard: Escape 
-a| KeyTrigger(KeyInput.KEY_ESCAPE) 
+a| Keyboard: Escape
+a| KeyTrigger(KeyInput.KEY_ESCAPE)
 
-a| Keyboard: Arrows 
+a| Keyboard: Arrows
 a| KeyTrigger(KeyInput.KEY_UP), +
 KeyTrigger(KeyInput.KEY_DOWN) +
 KeyTrigger(KeyInput.KEY_LEFT), +
-KeyTrigger(KeyInput.KEY_RIGHT) 
+KeyTrigger(KeyInput.KEY_RIGHT)
 
 |===
 
@@ -323,15 +337,15 @@ If you don't recall an input constant during development, you benefit from an ID
 
 .  Add mappings for moving the player (box) up and down with the H and L keys!
 .  Switch off the flyCam and override the WASD keys.
-**  Tip: Use <<jme3/faq#how-do-i-switch-between-third-person-and-first-person-view,flyCam.setEnabled(false);>> 
+**  Tip: Use <<jme3/faq#how-do-i-switch-between-third-person-and-first-person-view,flyCam.setEnabled(false);>>
 
 .  Modify the mappings so that you can also trigger the up an down motion with the mouse scroll wheel!
 **  Tip: Use `new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true)`
 
-.  In which situation would it be better to use variables instead of literals for the MouseInput/KeyInput definitions? 
+.  In which situation would it be better to use variables instead of literals for the MouseInput/KeyInput definitions?
 [source,java]
 ----
-int usersPauseKey = KeyInput.KEY_P; 
+int usersPauseKey = KeyInput.KEY_P;
 ...
 inputManager.addMapping("Pause",  new KeyTrigger(usersPauseKey));
 
@@ -349,6 +363,6 @@ Link to user-proposed solutions: <<jm3/solutions#,Some proposed solutions>> +
 
 == Conclusion
 
-You are now able to add custom interactions to your game: You know 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 &#8220;analog (gradually repeated) and &#8220;digital (on/off) inputs.
+You are now able to add custom interactions to your game: You know 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.
 
 Now you can already write a little interactive game! But wouldn't it be cooler if these old boxes were a bit more fancy? Let's continue with learning about <<jme3/beginner/hello_material#,materials>>.

+ 18 - 17
src/docs/asciidoc/jme3/beginner/hello_main_event_loop.adoc

@@ -1,6 +1,6 @@
 = jMonkeyEngine 3 Tutorial (4) - Hello Update Loop
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: documentation, state, states, intro, beginner, control, loop
 :relfileprefix: ../../
@@ -28,7 +28,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Box;
 
 /** Sample 4 - how to trigger repeating actions from the main event loop.
- * In this example, you use the loop to make the player character 
+ * In this example, you use the loop to make the player character
  * rotate continuously. */
 public class HelloLoop extends SimpleApplication {
 
@@ -55,32 +55,32 @@ public class HelloLoop extends SimpleApplication {
     @Override
     public void simpleUpdate(float tpf) {
         // make the player rotate:
-        player.rotate(0, 2*tpf, 0); 
+        player.rotate(0, 2*tpf, 0);
     }
 }
 ----
 
-Build and run the file: You see a constantly rotating cube. 
+Build and run the file: You see a constantly rotating cube.
 
 
 == Understanding the Code
 
-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 usual, we initialize the player object in the `simpleInitApp()` method. 
+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 usual, we initialize the player object in the `simpleInitApp()` method.
 
 Now have a closer look at the `simpleUpdate()` method – this is the update loop.
 
-*  The `player.rotate(0, 2*tpf, 0);` line changes the rotation of the player object. 
-*  We use the `tpf` variable (“time per frame) to time this action depending on the current frames per second rate. This simply means that the cube rotates with the same speed on fast and slow machines, and the game remains playable.
-*  When the game runs, the rotate() code is executed again and again. 
+*  The `player.rotate(0, 2*tpf, 0);` line changes the rotation of the player object.
+*  We use the `tpf` variable ("`time per frame`") to time this action depending on the current frames per second rate. This simply means that the cube rotates with the same speed on fast and slow machines, and the game remains playable.
+*  When the game runs, the rotate() code is executed again and again.
 
 
 == Using the Update Loop
 
-A rotating object is just a simple example. In the update loop, you typically have many tests and trigger various game actions. This is where you 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.  
+A rotating object is just a simple example. In the update loop, you typically have many tests and trigger various game actions. This is where you 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.
 
 *  The `simpleUpdate()` method starts running after the `simpleInitApp()` method has initialized the scene graph and state variables.
 *  JME3 executes everything in the `simpleUpdate()` method repeatedly, as fast as possible.
-..  Use the loop to poll the game state and then initiate actions. 
+..  Use the loop to poll the game state and then initiate actions.
 ..  Use the loop to trigger reactions and update the game state.
 ..  Use the loop wisely, because having too many calls in the loop also slows down the game.
 
@@ -90,15 +90,16 @@ A rotating object is just a simple example. In the update loop, you typically ha
 
 Note the the three phases of every game:
 
-*  *Init:* The `simpleInitApp()` method is executed only _once_, right at the beginning; 
-*  *Update:* The `simpleUpdate()` method runs _repeatedly_, during the game. 
+*  *Init:* The `simpleInitApp()` method is executed only _once_, right at the beginning;
+*  *Update:* The `simpleUpdate()` method runs _repeatedly_, during the game.
 *  *Render:* After every update, the jMonkeyEngine _automatically_ redraws (`renders`) the screen for you.
 
 Since rendering is automatic, initialization and updating are the two most important concepts in a SimpleApplication-based game for you:
 
-*  The `simpleInitApp()` method is the application's “first breath. +
-Here you load and create game data (once).
-*  The `simpleUpdate()` method is the application's “heartbeat (the time unit is called `ticks`). +
+*  The `simpleInitApp()` method is the application's "`first breath`".
+**  Here you load and create game data (once).
+
+*  The `simpleUpdate()` method is the application's "`heartbeat`" (the time unit is called `ticks`). +
 Here you change their properties to update the game state (repeatedly).
 
 
@@ -138,7 +139,7 @@ Link to user-proposed solutions: <<jm3/solutions#,Some proposed solutions>> +
 
 == Conclusion
 
-Now you are listening to the update loop, the heart beat of the game, and you can add all kinds of action to it. 
+Now you are listening to the update loop, the "`heartbeat`" of the game, and you can add all kinds of action to it. 
 
 The next thing the game needs is some __inter__action! Continue learning how to <<jme3/beginner/hello_input_system#,respond to user input>>.
 

+ 91 - 88
src/docs/asciidoc/jme3/beginner/hello_node.adoc

@@ -1,6 +1,6 @@
 = jMonkeyEngine 3 Tutorial (2) - Hello Node
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: beginner, rootNode, node, intro, documentation, color, spatial, geometry, scenegraph, mesh
 :relfileprefix: ../../
@@ -9,7 +9,7 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
 Previous: <<jme3/beginner/hello_simpleapplication#,Hello SimpleApplication>>,
-Next: <<jme3/beginner/hello_asset#,Hello Assets>>. 
+Next: <<jme3/beginner/hello_asset#,Hello Assets>>.
 
 In this tutorial we will have a look at the creation of a 3D scene.
 
@@ -18,11 +18,11 @@ In this tutorial we will have a look at the creation of a 3D scene.
 
 When creating a 3D game
 
-.  You create some scene objects like players, buildings, etc. 
+.  You create some scene objects like players, buildings, etc.
 .  You add the objects to the scene.
-.  You move, resize, rotate, color, and animate them. 
+.  You move, resize, rotate, color, and animate them.
 
-You will learn that the scene graph represents the 3D world, and why the rootNode is important. You will learn how to create simple objects, how to let them carry custom data (such as health points), and how to “transform them by moving, scaling, and rotating. You will understand the difference between the two types of “Spatials in the scene graph: Nodes and Geometries. 
+You will learn that the scene graph represents the 3D world, and why the rootNode is important. You will learn how to create simple objects, how to let them carry custom data (such as health points), and how to "`transform`" them by moving, scaling, and rotating. You will understand the difference between the two types of "`Spatials`" in the scene graph: Nodes and Geometries.
 
 
 == Code Sample
@@ -56,16 +56,16 @@ public class HelloNode extends SimpleApplication {
         Box box1 = new Box(1,1,1);
         Geometry blue = new Geometry("Box", box1);
         blue.setLocalTranslation(new Vector3f(1,-1,1));
-        Material mat1 = new Material(assetManager, 
+        Material mat1 = new Material(assetManager,
                 "Common/MatDefs/Misc/Unshaded.j3md");
         mat1.setColor("Color", ColorRGBA.Blue);
         blue.setMaterial(mat1);
 
         /** create a red box straight above the blue one at (1,3,1) */
-        Box box2 = new Box(1,1,1);      
+        Box box2 = new Box(1,1,1);
         Geometry red = new Geometry("Box", box2);
         red.setLocalTranslation(new Vector3f(1,3,1));
-        Material mat2 = new Material(assetManager, 
+        Material mat2 = new Material(assetManager,
                 "Common/MatDefs/Misc/Unshaded.j3md");
         mat2.setColor("Color", ColorRGBA.Red);
         red.setMaterial(mat2);
@@ -92,22 +92,22 @@ In this tutorial, you learn some new terms:
 [cols="2", options="header"]
 |===
 
-a|What you want to do
+a|What you want to do?
 a|How you say it in JME3 terminology
 
-a|Lay out the 3D scene
-a|Populate the scene graph
+a|Lay out the 3D scene.
+a|Populate the scene graph.
 
-a|Create scene objects
-a|Create Spatials (e.g. create Geometries)
+a|Create scene objects.
+a|Create Spatials. (e.g. create Geometries)
 
-a|Make an object appear in the scene
-a|Attach a Spatial to the rootNode
+a|Make an object appear in the scene.
+a|Attach a Spatial to the rootNode.
 
-a|Make an object disappear from the scene
-a|Detach the Spatial from the rootNode
+a|Make an object disappear from the scene.
+a|Detach the Spatial from the rootNode.
 
-a|Position/move, turn, or resize an object
+a|Position/move, turn, or resize an object.
 a|Translate, or rotate, or scale an object = transform an object.
 
 |===
@@ -121,21 +121,21 @@ Every JME3 application has a rootNode: Your game automatically inherits the `roo
 [cols="10,45,45", options="header"]
 |===
 
-<a|  
-a| Geometry 
-a| Node 
+<a|
+a| Geometry
+a| Node
 
-a| Visibility: 
-a| A Geometry is a visible scene object. 
-a| A Node is an invisible “handle for scene objects. 
+a| Visibility:
+a| A Geometry is a visible scene object.
+a| A Node is an invisible "`handle`" for scene objects.
 
-a| Purpose: 
-a| A Geometry stores an object's looks. 
-a| A Node groups Geometries and other Nodes together. 
+a| Purpose:
+a| A Geometry stores an object's looks.
+a| A Node groups Geometries and other Nodes together.
 
-a| Examples: 
-a| A box, a sphere, a player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc… 
-a| The `rootNode`, a floor node grouping several terrains, a custom vehicle-with-passengers node, a player-with-weapon node, an audio node, etc… 
+a| Examples:
+a| A box, a sphere, a player, a building, a piece of terrain, a vehicle, missiles, NPCs, etc…
+a| The `rootNode`, a floor node grouping several terrains, a custom vehicle-with-passengers node, a player-with-weapon node, an audio node, etc…
 
 |===
 
@@ -148,7 +148,7 @@ What happens in the code snippet? You use the `simpleInitApp()` method that was
 **  Create a Box shape with extents of (1,1,1), that makes the box 2x2x2 world units big.
 **  Position the box at (1,-1,1) using the setLocalTranslation() method.
 **  Wrap the Box shape into a Geometry.
-**  Create a blue material. 
+**  Create a blue material.
 **  Apply the blue material to the Box Geometry.
 +
 [source,java]
@@ -164,12 +164,11 @@ What happens in the code snippet? You use the `simpleInitApp()` method that was
 
 
 .  You create a second box Geometry.
-+
 **  Create a second Box shape with the same size.
 **  Position the second box at (1,3,1). This is straight above the first box, with a gap of 2 world units inbetween.
 **  Wrap the Box shape into a Geometry.
-**  Create a red material. 
-**  Apply the red material to the Box Geometry. 
+**  Create a red material.
+**  Apply the red material to the Box Geometry.
 +
 [source,java]
 ----
@@ -184,33 +183,35 @@ What happens in the code snippet? You use the `simpleInitApp()` method that was
 ----
 
 
-.  You create a pivot Node. 
-+
-**  Name the Node “pivot.
-**  By default the Node is positioned at (0,0,0). 
+.  You create a pivot Node.
+**  Name the Node "`pivot`".
+**  By default the Node is positioned at (0,0,0).
 **  Attach the Node to the rootNode.
-**  The Node has no visible appearance in the scene. 
+**  The Node has no visible appearance in the scene.
 +
+--
 [source,java]
 ----
 
     Node pivot = new Node("pivot");
     rootNode.attachChild(pivot);
 ----
-+
-If you run the application with only the code up to here, the scene appears empty. This is because a Node is invisible, and you have not yet attached any visible Geometries to the rootNode. 
 
+If you run the application with only the code up to here, the scene appears empty. This is because a Node is invisible, and you have not yet attached any visible Geometries to the rootNode.
+--
 
-.  Attach the two boxes to the pivot node. 
+.  Attach the two boxes to the pivot node.
 +
+--
 [source,java]
 ----
 
         pivot.attachChild(blue);
         pivot.attachChild(red);
 ----
-+
+
 If you run the app with only the code up to here, you see two cubes: A red cube straight above a blue cube.
+--
 
 .  Rotate the pivot node.
 +
@@ -218,50 +219,52 @@ If you run the app with only the code up to here, you see two cubes: A red cube
 ----
         pivot.rotate( 0.4f , 0.4f , 0.0f );
 ----
-+
-If you run the app now, you see two boxes on top of each other – both tilted at the same angle.
 
+If you run the app now, you see two boxes on top of each other – both tilted at the same angle.
 
 
 === What is a Pivot Node?
 
 You can transform (e.g. rotate) Geometries around their own center, or around a user defined center point. A user defined center point for one or more Geometries is called a pivot.
 
-*  In this example, you have grouped two Geometries by attaching them to one pivot Node. You use the pivot Node as a handle to rotate the two Geometries together around one common center. Rotating the pivot Node rotates all attached Geometries, in one step. The pivot node is the center of the rotation. Before attaching the other Geometries, make certain that the pivot node is at (0,0,0). Transforming a parent Node to transform all attached child Spatials is a common task. You will use this method a lot in your games when you move Spatials around. +
-*Examples:* A vehicle and its driver move together; a planet with its moon orbits the sun. 
-*  Contrast this case with the other option: If you don't create an extra pivot node and transform a Geometry, then every transformation is done relative to the Geometry's origin (typically the center). +
+In this example, you have grouped two Geometries by attaching them to one pivot Node. You use the pivot Node as a handle to rotate the two Geometries together around one common center. Rotating the pivot Node rotates all attached Geometries, in one step. The pivot node is the center of the rotation. Before attaching the other Geometries, make certain that the pivot node is at (0,0,0). Transforming a parent Node to transform all attached child Spatials is a common task. You will use this method a lot in your games when you move Spatials around.
+
+*Examples:* A vehicle and its driver move together; a planet with its moon orbits the sun.
+
+Contrast this case with the other option. If you don't create an extra pivot node and transform a Geometry, then every transformation is done relative to the Geometry's origin (typically the center).
+
 *Examples:* If you rotate each cube directly (using `red.rotate(0.1f , 0.2f , 0.3f);` and `blue.rotate(0.5f , 0.0f , 0.25f);`), then each cube is rotated individually around its center. This is similar to a planet rotating around its own center.
 
 
 == How do I Populate the Scenegraph?
-[cols="2", options="header"]
+[cols="30,70", options="header"]
 |===
 
-a| Task…? 
-a| Solution! 
+a| Task…?
+a| Solution!
 
-a| Create a Spatial 
-a| Create a Mesh shape, wrap it into a Geometry, and give it a Material. For example: 
+a| Create a Spatial.
+a| Create a Mesh shape, wrap it into a Geometry, and give it a Material. For example:
 [source,java]
 ----
 Box mesh = new Box(Vector3f.ZERO, 1, 1, 1); // a cuboid default mesh
-Geometry thing = new Geometry("thing", mesh); 
+Geometry thing = new Geometry("thing", mesh);
 Material mat = new Material(assetManager,
    "Common/MatDefs/Misc/ShowNormals.j3md");
 thing.setMaterial(mat);
 ----
 
 
-a| Make an object appear in the scene 
-a| Attach the Spatial to the `rootNode`, or to any node that is attached to the rootNode. 
+a| Make an object appear in the scene.
+a| Attach the Spatial to the `rootNode`, or to any node that is attached to the rootNode.
 [source,java]
 ----
 rootNode.attachChild(thing);
 ----
 
 
-a| Remove objects from the scene 
-a| Detach the Spatial from the `rootNode`, and from any node that is attached to the rootNode. 
+a| Remove objects from the scene.
+a| Detach the Spatial from the `rootNode`, and from any node that is attached to the rootNode.
 [source,java]
 ----
 rootNode.detachChild(thing);
@@ -273,8 +276,8 @@ rootNode.detachAllChildren();
 ----
 
 
-a| Find a Spatial in the scene by the object's name, or ID, or by its position in the parent-child hierarchy. 
-a| Look at the node's children or parent: 
+a| Find a Spatial in the scene by the object's name, or ID, or by its position in the parent-child hierarchy.
+a| Look at the node's children or parent:
 [source,java]
 ----
 Spatial thing = rootNode.getChild("thing");
@@ -291,8 +294,8 @@ Spatial parent = myNode.getParent();
 ----
 
 
-a| Specify what should be loaded at the start 
-a| Everything you initialize and attach to the `rootNode` in the `simpleInitApp()` method is part of the scene at the start of the game. 
+a| Specify what should be loaded at the start.
+a| Everything you initialize and attach to the `rootNode` in the `simpleInitApp()` method is part of the scene at the start of the game.
 
 |===
 
@@ -303,19 +306,19 @@ There are three types of 3D transformation: Translation, Scaling, and Rotation.
 [cols="55,15,15,15", options="header"]
 |===
 
-a| Translation moves Spatials 
-a| X-axis 
-a| Y-axis 
-a| Z-axis 
+a| Translation moves Spatials
+a| X-axis
+a| Y-axis
+a| Z-axis
 
 a| Specify the new location in three dimensions: How far away is it from the origin going right-up-forward? +
-To move a Spatial _to_ specific coordinates, such as (0,40.2f,-2), use: 
+To move a Spatial _to_ specific coordinates, such as (0,40.2f,-2), use:
 [source,java]
 ----
 thing.setLocalTranslation( new Vector3f( 0.0f, 40.2f, -2.0f ) );
 ----
 
- To move a Spatial _by_ a certain amount, e.g. higher up (y=40.2f) and further back (z=-2.0f): 
+ To move a Spatial _by_ a certain amount, e.g. higher up (y=40.2f) and further back (z=-2.0f):
 
 [source,java]
 ----
@@ -330,15 +333,15 @@ a|+forward -backward
 [cols="55,15,15,15", options="header"]
 |===
 
-a| Scaling resizes Spatials 
-a| X-axis 
-a| Y-axis 
-a| Z-axis 
+a| Scaling resizes Spatials
+a| X-axis
+a| Y-axis
+a| Z-axis
 
 a|Specify the scaling factor in each dimension: length, height, width. +
 A value between 0.0f and 1.0f shrinks the Spatial; bigger than 1.0f stretches it; 1.0f keeps it the same. +
 Using the same value for each dimension scales proportionally, different values stretch it. +
-To scale a Spatial 10 times longer, one tenth the height, and keep the same width: 
+To scale a Spatial 10 times longer, one tenth the height, and keep the same width:
 [source,java]
 ----
 thing.scale( 10.0f, 0.1f, 1.0f );
@@ -352,23 +355,23 @@ a|width
 [cols="55,15,15,15", options="header"]
 |===
 
-a| Rotation turns Spatials 
+a| Rotation turns Spatials
 a| X-axis (Pitch)
 a| Y-axis (Yaw)
 a| Z-axis (Roll)
 
 a|3-D rotation is a bit tricky (<<jme3/rotate#,learn details here>>). In short: You can rotate around three axes: Pitch, yaw, and roll. You can specify angles in degrees by multiplying the degrees value with `FastMath.DEG_TO_RAD`. +
-To roll an object 180° around the z axis: 
+To roll an object 180° around the z axis:
 [source,java]
 ----
 thing.rotate( 0f , 0f , 180*FastMath.DEG_TO_RAD );
 ----
 
-Tip: If your game idea calls for a serious amount of rotations, it is worth looking into <<jme3/quaternion#,quaternions>>, a data structure that can combine and store rotations efficiently. 
+Tip: If your game idea calls for a serious amount of rotations, it is worth looking into <<jme3/quaternion#,quaternions>>, a data structure that can combine and store rotations efficiently.
 
 [source,java]
 ----
-thing.setLocalRotation( 
+thing.setLocalRotation(
   new Quaternion().fromAngleAxis(180*FastMath.DEG_TO_RAD, new Vector3f(1,0,0)));
 ----
 
@@ -385,25 +388,25 @@ If you get unexpected results, check whether you made the following common mista
 [cols="40,60", options="header"]
 |===
 
-a| Problem? 
-a| Solution! 
+a| Problem?
+a| Solution!
 
-a| A created Geometry does not appear in the scene. 
+a| A created Geometry does not appear in the scene.
 a| Have you attached it to (a node that is attached to) the rootNode? +
 Does it have a Material? +
 What is its translation (position)? +
 Is it behind the camera or covered up by another Geometry? +
 Is it too tiny or too gigantic to see? +
-Is it too far from the camera? (Try link:http://javadoc.jmonkeyengine.org/com/jme3/renderer/Camera.html#setFrustumFar(float)[cam.setFrustumFar](111111f); to see further) 
+Is it too far from the camera? (Try link:http://javadoc.jmonkeyengine.org/com/jme3/renderer/Camera.html#setFrustumFar(float)[cam.setFrustumFar](111111f); to see further)
 
-a| A Spatial rotates in unexpected ways. 
+a| A Spatial rotates in unexpected ways.
 a| Did you use radian values, and not degrees? (If you used degrees, multiply them with FastMath.DEG_TO_RAD to convert them to radians)  +
 Did you create the Spatial at the origin (Vector.ZERO) before moving it? +
 Did you rotate around the intended pivot node or around something else? +
-Did you rotate around the right axis? 
+Did you rotate around the right axis?
 
-a| A Geometry has an unexpected Color or Material. 
-<a| Did you reuse a Material from another Geometry and have inadvertently changed its properties? (If so, consider cloning it: mat2 = mat.clone(); )  
+a| A Geometry has an unexpected Color or Material.
+<a| Did you reuse a Material from another Geometry and have inadvertently changed its properties? (If so, consider cloning it: mat2 = mat.clone(); )
 
 |===
 
@@ -412,7 +415,7 @@ a| A Geometry has an unexpected Color or Material.
 
 Many Spatials represent game characters or other entities that the player can interact with. The above code that rotates the two boxes around a common center (pivot) could be used for a spacecraft docked to a orbiting space station, for example.
 
-Depending on your game, game entities do not only change their position, rotation, or scale (the transformations that you just learned about). Game entities also have custom properties, such as health, inventory carried, equipment worn for a character, or hull strength and fuel left for a spacecraft. In Java, you represent entity data as class variables, e.g. floats, Strings, or Arrays. 
+Depending on your game, game entities do not only change their position, rotation, or scale (the transformations that you just learned about). Game entities also have custom properties, such as health, inventory carried, equipment worn for a character, or hull strength and fuel left for a spacecraft. In Java, you represent entity data as class variables, e.g. floats, Strings, or Arrays.
 
 You can add custom data directly to any Node or Geometry. *You do not need to extend the Node class to include variables*!
 For example, to add a custom id number to a node, you would use:
@@ -426,7 +429,7 @@ To read this Node's id number elsewhere, you would use:
 
 [source,java]
 ----
-int id = pivot.getUserData( "pivot id" ); 
+int id = pivot.getUserData( "pivot id" );
 ----
 
 By using different Strings keys (here the key is `pivot id`), you can get and set several values for whatever data the Spatial needs to carry. When you start writing your game, you might add a fuel value to a car node, speed value to an airplane node, or number of gold coins to a player node, and much more. However, one should note that only custom objects that implements Savable can be passed.

+ 41 - 36
src/docs/asciidoc/jme3/beginner/hello_simpleapplication.adoc

@@ -1,10 +1,11 @@
 = jMonkeyEngine 3 Tutorial (1) - Hello SimpleApplication
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: beginner, intro, documentation, init, simpleapplication, basegame
 :relfileprefix: ../../
 :imagesdir: ../..
+:experimental:
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
@@ -13,7 +14,7 @@ Next: <<jme3/beginner/hello_node#,Hello Node>>
 
 *Prerequisites:* This tutorial assumes that you have <<documentation#,downloaded the jMonkeyEngine SDK>>.
 
-In this tutorial series, we assume that you use the jMonkeyEngine <<sdk#,SDK>>. As an intermediate or advanced Java developer, you will quickly see that, in general, you can develop jMonkeyEngine code in any integrated development environment (NetBeans IDE, Eclipse, IntelliJ) or even from the <<jme3/simpleapplication_from_the_commandline#,command line>>. 
+In this tutorial series, we assume that you use the jMonkeyEngine <<sdk#,SDK>>. As an intermediate or advanced Java developer, you will quickly see that, in general, you can develop jMonkeyEngine code in any integrated development environment (NetBeans IDE, Eclipse, IntelliJ) or even from the <<jme3/simpleapplication_from_the_commandline#,command line>>.
 
 OK, let's get ready to create our first jMonkeyEngine3 application.
 
@@ -22,13 +23,14 @@ OK, let's get ready to create our first jMonkeyEngine3 application.
 
 In the jMonkeyEngine SDK:
 
-.  Choose File→New Project… from the main menu.
-.  In the New Project wizard, select the template JME3→Basic Game. Click Next. 
-..  Specify a project name, e.g. “HelloWorldTutorial
+.  Choose `menu:File[New Project]` from the main menu.
+.  In the New Project wizard, select the template `menu:JME3[Basic Game]`.
+.  Click btn:[Next].
+..  Specify a project name, e.g. "`HelloWorldTutorial`".
 ..  Specify a path where to store your new project, e.g. a `jMonkeyProjects` directory in your home directory.
+.  Click btn:[Finish].
 
-.  Click Finish. 
-
+This will create a basic jme3 application for an easy start with jme3. You can click the run button to run it: You will see a blue cube.
 If you have questions, read more about <<sdk/project_creation#,Project Creation>> here.
 
 
@@ -41,18 +43,22 @@ We recommend to go through the steps yourself, as described in the tutorials. Al
 
 == Extend SimpleApplication
 
-For this tutorial, you want to create a jme3test.helloworld package in your project, and create a file HelloJME3.java in it.
+For this tutorial, you need a jme3test.helloworld package in your project, with the file HelloJME3.java in it.
 
 In the jMonkeyEngine SDK:
 
-.  Right-click the Source Packages node of your project.
-.  Choose New…→Java Class to create a new file.
-.  Enter the class name: HelloJME3
-.  Enter the package name: jme3test.helloworld.
-.  Click Finish.
+.  In the `Source Packages` node of your project, btn:[RMB] select the "`mygame`" package.
+..  Choose: `menu:Refactor[Rename]`
+..  Enter the New Name: `jme3test.helloworld`
+..  Click btn:[Refactor] when ready.
+.  In the newly refactored package, btn:[RMB] select the `Main.java` class.
+..   Choose: `menu:Refactor[Rename]`
+..  Enter the New Name: `HelloJME3`
+..  Click btn:[Refactor] when ready.
 
-The SDK creates the file HelloJME3.java for you.
+You follow this same basic procedure for the remaining tutorials.
 
+TIP: The remaining tutorials all use the same `jme3test.helloworld` package. Just refactor the "`Main.java`" class name to the tutorial examples class name rather than creating a new project for each.
 
 == Code Sample
 
@@ -65,7 +71,6 @@ package jme3test.helloworld;
 
 import com.jme3.app.SimpleApplication;
 import com.jme3.material.Material;
-import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Box;
 import com.jme3.math.ColorRGBA;
@@ -79,7 +84,7 @@ public class HelloJME3 extends SimpleApplication {
         HelloJME3 app = new HelloJME3();
         app.start(); // start the game
     }
-    
+
     @Override
     public void simpleInitApp() {
         Box b = new Box(1, 1, 1); // create cube shape
@@ -93,12 +98,12 @@ public class HelloJME3 extends SimpleApplication {
 }
 ----
 
-Right-click the HelloJME3 class and choose Run. If a jME3 settings dialog pops up, confirm the default settings.
+btn:[RMB] select the `HelloJME3` class and choose `Run`. If a jME3 settings dialog pops up, confirm the default settings.
 
 .  You should see a simple window displaying a 3D cube.
-.  Press the WASD keys and move the mouse to navigate around.
+.  Press the kbd:[W] kbd:[A] kbd:[S] kbd:[D] keys and move the mouse to navigate around.
 .  Look at the FPS text and object count information in the bottom left. You will use this information during development, and you will remove it for the release. (To read the numbers correctly, consider that the 14 lines of text counts as 14 objects with 914 vertices.)
-.  Press Escape to close the application.
+.  Press kbd:[Esc]  to close the application.
 
 Congratulations! Now let's find out how it works!
 
@@ -110,7 +115,7 @@ The code above has initialized the scene, and started the application.
 
 === Start the SimpleApplication
 
-Look at the first line. Your HelloJME3.java class extends `com.jme3.app.SimpleApplication`. 
+Look at the first line. Your HelloJME3.java class extends `com.jme3.app.SimpleApplication`.
 
 [source,java]
 ----
@@ -126,7 +131,7 @@ Every JME3 game is an instance of the `com.jme3.app.SimpleApplication` class. Th
 You start every JME3 game from the main() method, as every standard Java application:
 
 .  Instantiate your `SimpleApplication`-based class
-.  Call the application's `start()` method to start the game engine. 
+.  Call the application's `start()` method to start the game engine.
 
 [source,java]
 ----
@@ -170,7 +175,7 @@ If you are unfamiliar with the vocabulary, read more about <<jme3/the_scene_grap
 
 === Initialize the Scene
 
-Look at rest of the code sample. The `simpleInitApp()` method is automatically called once at the beginning when the application starts. Every JME3 game must have this method. In the `simpleInitApp()` method, you load game objects before the game starts. 
+Look at rest of the code sample. The `simpleInitApp()` method is automatically called once at the beginning when the application starts. Every JME3 game must have this method. In the `simpleInitApp()` method, you load game objects before the game starts.
 
 [source,java]
 ----
@@ -205,34 +210,34 @@ A typical JME3 game has the following initialization process:
 **  You make objects appear in the scene by attaching them to the `rootNode`.
 **  *Examples:* Load player, terrain, sky, enemies, obstacles, …, and place them in their start positions.
 
-.  You initialize variables
-**  You create variables to track the game state. 
-**  You set variables to their start values. 
+.  You initialize variables:
+**  You create variables to track the game state.
+**  You set variables to their start values.
 **  *Examples:* Set the `score` to 0, set `health` to 100%, …
 
-.  You initialize keys and mouse actions.
+.  You initialize keys and mouse actions:
 **  The following input bindings are pre-configured:
-***  W,A,S,D keys – Move around in the scene
+***  kbd:[W] kbd:[A] kbd:[S] kbd:[D] keys – Move around in the scene
 ***  Mouse movement and arrow keys – Turn the camera
-***  Escape key – Quit the game
+***  kbd:[Esc]  key – Quit the game
 
 **  Define your own additional keys and mouse click actions.
-**  *Examples:* Click to shoot, press Space to jump, …
+**  *Examples:* Click to shoot, press kbd:[Space] to jump, …
 
 
 
 === The Future of SimpleApplication
 
 
-There are plans to change SimpleApplication. Sometime back it was decided that we should really re-factor the Application class. SimpleApplication especially is a mess of 'magic' protected fields that on the one hand makes it really easy to slam some simple one-class application together, but on the other hand does new users no favors because they have no idea where 'cam' and 'assetManager' come from. Unfortunately, lots of code refers to Application and it's tough to change... especially the app states.
+There are plans to change SimpleApplication. Sometime back it was decided that we should really re-factor the Application class. SimpleApplication especially is a mess of "`magic`" protected fields that on the one hand makes it really easy to slam some simple one-class application together, but on the other hand does new users no favors because they have no idea where 'cam' and 'assetManager' come from. Unfortunately, lots of code refers to Application and it's tough to change... especially the app states.
 
-So, we hatched a plan to convert the Application class to an interface. This would give us some freedom to iterate on a new set of application base classes. You can read about the changes link:https://hub.jmonkeyengine.org/t/jmonkeyengine-3-1-alpha-4-released/35478[here]. As said before we are envisioning a better design that is not enforced today, but that is already usable. 
+So, we hatched a plan to convert the Application class to an interface. This would give us some freedom to iterate on a new set of application base classes. You can read about the changes link:https://hub.jmonkeyengine.org/t/jmonkeyengine-3-1-alpha-4-released/35478[here]. As said before we are envisioning a better design that is not enforced today, but that is already usable.
 
 If you look at SimpleApplication default constructor you will understand how it works.
 
 [source,java]
 ----
-public SimpleApplication() {    
+public SimpleApplication() {   
     this(new StatsAppState(), new FlyCamAppState(), new AudioListenerState(), new DebugKeysAppState());}
 ----
 
@@ -240,7 +245,7 @@ Basically the application is injected upon construction with the default AppStat
 
 [source,java]
 ----
-public SimpleApplication( AppState... initialStates ) {    
+public SimpleApplication( AppState... initialStates ) {   
     super(initialStates);
 }
 ----
@@ -250,7 +255,7 @@ It allows you to specify what AppState you want for your application. So SimpleA
 [source,java]
 ----
 public class MyGame extends SimpleApplication {
-    
+
     public MyGame(){
          super(new MyCustomSate(), new AnotherState(), ....);
     }
@@ -279,7 +284,7 @@ You have learned that a SimpleApplication is a good starting point because it pr
 When developing a game application, you want to:
 
 .  Initialize the game scene
-.  Trigger game actions 
+.  Trigger game actions
 .  Respond to user input.
 
 The now following tutorials teach how you accomplish these tasks with the jMonkeyEngine 3.

+ 3 - 0
src/docs/asciidoc/jme3/build_jme3_sources_with_netbeans.adoc

@@ -74,6 +74,9 @@ To update *your fork* on GitHub:
 .  Select the "`compare across forks`" link.
 .  Click the btn:[Head Fork] button and from the drop down list select "`jMonkeyEngine/jmonkeyengine`".
 .  Click the green button btn:[Create pull request].
+.  Give a succinct and informative title, in the comment field give a short explanation of the changes and click the green button btn:[Create pull request] again.
+.  Select the btn:[Commit And Merge] button.
+.  Press the btn:[Commit And Merge] button again to confirm your choice.
 
 To submit changes to the jMonkeyEngine repository after pushing them to *your fork*:
 

+ 95 - 0
src/docs/asciidoc/jme3/build_sources_netbeans_svn.adoc

@@ -0,0 +1,95 @@
+= Setting up JME3 in Netbeans 6+
+:author:
+:revnumber:
+:revdate: 2016/03/17 20:48
+:keywords: documentation, install
+:relfileprefix: ../
+:imagesdir: ..
+ifdef::env-github,env-browser[:outfilesuffix: .adoc]
+
+
+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. These instructions work in NetBeans IDE 6 or better.
+
+Note: In the following, always replace “~ with the path to your home directory.
+
+
+== Downloading the Sources
+
+Check out the sources from the repository. (The following NetBeans instructions are equivalent to executing `cd ~/NetBeansProjects; svn checkout link:http://jmonkeyengine.googlecode.com/svn/branches/3.0final/engine[http://jmonkeyengine.googlecode.com/svn/branches/3.0final/engine] jme3` on the commandline.)
+
+.  In NetBeans go to Team &gt; Subversion &gt; Checkout
+..  Repository +++<abbr title="Uniform Resource Locator">URL</abbr>+++: `link:https://jmonkeyengine.googlecode.com/svn[https://jmonkeyengine.googlecode.com/svn]`
+..  You can leave user/pw blank for anonymous access.
+
+.  Click Next
+..  Repository Folders: `branches/3.0final/engine`
+..  Enable the checkbox to Skip “engine and only checkout its contents.
+..  Local Folder: `~/NetBeansProjects/jme3`
+
+.  Click Finish and wait.
+
+The jme3 project opens in the Project window. It already includes a working ANT build script for building and running.
+
+Look into the Libraries node and confirm that the project depends on the following libraries in the classpath:
+
+*  j-ogg-oggd.jar
+*  j-ogg-vorbisd.jar
+*  jbullet.jar
+*  stack-alloc.jar
+*  vecmath.jar
+*  lwjgl.jar
+*  jME3-lwjgl-natives.jar
+*  jinput.jar
+*  eventbus.jar
+*  nifty-default-controls.jar
+*  nifty-examples.jar
+*  nifty-style-black.jar
+*  nifty.jar
+*  jglfont-core.jar
+*  xmlpull-xpp3.jar
+*  android.jar
+*  jME3-bullet-natives.jar
+*  gluegen-rt.jar
+*  joal.jar
+*  jogl-all.jar
+*  jME3-natives-joal.jar
+*  jME3-openal-soft-natives-android.jar
+
+For a detailed description of the separate jar files see <<jme3/jme3_source_structure#structure_of_jmonkeyengine3_jars,this list>>.
+
+
+== Build the Project and Run a Sample App
+
+.  Right-click the jme3 project node and “Clean and Build the project.
+.  In the Projects window, open the `Test` folder which contains the sample apps.
+.  Every file with a Main class (for example `jme3test.model/TestHoverTank.java` or `jme3test.game/CubeField.java`) is an app.
+.  Right-click a sample app and choose “Run File (Shift-F6).
+.  Generally in sample apps:
+..  the mouse and the WASD keys control movement
+..  the Esc key exits the application
+
+
+
+== Optional: Javadoc Popups and Source Navigation in NetBeans
+
+If you are working on the jme3 sources:
+
+.  In the Projects window, right-click the jme3 project and choose Generate Javadoc. Wait.
+.  Confirm in the Files window that the javadoc has been created in `~/NetBeansProjects/jme3/dist/javadoc`
+.  In the editor, place the caret in a jme class and press ctrl-space to view javadoc.
+
+If you are working on a game project that depends on jme3:
+
+.  First follow the previous tip. (In the future, we may offer jme javadoc as download instead.)
+.  In your game project, right-click the Libraries node and choose “Properties.
+.  In the Library properties, select jme3.jar and click the Edit button.
+..  For the Javadoc field, browse to `~/NetBeansProjects/jme3/dist/javadoc`. Check “as relative path and click select.
+..  For the Sources field, browse to `~/NetBeansProjects/jme3/src`. Check “as relative path and click select.
+..  Click OK.
+
+.  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.
+
+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).
+'''
+
+Sources used: link:http://code.google.com/p/jmonkeyengine/wiki/BuildJme3[BuildJme3], link:http://www.jmonkeyengine.com/forum/index.php?topic=13108.0[NetBeans tutorial from forum]

+ 1 - 1
src/docs/asciidoc/jme3/contributions.adoc

@@ -14,7 +14,7 @@ The following list contains additional content for jMonkeyEngine 3 contributed b
 [TIP]
 ====
 To install a jMonkeyEngine SDK plugin, go to `menu:Tools[Plugins>Available Plugins]`. +
-(Currently only jME 3.0 stable SDK, jME 3.1 stable does not yet support plugins)
+(Currently only jME 3.0 stable SDK, jME 3.1+ does not yet support plugins)
 ====
 
 

+ 203 - 141
src/docs/asciidoc/jme3/external/blender.adoc

@@ -1,6 +1,6 @@
 = Creating assets in Blender3D
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :relfileprefix: ../../
 :imagesdir: ../..
@@ -8,7 +8,7 @@
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
-This section discusses how to create and import models from Blender3D (2.62+, see bottom of page for Blender 2.49 and before) to jME3. Furthermore it explains how you can create various typical game-related assets like normal maps of high-poly models and baked lighting maps.
+This section discusses how to create and import models from Blender3D (2.78+, see bottom of page for Blender 2.49 and before) to jME3. Furthermore, it explains how you can create various typical game-related assets like "`Normal`" maps of high-poly models and "`Baked Lighting`" maps.
 
 
 == Asset Management
@@ -18,17 +18,19 @@ For the managing of assets in general, be sure to read the <<jme3/intermediate/m
 
 == Creating Models
 
-Game-compatible models are models that basically only consist of a mesh and UV-mapped textures, in some cases animations. All other material parameters or effects (like particles etc.) can not be expected to be transferred properly and probably would not translate to live rendering very well anyway.
+Game-compatible models are models that basically only consist of a mesh and UV-mapped textures, in some cases animations. All other material parameters or effects (like particles, etc.) cannot be expected to be transferred properly and probably would not translate to live rendering very well anyway.
 
 
 === UV Mapped Textures
 
-To successfully import a texture, the texture *has to* be UV-mapped to the model. Heres how to assign diffuse, normal and specular maps:
+To successfully import a texture, the texture *has to* be UV-mapped to the model. Heres how to assign "`Diffuse`", "`Normal`" and "`Specular`" maps:
 
-*  image:jme3/external/blender-material-4.png[blender-material-4.png,width="300",height=""] image:jme3/external/blender-material-3.png[blender-material-3.png,width="350",height=""]
-**  image:jme3/external/blender-material-2.png[blender-material-2.png,width="300",height=""] image:jme3/external/blender-material-1.png[blender-material-1.png,width="150",height=""]
+image::jme3/external/blender-material-4.png[blender-material-4.png,width="",height=""]
+image::jme3/external/blender-material-3.png[blender-material-3.png,width="",height=""]
+image::jme3/external/blender-material-2.png[blender-material-2.png,width="",height=""]
+image::jme3/external/blender-material-1.png[blender-material-1.png,width="",height=""]
 
-Its important to note that each used texture will create one separate geometry. So its best to either combine the UV maps or use a premade atlas with different texture types from the start and then map the uv coords of the models to the atlas instead of painting on the texture. This works best for large models like cities and space ships.
+It's important to note that each used texture will create one separate geometry. So it's best to either combine the UV maps or use a pre-made atlas with different texture types from the start and then map the uv coords of the models to the atlas instead of painting on the texture. This works best for large models like cities and space ships.
 
 
 === Animations
@@ -37,23 +39,26 @@ Animations for jME3 have to be bone animations, simple object movement is suppor
 
 To create an animation from scratch do the following:
 
-*  Create the model.
-**  Make sure your models location, rotation and scale is applied and zero / one (see “Model Checklist below).
-**  (Did you know? You can make any model from a box by only using extrusion, this creates very clean meshes.)
+.  Create the model.
+..  Make sure your models location, rotation and scale is applied and zero / one (see "`Model Checklist`" below).
++
+TIP: Did you know? You can make any model from a box by only using extrusion, this creates very clean meshes.
 
-*  Create the armature bones, don't forget to have one root bone!
-**  Start by placing the cursor at zero.
-**  Go to the `menu:Add[Armature > Single Bone]` menu and create the root bone. 
-***  image:jme3/external/blender-add-bone.png[blender-add-bone.png,width="",height=""]
+.  Create the armature bones, don't forget to have one root bone!
+..  Start by placing the cursor at zero.
+..  Go to the `menu:Add[Armature > Single Bone]` menu and create the root bone.
++
+image::jme3/external/blender-add-bone.png[blender-add-bone.png,width="",height=""]
 
-**  Select the bone and go to edit mode (press kbd:[Tab]).
-**  Select the root bone end and press kbd:[E] to extrude the bone, then start rigging your model this way.
-**  *Make sure your armatures location, rotation and scale is applied (see “Model Checklist below) before continuing*.
+..  Select the bone and go to edit mode (press kbd:[Tab]).
+..  Select the root bone end and press kbd:[E] to extrude the bone, then start rigging your model this way.
++
+IMPORTANT: Make sure your armature's location, rotation and scale is applied (see "`Model Checklist`" below) before continuing.
 
-*  Make the armature the parent of the model.
-**  Make sure you are back in object mode (press kbd:[Tab] again).
-**  First select the model object then select the armature object with kbd:[Shift] pressed, then press kbd:[Ctrl] + kbd:[P].
-**  When you do this, you can select how the bone groups will be mapped to the model vertices initially. Select btn:[With Automatic Weights].
+.  Make the armature the parent of the model.
+..  Make sure you are back in object mode (press kbd:[Tab] again).
+..  First select the model object then select the armature object with kbd:[Shift] pressed, then press kbd:[Ctrl] + kbd:[P].
+..  When you do this, you can select how the bone groups will be mapped to the model vertices initially. Select btn:[With Automatic Weights].
 +
 [NOTE]
 ====
@@ -61,79 +66,92 @@ When you parent your mesh to the armature, Blender automatically adds the `Armat
 
 image:jme3/external/blender-make-armature.png[blender-make-armature.png,width="",height=""]
 ====
++
+Voila, your model should move when you move the bones in pose mode.
 
-*  Voila, your model should move when you move the bones in pose mode.
-*  From the `Info` header, press the btn:[Choose Screen Layout] button and select the `Animation` layout.
-*  In the `Dope Sheet Editor` window, press the btn:[Context] button and select `Action Editor`.
-**  image:jme3/external/blender-action-editor.png[blender-action-editor.png,width="",height=""]
+.  From the `Info` header, press the btn:[Choose Screen Layout] button and select the `Animation` layout.
+.  In the `Dope Sheet Editor` window, press the btn:[Context] button and select `Action Editor`.
++
+image::jme3/external/blender-action-editor.png[blender-action-editor.png,width="",height=""]
 
-*  Add an action by pressing the btn:[+] button.
-*  Set the rotationmode of the bone to Quaternion or switch later from your rotationmode to Quaternion and make a keyframe.
-**  image:jme3/external/blender-switch-rotationmode.png[blender-switch-rotationmode.png,width="",height=""]
-*  Create the keyframes (select the model armature and press kbd:[I]) along the timeline.
-**  image:jme3/external/blender-add-keyframes.png[blender-add-keyframes.png,width="",height=""]
+.  Add an action by pressing the btn:[+] button.
+.  Set the "`Rotation Mode`" of the bone to `Quaternion` or switch later from your "`Rotation Mode`" to `Quaternion` and make a `Keyframe`.
++
+image::jme3/external/blender-switch-rotationmode.png[blender-switch-rotationmode.png,width="",height=""]
+.  Create the ``Keyframe``s (select the model armature and press kbd:[I]) along the timeline.
++
+--
+image::jme3/external/blender-add-keyframes.png[blender-add-keyframes.png,width="",height=""]
 
-*  Each action will be an animation available via the animation control in jME after the import.
-*  *Press the btn:[F] button next to the action so it will be saved even if theres no references.*
-**  The animation would else be deleted if its not the active animation on the armature and the file is saved.
+Each action will be an animation available via the animation control in jME after the import.
 
+IMPORTANT: Press the btn:[F] button next to the action so it will be saved even if there's no references. The animation would else be deleted if its not the active animation on the armature and the file is saved.
+--
 
 
-== Model Checklist
+=== Model Checklist
 
-Sometimes you do not create the model yourself and often times models from the web are not really made for OpenGL live rendering or not completely compatible with the bone system in jME.
+Sometimes you do not create the model yourself and often models from the web are not really made for OpenGL live rendering or not completely compatible with the bone system in jME.
 
 To export an animated model in Blender make sure the following conditions are met:
 
-*  The animation has to be a *bone animation*.
-*  Apply Location, Rotation and Scale to the mesh in Blender: In the `3D Viewport` in Blender, select the mesh in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
-**  image:jme3/external/blender_apply_mesh.png[blender_apply_mesh.png,width="300",height=""]
+TIP: This checklist is interactive for your convenience.
 
-*  Apply Location, Rotation and Scale to the armature in Blender: In the `3D Viewport` in Blender, select the armature in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
-**  image:jme3/external/blender_apply_bones.png[blender_apply_bones.png,width="300",height=""]
+[%interactive]
+* [ ] The animation has to be a *bone animation*.
+* [ ] Apply Location, Rotation and Scale to the mesh in Blender: In the `3D Viewport` in Blender, select the mesh in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
++
+image::jme3/external/blender_apply_mesh.png[blender_apply_mesh.png,width="300",height=""]
 
-*  Set the mesh’s origin point in the bottom of the mesh (see the image below).
-*  Set the armature’s origin point in the bottom of the armature (see the image below).
-*  Armature’s origin point and mesh’s origin point must be in the same location(see the image below).
-*  Use a root bone located in the armature’s origin. This root bone must be in vertical position (see the image below) and it is the root bone of the armature. If you rotate the root bone, the the entire armature might be rotate when you import the model into jMonkey (I’m just mentioning the result, I don’t know where is the problem (jMonkey importer or blender’s ogre exporter plugin)).
-*  Uncheck "`Bone Envelopes`" checkbox on the Armature modifier for the mesh (see the image below).
-**  image:jme3/external/blender_envelopes.png[blender_envelopes.png,width="300",height=""]
+* [ ] Apply Location, Rotation and Scale to the armature in Blender: In the `3D Viewport` in Blender, select the armature in `Object Mode`, from the `3D View Editor` header, click `menu:Object[Apply > Location / Rotation / Scale]`.
++
+image::jme3/external/blender_apply_bones.png[blender_apply_bones.png,width="300",height=""]
+
+* [ ] Set the mesh’s origin point in the bottom of the mesh (see the image below).
+* [ ] Set the armature’s origin point in the bottom of the armature (see the image below).
+* [ ] Armature’s origin point and mesh’s origin point must be in the same location (see the image below).
+* [ ] Use a root bone located in the armature’s origin. This root bone must be in vertical position (see the image below) and it is the root bone of the armature. If you rotate the root bone, the entire armature might be rotated when you import the model into jMonkey.
+* [ ] Uncheck:
+** [ ] Bone Envelopes
++
+--
+on the Armature modifier for the mesh (see the image below).
 
-*  Under the armature data tab, make sure the bone type is `Octahedral` (see image below).
+image::jme3/external/blender_envelopes.png[blender_envelopes.png,width="300",height=""]
+--
+* [ ] Under the armature data tab, make sure the bone type is `Octahedral` (see image below).
 //*  Uncheck "`Envelopes`" checkbox on the armature (see the image below).
-**  image:jme3/external/blender_rootbone2.png[blender_rootbone2.png,width="",height=""]
++
+image::jme3/external/blender_rootbone2.png[blender_rootbone2.png,width="",height=""]
 
 
-You can use SkeletonDebugger to show the skeleton on your game in order to check if the mesh and the skeleton are loaded correctly:
+You can use `SkeletonDebugger` to show the skeleton on your game in order to check if the mesh and the skeleton are loaded correctly:
 
 [source,java]
 ----
-
-    final Material soldier2Mat = assetManager.loadMaterial("Materials/soldier2/soldier2.j3m");
-    final Spatial soldier2 = assetManager.loadModel("Models/soldier2/soldier2.j3o");
-    TangentBinormalGenerator.generate(soldier2);
-    soldier2.setMaterial(soldier2Mat);
- 
-    final Node soldier2Node = new Node("Soldier2 Node");
- 
-    soldier2Node.attachChild(soldier2);
-    rootNode.attachChild(soldier2Node);
-    
-    final AnimControl animControl = soldier2.getControl(AnimControl.class);
-    animControl.addListener(this);
-    final AnimChannel animChannel = animControl.createChannel();
-
-    final SkeletonDebugger skeletonDebug = 
-                    new SkeletonDebugger("skeleton", animControl.getSkeleton());
-    final Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-    mat.setColor("Color", ColorRGBA.Green);
-    mat.getAdditionalRenderState().setDepthTest(false);
-    skeletonDebug.setMaterial(mat);
-    soldier2Node.attachChild(skeletonDebug);
-
+final Material soldier2Mat = assetManager.loadMaterial("Materials/soldier2/soldier2.j3m");
+final Spatial soldier2 = assetManager.loadModel("Models/soldier2/soldier2.j3o");
+TangentBinormalGenerator.generate(soldier2);
+soldier2.setMaterial(soldier2Mat);
+
+final Node soldier2Node = new Node("Soldier2 Node");
+
+soldier2Node.attachChild(soldier2);
+rootNode.attachChild(soldier2Node);
+
+final AnimControl animControl = soldier2.getControl(AnimControl.class);
+animControl.addListener(this);
+final AnimChannel animChannel = animControl.createChannel();
+
+final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", animControl.getSkeleton());
+final Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+mat.setColor("Color", ColorRGBA.Green);
+mat.getAdditionalRenderState().setDepthTest(false);
+skeletonDebug.setMaterial(mat);
+soldier2Node.attachChild(skeletonDebug);
 ----
 
-*  image:jme3/external/blender_finished.png[blender_finished.png,width="500",height=""]
+image::jme3/external/blender_finished.png[blender_finished.png,width="500",height=""]
 
 Also check out these videos and resources:
 
@@ -142,101 +160,145 @@ Also check out these videos and resources:
 *  link:https://docs.google.com/fileview?id=0B9hhZie2D-fENDBlZDU5MzgtNzlkYi00YmQzLTliNTQtNzZhYTJhYjEzNWNk&hl=en[Exporting OgreXML scenes from Blender 2.49 to jME]
 
 
-=== NormalMap baking
-
-Models for live rendering should have a low polygon count. To increase the perceived detail of a model normal maps are commonly used in games. This tutorial will show how to create a normalmap from a highpoly version of your model that you can apply to a lowpoly version of the model in your game.
-
-
-== Blender modeling lowPoly & highPoly
-
-*  If you use the multiresolution modifier you only need one object. Lets look at this example:
-**  image:jme3/external/1.gif[1.gif,width="150",height=""]
+== Normal Map baking
 
-*  Add a multiresolution modifier:
-**  image:jme3/external/3.1.gif[3.1.gif,width="300",height=""]
+Models for live rendering should have a low polygon count. To increase the perceived detail of a model, Normal maps are commonly used in games. This tutorial will show how to create a Normal map from a "`HighPoly`" version of your model that you can apply to a "`LowPoly`" version of the model in your game.
 
-*  There are two types of modifiers: Catmull-Clark and Simple. 
-**  Simple is better for things like walls or floors.
-**  Catmull-Clark is better for objects like spheres.
 
-*  When using Catmull-Clark with a higher “subdivide value (more than 3) its good to have the “preview value above 0 and less than the subdivide level. This is because Catmull-Clark smoothes the vertices, so the normalMap is not so precise.
-*  Here is an example of Prewiew 1, it's more smooth than the original mesh:
-**  image:jme3/external/2.gif[2.gif,width="150",height=""]
+=== Blender Modeling LowPoly & HighPoly
 
-*  Enable “Sculpt Mode in blender and design the highPoly version of your model like here:
-**  image:jme3/external/3.gif[3.gif,width="150",height=""]
+.Method 1
+If you use the `Multiresolution` modifier you only need one object. Let's look at this example, the Blender object Monkey, with an applied `Triangulate` modifier:
 
-*  Now go into Render Tab, and bake a normalMap using same configuration as here:
-**  image:jme3/external/4.gif[4.gif,width="300",height=""]
+image::jme3/external/monkey.png[monkey.png,width="50%",height=""]
 
-
-
-[NOTE]
-====
-Remember! The actual preview affects the baking output and mesh export!
+.  Add a "`Monkey`" object by selecting the btn:[Monkey] button located on the "`Create Tab`".
+.. While in `Object Mode`, in the `Properties` panel under the `Modifiers` tab, add a `Triangulate` modifier and apply it:
+..  While in `Object Mode`, in the `Properties` panel under the `Modifiers` tab, add a `Multiresolution` modifier:
++
+--
+image::jme3/external/3.1.gif[3.1.gif,width="300",height=""]
+
+There are two types of modifiers: Catmull-Clark and Simple.
+
+*  Simple is better for things like walls or floors.
+*  Catmull-Clark is better for objects like spheres.
+
+When using Catmull-Clark with a higher "`subdivide`" value (more than 3), it's good to have the "`Preview`" value above 0 and less than the subdivide level. This is because Catmull-Clark smooths the vertices, so the Normal map is not so precise.
+
+Regardless of the choice, the larger the difference is between "`Render`" and "`Preview`", the deeper the detail is on the Normal map.
+
+*  Here is an example of `Preview 1`, it's more smooth than the original mesh:
+
+image::jme3/external/monkeyprev1.png[monkkeyprev1.png,width="50%",height=""]
+--
+.  From the `File` header at the top of the 3d View, click the btn:[Choose Screen layout] button and select "`UV Editing`".
+.  In the `3d View`, select the Monkey and kbd:[Tab] into "`Edit Mode`".
+.  If the Monkey vertices are not already highlighted, press the kbd:[A] key until all vertices are highlighted.
+.  From the `3d View` header, select `menu:Mesh[UV Unwrap>Smart UV Project]`.
+..  Click the btn:[Island Margin] button once to advance the value to .03.
+..  Click btn:[OK] when ready.
+.  In the `UV Image Editor`, click the btn:[New]  button.
+..  Change the name to something like "`monkey_bump`".
+..  Optionally, change the `Generated Type` to "`UV Grid`".
+..  Uncheck:
+** [ ] 32 Bit
+..  Click btn:[OK] when ready.
+.  From the `File` header at the top of the `UV Image Editor`, click the btn:[Choose Screen layout] button and select "`Default`".
+.  With your mouse inside the `3D View`, tab into `Object Mode`.
+.  Now go into the `Render` tab, and bake a `Normal` map using the same configuration as here:
++
+--
+image::jme3/external/4.gif[4.gif,width="300",height=""]
+
+IMPORTANT: Remember! The actual preview affects the baking output and mesh export!
+--
+
+.  Navigate back to the `UV Editing` layout and save your image by selecting `menu:Image*[Save As]` from the `UV Image Editor` header.
+
+TIP: The asterisk kbd:[*] next to the `Image` menu item means the image has not yet been saved.
+
+.Normal map from Method 1
+image::jme3/external/monkey_bump.png[monkey_bump.png,width="50%",height=""]
+
+This second method produces the best results by far:
+
+.Method 2
+.  Follow the steps for "`Method 1`" but before baking, uncheck:
+** [ ] Bake from Multires
+.  Make a copy of your mesh (kbd:[SHIFT]+kbd:[D]).
+.  Remove the Multires modifier from the copied model.
+.  Remove any materials from the copied model.
+.  Remove the armature modifier from the copied model.
+.  Select the original (HighPoly) model.
+.  Go into pose mode, clear any pose transformations.
+.  The "`HighPoly`" and "`LowPoly`" models should be on top of each other now.
+.  Select the original (HighPoly) model.
+.  Hold kbd:[SHIFT] and select the copied (LowPoly) model.
+.  In the `Properties` panel, in the `Render` tab:
+..  Bake Mode: `Normal`
+..  check:
+** [x] Selected to Active
+..  Use a reasonably high value for "`Margin`" (4+ pixels at least for 1024x1024 maps).
+.  Bake and don't forget to save the Normal map image.
+
+[IMPORTANT]
 ====
+Keep in mind that when you duplicate the model, you are also duplicating its UV mapping. What this means is your "HiPoly" model and "`LowPoly`" model are both assigned to an image.
 
+If you ever see this error:
 
+"No objects or images found to bake to"
 
-[NOTE]
-====
-Be careful: The steps above lead to terrible normal maps - use this procedure instead:
+You are either missing the image for the "`LowPoly`" model, or in the Outliner, the camera symbol (Restrict Render) is off (grayed out).
 ====
 
+.Normal map from Method 2
+image::jme3/external/monkey_bump2.png[monkey_bump2.png,width="50%",height=""]
 
-*  uncheck “[ ] Bake from Multires
-*  switch to object mode
-*  make a copy of your mesh (SHIFT+D)
-*  remove the Multires modifier from the copied model
-*  remove any materials from the copied model
-*  remove the armature modifier from the copied model
-*  select the original (highres) model
-*  go into pose mode, clear any pose transformations
-*  the highres and lowres models should be on top of each other now
-*  select the original (highres) model
-*  hold SHIFT and select the copied (lowres) model
-*  in the properties menu go to render
-*  use Bake &gt; Normal
-*  check “[x] Selected to Active
-*  use a reasonably high value for “Margin (4+ pixels at least for 1024x1024 maps)
-*  don't forget to safe the normal map image
+=== Fixing the Normal colors in Blender
 
+There are two "`standards`" for Normal maps:
 
-[NOTE]
-====
-Be careful: in the Outliner the camera symbol (Restrict Render) must be on!
-====
-
+*  DirectX
+*  OpenGL
 
+The difference between them is that the green channel is inverted. One would expect that JME supports the OpenGL way, but actually JME supports the DirectX way because it’s what Blender supports and the developers of JME thought it would be easier in the Blender to JME workflow.
 
-== Fixing the normal colors in Blender
+Because of this, you need to fix the colors to prepare the Normal map for using it with the JME Lighting Material. You should only have to invert the green channel, the red and blue channels should stay unchanged. The curve for the red and blue channels should go from bottom left to top right, the green from top left to bottom right.
 
-Blender has its own normal colors standard. We need to fix the colors to prepare the normalmap for using it with the JME Lighting Material.
+To do this after baking and saving the original Normal map image:
 
-To do this, go to the Blender Node Window
+. In the "`UV Editing`" layout, from the "`UV Image Editor`" header select `menu:Image[Invert>Invert Green Channel]`.
+.  Save the inverted image to a destination you want and use it with the JME Lighting Material and the "`LowPoly`" version of the model.
 
-*  Here is Blender Node example. It fixes the normal colors:
-**  image:jme3/external/5.gif[5.gif,width="500",height=""]
+.Normal map invert results (Method 2 example)
+image::jme3/external/monkey_bump2_invert.png[monkey_bump2_invert.png,width="50%",height=""]
 
+[TIP]
+.Inverting Tips
+====
+If you build the engine from source, the master branch link:https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md#L39[PBR material] has a NormalType parameter that allows one to handle this in the shader instead of having to edit the Normal map.
 
-*  Here is the colors configuration:
-**  image:jme3/external/6.gif[6.gif,width="180",height=""] image:jme3/external/7.gif[7.gif,width="180",height=""] image:jme3/external/8.gif[8.gif,width="180",height=""]
-
+You can also use the SDK to invert the channel:
 
-*  Sometimes it will be needed to change R and G scale and add some blur for better effect. Do it like on image below
-**  image:jme3/external/exception2.gif[exception2.gif,width="",height=""]
+.  In the SDK, btn:[RMB] select the image and choose "`Edit Texture`".
+.  In the window header, press the btn:[Filters] button and choose `menu:Invert[Green]`.
+.  When satisfied, save the change in the same format as the original image using `menu:File[Save]`.
+====
 
-*  After rendering, save the file to a destination you want and use it with the JME Lighting Material and the lowpoly version of the model.
-**  image:jme3/external/ready_normal.gif[ready_normal.gif,width="",height=""]
+This is what the final outcome of Normal map baking should produce for you. A "`LowPoly`" model that looks like it's a "`HighPoly`" model.
 
+.Final results (Method 2 example)
+image::jme3/external/monkey_final.gif[monkey_final.gif,width="",height=""]
 
 
-=== LightMap baking
+== LightMap baking
 
 The goal of this tutorial is to explain briefly how to bake light map in blender with a separate set of texture coordinates and then export a model using this map in jME3.
 
 
-== Blender modeling + texturing
+=== Blender modeling + texturing
 
 *  create a mesh in blender and unwrap it to create uvs
 **  image:jme3/advanced/1.jpg[1.jpg,width="600",height=""]
@@ -279,19 +341,19 @@ The blend file, the ogre xml files and the textures can be found in the download
 link:http://code.google.com/p/jmonkeyengine/downloads/detail?name=LightMap.zip&can=2&q=#makechanges[http://code.google.com/p/jmonkeyengine/downloads/detail?name=LightMap.zip&amp;can=2&amp;q=#makechanges]
 
 
-=== Modelling racing tracks and cars
+== Modelling racing tracks and cars
 
 Follow the link below to a pdf tutorial by rhymez where I guide you to modelling a car and importing it to the jMonkeyengine correctly and edit it in the vehicle editor.Plus how to model a simple racing track.
 link:http://www.indiedb.com/games/street-rally-3d/downloads/modelling-in-blender-to-the-jmonkeyengine[http://www.indiedb.com/games/street-rally-3d/downloads/modelling-in-blender-to-the-jmonkeyengine]
 
 
-=== Optimizing Models for 3D games
+== Optimizing Models for 3D games
 
 Follow the link below to a pdf tutorial by rhymez where I guide you on how you can optimize your models for faster rendering.
 link:http://www.indiedb.com/games/street-rally-3d/downloads/optimizing-3d-models-for-games[http://www.indiedb.com/games/street-rally-3d/downloads/optimizing-3d-models-for-games]
 
 
-=== SkyBox baking
+== SkyBox baking
 
 There are several ways to create static images to use for a sky in your game. This will describe the concepts used in blender and create an ugly sky emoji:smiley Check the links below for other ways and prettier skies.
 

+ 12 - 12
src/docs/asciidoc/jme3/intermediate/appsettings.adoc

@@ -1,13 +1,13 @@
 = jME3 Application Display Settings
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :relfileprefix: ../../
 :imagesdir: ../..
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
-Every class that extends jme3.app.SimpleApplication has properties that can be configured by customizing a `com.jme3.system.AppSettings` object. 
+Every class that extends jme3.app.SimpleApplication has properties that can be configured by customizing a `com.jme3.system.AppSettings` object.
 
 
 [IMPORTANT]
@@ -29,7 +29,7 @@ public static void main(String[] args) {
   AppSettings settings = new AppSettings(true);
   settings.setResolution(640,480);
   // ... other properties, see below
-  MyGame app = new MyGame(); 
+  MyGame app = new MyGame();
   app.setSettings(settings);
   app.start();
 }
@@ -67,8 +67,8 @@ a|Default
 a|setRenderer(AppSettings.LWJGL_OPENGL1) +
 setRenderer(AppSettings.LWJGL_OPENGL2) +
 setRenderer(AppSettings.LWJGL_OPENGL3)
-a|Switch Video Renderer to OpenGL 1.1, OpenGL 2, or OpenGL 3.3. If your graphic card does not support all OpenGL2 features (`UnsupportedOperationException: GLSL and OpenGL2 is required for the LWJGL renderer`), then you can force your SimpleApplication to use OpenGL1 compatibility. (Then you still can't use special OpenGL2 features, but at least the error goes away and you can continue with the rest.) 
-a| OpenGL 2 
+a|Switch Video Renderer to OpenGL 1.1, OpenGL 2, or OpenGL 3.3. If your graphic card does not support all OpenGL2 features (`UnsupportedOperationException: GLSL and OpenGL2 is required for the LWJGL renderer`), then you can force your SimpleApplication to use OpenGL1 compatibility. (Then you still can't use special OpenGL2 features, but at least the error goes away and you can continue with the rest.)
+a| OpenGL 2
 
 a|setBitsPerPixel(32)
 a|Set the color depth. +
@@ -119,7 +119,7 @@ a|24
 .Input
 |===
 
-a|Settings Property 
+a|Settings Property
 a|Description
 a|Default
 
@@ -144,12 +144,12 @@ a|false,false
 .Audio
 |===
 
-a|Settings Property 
+a|Settings Property
 a|Description
 a|Default
 
 a|setAudioRenderer(AppSettings.LWJGL_OPENAL)
-a|Switch Audio Renderer. Currently there is only one option. 
+a|Switch Audio Renderer. Currently there is only one option.
 a|OpenAL
 
 a|setStereo3D(true)
@@ -167,7 +167,7 @@ a|Default
 
 a|setTitle("My Game")
 a|This string will be visible in the titlebar, unless the window is fullscreen.
-a|"jMonkey Engine 3.1-stable"
+a|"jMonkey Engine 3.x-stable"
 
 a|setIcons(new BufferedImage[]{ +
 ImageIO.read(new File(" ")), …});
@@ -218,14 +218,14 @@ An AppSettings object also supports the following methods to save your settings
 *  Use `settings.load("com.foo.MyCoolGame3")` to load your settings.
 *  Use `settings2.copyFrom(settings)` to copy a settings object.
 
-Usage: 
+Usage:
 
 Provide the unique name of your jME3 application as the String argument. For example `com.foo.MyCoolGame3`.
 
 [source,java]
 ----
 
-    try { settings.save("com.foo.MyCoolGame3"); } 
+    try { settings.save("com.foo.MyCoolGame3"); }
     catch (BackingStoreException ex) { /** could not save settings */ }
 
 ----

+ 21 - 21
src/docs/asciidoc/jme3/intermediate/best_practices.adoc

@@ -1,7 +1,7 @@
 = Best Practices For jME3 Developers
 :author: 
 :revnumber: 
-:revdate: 2016/03/17 20:48
+:revdate: 2017/11/26 13:30
 :relfileprefix: ../../
 :imagesdir: ../..
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
@@ -9,7 +9,7 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 Every milestone of a game development project is made up of phases: Planning, development, testing, and release. Every milestone involves updates to multi-media assets and to code.  
 
-This “best practices page is a collection of recommendations and expert tips. Feel free to add your own!
+This "best practices" page is a collection of recommendations and expert tips. Feel free to add your own!
 
 
 == Requirements and Planning
@@ -23,7 +23,7 @@ As a quick overview, answer yourself the following questions:
 
 *  Motivation
 **  Sum up your game idea in one catchy sentence. If you can't, it's too complicated. +
-E.g. “Craft by day, fight by night!
+Exmple: "Craft by day, fight by night!"
 **  Who's the target group? Are you making it for your friends or are you trying to attract the masses?
 
 *  Game type
@@ -35,13 +35,13 @@ E.g. “Craft by day, fight by night!
 *  Gameplay
 **  What is the start state, what is the end state? (if applicable)
 **  What resources does the player manage? How are resources gained, transformed, spent? +
-E.g. “points, health, speed, gold, xp, mana.
+Exmple: points, health, speed, gold, xp, mana.
 **  How does the player interact? Define rules, challenges, game mechanics.
 **  What state is considered winning, and what losing, or is it an open world?
 
 *  Multi-media assets
 **  Which media will you need? How will you get this content? +
-E.g. models, terrains; materials, textures; noises, music, voices; video, cutscenes; spoken/written dialog; level maps, quests, story; AI scripts.
+Exmple: models, terrains; materials, textures; noises, music, voices; video, cutscenes; spoken/written dialog; level maps, quests, story; AI scripts.
 
 *  Interface
 **  Can you achieve a high degree of input control? (Even minor navigation and interaction glitches make the game unsolvable.)
@@ -58,18 +58,18 @@ Use an link:http://en.wikipedia.org/wiki/Issue_tracking_system[issue and bug tra
 **  Artwork: Test asset loading and saving with mock-ups and stock art.
 **  Lay out the overall application flow, i.e. switching between intro / options / game screen, etc.
 **  Get one typical level working before you can announce the Alpha Release. +
-E.g. if the game is a “Jump'n'Run, jumping and running must work.
+Exmple: if the game is a "Jump'n'Run", jumping and running must work.
 
 .  Alpha Release
 .  Pre-Beta Development
 **  Artwork: Replace all mock-ups with first drafts of real media and level maps.
-**  Have your team members review and alpha test it on various systems, track bugs, debug, optimize.
+**  Have your team members review and alpha test it on various systems, track bugs, debug, optimize.
 **  Declare link:http://en.wikipedia.org/wiki/Feature_freeze[Feature Freeze] before you announce the Beta Release to prevent a bottomless pit of new bugs.
 
 .  Beta Release
 .  Post-Beta Development
 **  Artwork: Fill in the final media and level maps.
-**  Have external people review and beta test it, make it easy to report bugs.
+**  Have external people review and beta test it, make it easy to report bugs.
 **  Fix high-priority bugs, even out the kinks in code and gameplay, don't add new features for now!
 
 .  Gamma Release, Delta Release… = Release Candidates
@@ -78,17 +78,17 @@ E.g. if the game is a “Jump'n'Run, jumping and running must work.
 
 .  Omega = Final Release
 
-How you name or number these stages is fully up to your team. Development teams use numbered milestones (m1, m2, m3), Greek letters (e.g. alpha, beta, gamma, delta), link:http://en.wikipedia.org/wiki/Software_versioning[&quot;major.minor.patch-build&quot; version] numbering (e.g. “2.7.23-1328), or combinations thereof. 
+How you name or number these stages is fully up to your team. Development teams use numbered milestones (m1, m2, m3), Greek letters (ex. alpha, beta, gamma, delta), link:http://en.wikipedia.org/wiki/Software_versioning[&quot;major.minor.patch-build&quot; version] numbering (ex. "2.7.23-1328"), or combinations thereof. 
 
 
 === Use File Version Control
 
 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 old code that someone deleted and that is now needed again.
 
-*  Treat commit messages as messages to your future self. “Made some changes is _not_ a commit message.
+*  Treat commit messages as messages to your future self. "Made some changes" is _not_ a commit message.
 *  The jMonkeyEngine SDK supports Subversion, Mercurial, and Git. +
 If you don't know which to choose, Subversion is a good choice for starters.
-*  Set up your own local server, or get free remote hosting space from various open-source dev portals like link:http://sourceforge.net/[Sourceforge], link:https://github.com/[Github], link:https://bitbucket.org/[bitbucket] (supports private projects), link:http://home.java.net/create-project[Java.net]
+*  Set up your own local server, or get free remote hosting space from various open-source dev portals like link:http://sourceforge.net/[SourceForge], link:https://github.com/[GitHub], link:https://bitbucket.org/[BitBucket] (supports private projects), link:https://about.gitlab.com/[GitLab] (free private projects)
 
 
 == Multi-Media Asset Pipeline
@@ -126,8 +126,8 @@ Learn details about the <<jme3/intermediate/multi-media_asset_pipeline#,Multi-Me
 
 [NOTE]
 ====
-Many game developers dream of creating their very own MMORPG with full-physics, AI, post-rendering effects, multi-player networking, procedurally generated maps, and customizable characters. So why aren't there tons of MMORPGs out there? +
-Even for large experienced game producers, the creation of such a complex game is time-intensive and failure-prone. How familiar are you with multi-threading, persistence, optimization, client-server synchonization, …? Unless your answer is “very!, then start with a single-player desktop game, and work your way up – just as the pros did when they started.
+Many game developers dream of creating their very own MMORPG with full-physics, AI, post-rendering effects, multi-player networking, procedurally generated maps, and customizable characters. So why aren't there tons of MMORPGs out there? +
+Even for large experienced game producers, the creation of such a complex game is time-intensive and failure-prone. How familiar are you with multi-threading, persistence, optimization, client-server synchonization, …? Unless your answer is "very!", then start with a single-player desktop game, and work your way up – just as the pros did when they started.
 ====
 
 
@@ -139,7 +139,7 @@ Every jME3 game is centered around one main class that (directly or indirectly)
 
 [IMPORTANT]
 ====
-Note that although the “SimpleApplication name might be misleading, all jME3 applications, including very large projects, are based on this class. The name only implies that this class itself is a simple application already. You make it “non-simple by extending it!
+Note that although the "SimpleApplication" name might be misleading, all jME3 applications, including very large projects, are based on this class. The name only implies that this class itself is a simple application already. You make it "non-simple" by extending it!
 ====
 
 
@@ -160,14 +160,14 @@ You have a list of features that you want in game, but which one do you implemen
 
 .  Make sure the game's high-level frame (screen switching, network sync, loading/saving) is sound and solid. 
 .  Start with implementing the most complex game feature first – the one that imposes most constraints on the structure of your project (for example: multi-player networking, or physics.)
-.  Add only one larger feature at a time. If there are complex interactions (such as networking + physics), start with a small test case (one shared cube) and work your way up. Starting with a whole scene introduces too many extra sources of error.
+.  Add only one larger feature at a time. If there are complex interactions (such as networking + physics), start with a small test case (one shared cube) and work your way up. Starting with a whole scene introduces too many extra sources of error.
 .  Implement low-complexity decorations (audio and visual effects) last.
 .  Test for side-effects on existing code after you add a new feature (regression test).
 
 
 [TIP]
 ====
-Acknowledge whether you want a feature because it is necessary for gameplay, or simply because “everyone else has it. Your goal should be to bring out the essence of your game idea. Don't water down gameplay by attempting to make it “do everything, but better. Successful high-performance games are the ones where someone made smart decisions what to keep and what to _drop_.
+Acknowledge whether you want a feature because it is necessary for gameplay, or simply because "everyone else has it". Your goal should be to bring out the essence of your game idea. Don't water down gameplay by attempting to make it "do everything, but better". Successful high-performance games are the ones where someone made smart decisions what to keep and what to _drop_.
 ====
 
 
@@ -179,13 +179,13 @@ Acknowledge whether you want a feature because it is necessary for gameplay, or
 ====
 *Avoid the Anti-Pattern:* Don't design complex role-based classes using Java inheritance, it will result in an unmaintainable mess. +
 Example: You start extending `Node` –> `MyMobileNode` –> `MyNPC`. Then you extend `MyFighterNPC` (defends, attacks) and `MyShopKeeperNPC` (trades) from `MyNPC`. What if you need an NPC that trades and defends itself, but doesn't attack? Do you extend MyShopKeeperNPC and copy and paste the defensive methods from MyFighterNPC? Or do you extend MyFighterNPC and override the attacking methods of its parent? Neither is a clean solution. +
-Wouldn't it be better if behaviours were a separate system, and attributes were separate components that you add to the entity that needs them?
+Wouldn't it be better if behaviours were a separate system, and attributes were separate components that you add to the entity that needs them?
 ====
 
 
 You write Java classes named `Controls` to implement your Game Entities, and define an Entity's visuals, attributes, and behaviours. In jME, `Spatial`s (`Nodes` or `Geometry`s) are the visual representation of the game entity in the scene graph.
 
-*  Game entities have *attributes* – All Entities are neutral _things_, only their attributes define what an entity actually _is_ (a person or a brick). In jME, we call these class fields of Spatials “user data. +
+*  Game entities have *attributes* – All Entities are neutral _things_, only their attributes define what an entity actually _is_ (a person or a brick). In jME, we call these class fields of Spatials "user data". +
 Example: Players have *class fields* for `id, health, coins, inventory, equipment, profession`.
 *  Game entities have *behaviours* – Behaviour systems communicate about the game state and modify attributes. In jME, these game mechanics are implemented in modular `update()` methods that all hook into the main update loop. +
 Example: Players have *methods* such as `walk(), addGold(), getHealth(), pickUpItem(), dropItem(), useItem(), attack()`.
@@ -193,14 +193,14 @@ Example: Players have *methods* such as `walk(), addGold(), getHealth(), pickUpI
 
 [TIP]
 ====
-*Follow the Best Practice:* In general, use composition over inheritance and keep what an entity does (behaviour system) separate from what this entity is (attributes).
+*Follow the Best Practice:* In general, use composition over inheritance and keep what an entity does (behaviour system) separate from what this entity is (attributes).
 
 *  Use `<<jme3/advanced/spatial#,setUserData()>>` to add custom attributes to Spatials.
 *  Use <<jme3/advanced/custom_controls#,Controls>> and <<jme3/advanced/application_states#,Application States>> to define custom behaviour systems.
 ====
 
 
-If your game is even more complex, you may want to learn about “real Entity Systems, which form a quite different programming paradigm from object oriented coding but are scalable to very large proportions. Note however that this topic is very unintuitive to handle for an OOP programmer and you should really decide on a case basis if you really need this or not and gather some experiences before diving head first into a MMO project emoji:smiley
+If your game is even more complex, you may want to learn about "real" Entity Systems, which form a quite different programming paradigm from object oriented coding but are scalable to very large proportions. Note however that this topic is very unintuitive to handle for an OOP programmer and you should really decide on a case basis if you really need this or not and gather some experiences before diving head first into a MMO project emoji:smiley
 
 *  link:http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/[http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/] 
 *  link:http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php[http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php]
@@ -286,7 +286,7 @@ It's unlikely you will fully document _every_ class you write, we hear you. Howe
 *  Write down implicit limits (e.g. min/max values) and defaults while you still remember.
 *  In which situation do I want to use this, is this part of a larger process? Is this step required, or what are the alternatives? 
 
-Treat javadoc as messages to your future self. “genNextVal() generates the next value and “@param float factor A factor influencing the result do _not_ count as documentation.
+Treat javadoc as messages to your future self. `genNextVal() generates the next value` and `@param float factor A factor influencing the result` do _not_ count as documentation.
 
 
 == Debugging and Test Phase

+ 19 - 11
src/docs/asciidoc/jme3/intermediate/file_types.adoc

@@ -1,6 +1,6 @@
 = jMonkeyEngine3 Supported File Types
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :relfileprefix: ../../
 :imagesdir: ../..
@@ -19,22 +19,22 @@ a|Learn more
 l|.j3o
 a|Binary 3D model or scene. At the latest 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.
-a|<<sdk/model_loader_and_viewer#,Model Loader and Viewer>> 
+a|<<sdk/model_loader_and_viewer#,Model Loader and Viewer>>
 
 l|.j3m
 a|A custom Material. You can create a .j3m file to store a Material configuration for a Geometry (e.g. 3D model).
 a|<<jme3/advanced/materials_overview#,Materials Overview>> +
-<<sdk/material_editing#,Material Editing>> 
+<<sdk/material_editing#,Material Editing>>
 
 l|.j3md
 a|A Material definition. These are pre-defined templates for shader-based Materials. +
-Each custom .j3m Material is based on a material definition. Advanced users can create their own material definitions. 
-a| <<jme3/advanced/materials_overview#,Materials Overview>> 
+Each custom .j3m Material is based on a material definition. Advanced users can create their own material definitions.
+a| <<jme3/advanced/materials_overview#,Materials Overview>>
 
 l|.j3f
-a|A custom post-processor filter configuration. You can create a .j3f file to store a FilterPostProcessor with a set of preconfigured filters. 
+a|A custom post-processor filter configuration. You can create a .j3f file to store a FilterPostProcessor with a set of preconfigured filters.
 a| <<sdk/filters#,Filters>> +
-<<jme3/advanced/effects_overview#,Effects Overview>> 
+<<jme3/advanced/effects_overview#,Effects Overview>>
 
 |===
 
@@ -49,11 +49,11 @@ a|Description
 
 l|.mesh.xml, .meshxml
 a|3D model
-a|Ogre Mesh XML 
+a|Ogre Mesh XML
 
 l|.scene
 a|3D scene
-a|Ogre DotScene 
+a|Ogre DotScene
 
 l|.OBJ, .MTL
 a|3D model
@@ -61,7 +61,15 @@ a|Wavefront
 
 l|.blend
 a|3D model
-a|Blender version 2.49 onwards (tested up to 2.65)
+a|Blender version 2.49 onwards (tested up to 2.78c)
+
+l|.xbuf
+a|3D model
+a|Blender version 2.74, see: link:https://hub.jmonkeyengine.org/t/xbuf-format-a-developer-friendly-game-exchange-format-for-3d-data/31130[.xbuf] forum post
+
+l|.gltf, .bin, .glb, custom extensions
+a|3D model
+a|Blender version 2.78c onwards, see: link:https://hub.jmonkeyengine.org/t/jme-gltf-support/39174[.gltf] forum post 
 
 a|COLLADA
 a| 3D model

+ 23 - 21
src/docs/asciidoc/jme3/maven.adoc

@@ -1,6 +1,6 @@
 = Maven Artifacts
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :relfileprefix: ../
 :imagesdir: ..
@@ -10,35 +10,37 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 You can use jME3 with maven compatible build systems.
 
 
-== jME3.1
+== jME3.2
 
-Artifacts for jME3.1 releases are available in repositories :
+Artifacts for jME3.1 and jME3.2 releases are available in repositories :
 
 * link:https://jcenter.bintray.com/org/jmonkeyengine/[JCenter]
-* link:https://bintray.com/jmonkeyengine/org.jmonkeyengine[Bintray repo: org.jmonkeyengine] every artifacts of the group org.jmonkeyengine (same as jcenter + few artifacts not eligible for jcenter), click on the `SET ME UP` button to view instruction for Gradle, Maven,...
+* link:https://bintray.com/jmonkeyengine/org.jmonkeyengine[Bintray repo: org.jmonkeyengine] every artifact of the group org.jmonkeyengine (same as jcenter + few artifacts not eligible for jcenter), click on the `SET ME UP` button to view instruction for Gradle, Maven,...
 
 The group id for all jME3 libraries is `org.jmonkeyengine`.
-The following artifacts are currently available (version `3.1.0-stable`):
-
-*  jme3-android-native - Native libraries needed for Android
-*  jme3-android - Android renderer for jME3
-*  jme3-blender - Blender file loader, only works on desktop renderers
-*  jme3-bullet-native-android - Native libraries needed for bullet (not jbullet) on android (beta)
-*  jme3-bullet-native - Native libraries needed for bullet (not jbullet) on desktop (beta)
-*  jme3-bullet - Physics support using native bullet, needs jme3-bullet-native or jme3-bullet-native-android (beta)
+
+The following artifacts are currently available (version `3.2.0-stable`):
+
+*  jme3-android-native - Native libraries needed for Android
+*  jme3-android - Android renderer for jME3
+*  jme3-blender - Blender file loader, only works on desktop renderers
+*  jme3-bullet-native-android - Native libraries needed for bullet (not jbullet) on android (beta)
+*  jme3-bullet-native - Native libraries needed for bullet (not jbullet) on desktop (beta)
+*  jme3-bullet - Physics support using native bullet, needs jme3-bullet-native or jme3-bullet-native-android (beta)
 *  jme3-core - Core libraries needed for all jME3 projects
-*  jme3-desktop - Parts of the jME3 +++<abbr title="Application Programming Interface">API</abbr>+++ that are only compatible with desktop renderers, needed for image loading on desktop
+*  jme3-desktop - Parts of the jME3 +++<abbr title="Application Programming Interface">API</abbr>+++ that are only compatible with desktop renderers, needed for image loading on desktop
 *  jme3-effects - Effects libraries for water and other post filters
-*  jme3-jogg - Loader for jogg audio files
-*  jme3-jogl - JOGL based renderer (optional replacement for lwjgl / lwjgl3)
-*  jme3-lwjgl - Desktop renderer for jME3
-*  jme3-lwjgl3 - NEW in jME3.1! LWJGL3-based desktop renderer for jME3 (beta)
+*  jme3-jogg - Loader for jogg audio files
+*  jme3-jogl - JOGL based renderer (optional replacement for lwjgl / lwjgl3)
+*  jme3-lwjgl - Desktop renderer for jME3
+*  jme3-lwjgl3 - NEW since jME3.1! LWJGL3-based desktop renderer for jME3 (beta)
 *  jme3-networking - jME3 networking libraries (aka spidermonkey)
-*  jme3-niftygui - NiftyGUI support for jME3 (Not available in JCenter)
+*  jme3-niftygui - NiftyGUI support for jME3 (Not available in JCenter)
 *  jme3-plugins - Loader plugins for OgreXML and jME-XML
 *  jme3-terrain - Terrain generation +++<abbr title="Application Programming Interface">API</abbr>+++
 *  jme3-jbullet - Physics support using jbullet (desktop only, not available in JCenter) *Only jme3-jbullet OR jme3-bullet can be used*
 *  jme3-ios - iOS renderer for jME3 (Not available in JCenter)
+*  jme3-vr - New since jME3.2! Support for virtual reality. (Not available in JCenter)
 
 For a basic desktop application to work you need to import at least
 
@@ -61,7 +63,7 @@ repositories {
     //maven { url "http://dl.bintray.com/jmonkeyengine/org.jmonkeyengine" }
 }
 
-def jme3 = [v:'3.1.0-stable', g:'org.jmonkeyengine']
+def jme3 = [v:'3.2.0-stable', g:'org.jmonkeyengine']
 dependencies {
 	compile "${jme3.g}:jme3-core:${jme3.v}"
 	runtime "${jme3.g}:jme3-desktop:${jme3.v}"
@@ -75,7 +77,7 @@ dependencies {
 ----
   <properties>
     <jme3_g>org.jmonkeyengine</jme3_g>
-    <jme3_v>3.1.0-stable</jme3_v>
+    <jme3_v>3.2.0-stable</jme3_v>
   </properties>
 
   <repositories>

+ 7 - 7
src/docs/asciidoc/jme3/setting_up_jme3_in_eclipse.adoc

@@ -1,6 +1,6 @@
 = Setting up JME3 in Eclipse
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: documentation, install, eclipse
 :relfileprefix: ../
@@ -16,10 +16,10 @@ Alternatively, you can use your favorite IDE: In this tutorial we show how to do
 
 == Downloading jME3
 
-The currently available JAR binaries are the nightly builds. 
+The currently available JAR binaries are the nightly builds.
 
 .  Download the most recent zipped build from link:https://github.com/jMonkeyEngine/jmonkeyengine/releases[https://github.com/jMonkeyEngine/jmonkeyengine/releases]
-.  Unzip the file and save it as `jME3.1-stable` in your home directory ($HOME). You should see the following files and directories:
+.  Unzip the file and save it as `jME3.2-stable` in your home directory ($HOME). You should see the following files and directories:
 **  `lib/` – The jMonkeyEngine binaries, and libraries used by the jMonkeyEngine. (Don't remove)
 **  `jMonkeyEngine3.jar` – Run this to see various feature demos. (optional)
 **  `javadoc/` – jME3 +++<abbr title="Application Programming Interface">API</abbr>+++ documentation. (optional)
@@ -40,7 +40,7 @@ The new project appears in the Explorer.
 Your project depends on the jMonkeyEngine libraries and needs to know where they are.
 
 .  Right-click the project in the explorer and choose `menu:Build Path[Add External Archives]`
-.  In the “JAR selection dialog, browse to the `$HOME/jME3.1-stable` directory.
+.  In the “JAR selection dialog, browse to the `$HOME/jME3.2-stable` directory.
 .  Select all JARs in the `lib` directory and click Open.
 
 All necessary JAR libraries are now on the classpath and should appear in the Referenced Libraries list. For a detailed description of the separate jar files see <<jme3/jme3_source_structure#structure_of_jmonkeyengine3_jars,this list>>.
@@ -52,14 +52,14 @@ The easiest way to make sure the asset manager can access the assets is by addin
 
 .  Go to `Project Properties`
 .  Select `Java Build Path`
-.  Under the `Source` tab click btn:[Add Folder] 
+.  Under the `Source` tab click btn:[Add Folder]
 .  Add your Assets folder
 
 
 == Writing a Simple Application
 
 .  From the menu call `menu:File[New>New Package]`. Name the src package for example `hello`.
-.  From the menu call `menu:File[New>Class]`. 
+.  From the menu call `menu:File[New>Class]`.
 **  Select package `hello`.
 **  Name the class for example `MyGame`.
 **  Superclass: `com.jme3.app.SimpleApplication`

+ 14 - 14
src/docs/asciidoc/jme3/setting_up_netbeans_and_jme3.adoc

@@ -1,6 +1,6 @@
 = Setting up JME3 in Netbeans 8.x
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: documentation, install
 :relfileprefix: ../
@@ -16,17 +16,17 @@ Alternatively, you can use your favorite IDE: In this tutorial we show how to do
 
 [IMPORTANT]
 ====
-Note that the jMonkeyEngine SDK is built in top of the NetBeans Platform, and is identical to the NetBeans IDE for Java (plus some unique NetBeans plugins). Basically it's redundant and unnecessary to set up jME for NetBeans – but if you want to, it's easily possible. 
+Note that the jMonkeyEngine SDK is built in top of the NetBeans Platform, and is identical to the NetBeans IDE for Java (plus some unique NetBeans plugins). Basically it's redundant and unnecessary to set up jME for NetBeans – but if you want to, it's easily possible.
 ====
 
 
 
 == Downloading jME3
 
-The currently available JAR binaries are the nightly builds. 
+The currently available JAR binaries are the nightly builds.
 
 .  Download the most recent zipped build from link:https://github.com/jMonkeyEngine/jmonkeyengine/releases[https://github.com/jMonkeyEngine/jmonkeyengine/releases]
-.  Unzip the file and save it as `jME3.1-stable` in your NetBeansProjects directory. You should see the following files and directories:
+.  Unzip the file and save it as `jME3.2-stable` in your NetBeansProjects directory. You should see the following files and directories:
 ..  `lib/` - The jMonkeyEngine binaries and libraries. (Don't remove.)
 ..  `jMonkeyEngine3.jar` – Run this executable jar file to see various feature demos. (optional)
 ..  `javadoc/` - jME3 +++<abbr title="Application Programming Interface">API</abbr>+++ documentation. (optional)
@@ -52,26 +52,26 @@ Your project depends on the jMonkeyEngine libraries and needs to know where they
 
 .  In the Projects window of the HelloJME3 project, btn:[RMB] click the project's `Libraries` node and choose `Add Library`.
 .  In the `Add Library` dialog, click the btn:[Create] button.
-.  For the `Library Name` enter "`jME3.1-stable`".
+.  For the `Library Name` enter "`jME3.2-stable`".
 .  For the `Library Type` select `Class Libraries`.
 .  Click btn:[OK] and the `Customize Library` dialog will open.
-.  In the `Classpath` tab, click the btn:[Add Jar/Folder] button and navigate to the `lib/` directory located in your `~/NetBeansProjects/jME3.1-stable` folder.
+.  In the `Classpath` tab, click the btn:[Add Jar/Folder] button and navigate to the `lib/` directory located in your `~/NetBeansProjects/jME3.2-stable` folder.
 .  Select all JARs in `lib/` and when done click the btn:[Add Jar/Folder] button.
-* Optional: Configuring the `Source File`  editor for NetBeans. 
-**  In the `Sources` tab, click the btn:[Add Jar/Folder] button and navigate to the `sources/` directory located in your `~/NetBeansProjects/jME3.1-stable` folder.
+* Optional: Configuring the `Source File`  editor for NetBeans.
+**  In the `Sources` tab, click the btn:[Add Jar/Folder] button and navigate to the `sources/` directory located in your `~/NetBeansProjects/jME3.2-stable` folder.
 **  Select all JARs in `sources/` and when done click the btn:[Add Jar/Folder] button.
-* Optional: Configuring the JavaDoc Popups in NetBeans.  
-**  In the `Javadoc` tab, click the btn:[Add ZIP/Folder] button and navigate to the `javadoc/` folder located in your `~/NetBeansProjects/jME3.1-stable` folder.
+* Optional: Configuring the JavaDoc Popups in NetBeans. 
+**  In the `Javadoc` tab, click the btn:[Add ZIP/Folder] button and navigate to the `javadoc/` folder located in your `~/NetBeansProjects/jME3.2-stable` folder.
 **  Select the `javadoc/` folder but do not enter the directory, the `File Name` will change to `javadoc`. Click the btn:[Add ZIP/Folder] button to close the dialog.
 .  Click the btn:[OK] button, next click the btn:[Add Library] to create the library.
 
-The necessary libraries are now on the classpath and should appear in the Libraries list. You now have a global library you can add to any project. 
+The necessary libraries are now on the classpath and should appear in the Libraries list. You now have a global library you can add to any project.
 
 [NOTE]
 ====
 If you configured your library with sources and javadocs, open a class of your HelloJME3 project, place the caret into a jme3 class, and press kbd:[Ctrl] + kbd:[Space] to see the javadoc popup, as well as code-completion.
 
-To open the source file editor, btn:[RMB] click on any jME3 class or method, then select `menu:Navigate[Go To Source]`. 
+To open the source file editor, btn:[RMB] click on any jME3 class or method, then select `menu:Navigate[Go To Source]`.
 ====
 
 == Build & Run Tips in NetBeans
@@ -85,7 +85,7 @@ How to build and run in NetBeans:
 Tips for configuring the main class in NetBeans:
 
 *  btn:[RMB] select the HelloJME3 project and choose "`Set as main project`". Now you can use the toolbar buttons (clean&build, run, debug, etc) to control this project.
-*  btn:[RMB] select the HelloJME3 project and choose `Properties`. Go to the `Run` section. 
+*  btn:[RMB] select the HelloJME3 project and choose `Properties`. Go to the `Run` section.
 **  Under Main Class, specify the class that will be executed when you run the whole project. For now, enter `hellojme3.HelloJME3`.
 
 

+ 1 - 1
src/docs/asciidoc/jme3/simpleapplication_from_the_commandline.adoc

@@ -39,7 +39,7 @@ To install the development version of jme3, download the latest  link:https://gi
 
 mkdir jme3
 cd jme3
-unzip jME3.1-stable.zip
+unzip jME3.2-stable.zip
 
 ----
 

+ 49 - 51
src/docs/asciidoc/sdk/project_creation.adoc

@@ -1,10 +1,11 @@
 = jMonkeyEngine SDK: Creating Projects
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: documentation, project, deployment, sdk
 :relfileprefix: ../
 :imagesdir: ..
+:experimental:
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
@@ -13,22 +14,21 @@ The jMonkeyEngine SDK makes it easy to get started with developing 3-D games bas
 
 == Creating a New jMonkeyEngine Project
 
-.  Choose File &gt; New Project from the main menu.
-.  In the New Project Wizard, select the template JME3 &gt; Basic Game
+.  Choose `menu:File[New Project]` from the main menu.
+.  In the New Project Wizard, select the template `menu:JME3[Basic Game]`.
 .  Click next to specify a project name, and the path where to store your new project.
 .  Click Finish. A skeleton application is created and opens in the Project Explorer.
 **  This basic jme3 application is based on the SimpleApplication class to allow an easy start with jme3.
-**  You can click the run button to run it: You will see a jMonkey cube.
+**  You can click the run button to run it: You will see a blue cube.
 
 
 
 === Project Structure
 
-[.right]
-image::sdk/jmonkeyplatform-docu-4.png[jmonkeyplatform-docu-4.png,width="421",height="298"]
+image::sdk/jmonkeyplatform-docu-4.png[jmonkeyplatform-docu-4.png,width="421",height="298",align="center"]
 
 
-Let's have a look at the abstract project structure in the Project Explorer (ctrl-1).
+Let's have a look at the abstract project structure in the Project Explorer. (kbd:[Ctrl]+kbd:[1]).
 
 *  *Project Assets node:* 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.
 *  *Source Packages node:* This is where you manage your packages and classes. For a newly created project, it contains one package and one class, `Main.java`. Double click `Main.java` to open it in the editor.
@@ -37,9 +37,12 @@ Let's have a look at the abstract project structure in the Project Explorer (ctr
 
 === Directory Structure
 
-Now let's have a look at the project's file structure in the File Explorer (ctrl-2). This explorer shows the physical directory structure on your hard drive.
+Now let's have a look at the project's file structure in the File Explorer (kbd:[Ctrl]+kbd:[2]). This explorer shows the physical directory structure on your hard drive.
+
+*  *assets* – This directory corresponds to the Project Assets node. It is needed for the assetManager.
++
+This is the recommended internal structure:
 
-*  *assets* – This directory corresponds to the Project Assets node. It is needed for the assetManager. This is the recommended internal structure:
 **  `assets/Interface`
 **  `assets/MatDefs`
 **  `assets/Materials`
@@ -56,47 +59,42 @@ Now let's have a look at the project's file structure in the File Explorer (ctrl
 *  *dist* – This directory contains the executable JAR files. (Will be generated by the jMonkeyEngine SDK when you build the project.)
 *  *test* – The jMonkeyEngine SDK will store JUnit tests here if you create any. (Optional.)
 
-Project Configuration
-
-Right-Click the project to open the Project properties.
-
-In the Run section, specify the main class of your project. (Pressing F6 runs this main class.)
-In the Run section, you can optionally configure JVM options and command line parameters *(in most cases set the-Xms VMOption [NUMBER] m for the memory usage. for example (-Xms500m). see link:http://performance.netbeans.org/howto/jvmswitches/[http://performance.netbeans.org/howto/jvmswitches/])*.
-In the Application section, specify the game title (by default the game will be named BasicGame).
-In the Application section, specify the vendor name (your name), a short description, your project's homepage, and a splash screen.
 
+=== Project Configuration
 
-==== Project Configuration
+[RMB] select the project and from the menu open the project `Properties`.
 
-Right-Click the project to open the Project properties.
+*  In the `Run` section:
+**  Specify the main class of your project. (Pressing kbd:[F6] runs this main class.)
+**  You can optionally configure JVM options and command line parameters. In most cases, set the `-Xms VMOption [NUMBER] m` for the memory usage.
+***  For example (-Xms500m).
+***  see link:http://performance.netbeans.org/howto/jvmswitches/[http://performance.netbeans.org/howto/jvmswitches/]).
+*  In the Application section:
+**  Specify the game title (by default the game will be named `BasicGame`).
+**  Specify the vendor name (your name), a short description, your project's homepage, and a splash screen.
 
-*  In the Run section, specify the main class of your project. (Pressing F6 runs this main class.) 
-*  In the Run section, you can optionally configure JVM options and command line parameters.
-*  In the Application section, specify the game title (by default the game will be named `BasicGame`).
-*  In the Application section, specify the vendor name (your name), a short description, your project's homepage, and a splash screen.
 
+=== Clean, Build and Run Cycle
 
-==== Clean, Build and Run Cycle
-
-
-image::sdk/jmonkeyplatform-docu-5.png[jmonkeyplatform-docu-5.png,width="421",height="298",align="right"]
 
+image::sdk/jmonkeyplatform-docu-5.png[jmonkeyplatform-docu-5.png,width="421",height="298",align="center"]
 
 
 [IMPORTANT]
 ====
-Pressing *F6 builds &amp; runs* the _main_ class of the _main project_. If there are several classes, or several projects, you have to specify which one you want F6 to run. Right-click a project and choose Set As Main Project, then right-click the project again and choose Properties > Run and choose a Main Class. +
-To build and run the main() of _any file that is open in the editor_, press *Shift-F6* !
+Pressing *kbd:[F6] builds & runs* the _main_ class of the _main project_. If there are several classes, or several projects, you have to specify which one you want kbd:[F6] to run. btn:[RMB] select a project and choose `Set As Main Project`, then btn:[RMB] select the project again and choose `menu:Properties[Run]` and choose a Main Class.
+
+To build and run the main() of _any file that is open in the editor_, press kbd:[Shift]+kbd:[F6]!
 ====
 
 
-*  Right-Click the project and use the context-menu to clean all generated classes and JARs.
-*  Right-Click individual files with a main method to build and run them. (Shift-F6)
-*  Press the Run button (green arrow in the toolbar) to build and run the project. (F6) 
+*  btn:[RMB] select the project and use the context-menu to clean all generated classes and JARs.
+*  btn:[RMB] select individual files with a main method to build and run them. (kbd:[Shift]+kbd:[F6])
+*  Press the btn:[Run] button (green arrow in the toolbar) to build and run the project. (kbd:[F6])
 
-*More than one project open?* 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.
+*More than one project open?* The toolbar buttons and the F-keys are bound to the main project, which is shown in bold in the Project Explorer. btn:[RMB] select a project and select `Set As Main Project` to make it respond to the toolbar buttons and F-keys.
 
-*Worried About Proprietary Lock-in?* You are never locked into the jMonkeyEngine SDK: 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: 
+*Worried About Proprietary Lock-in?* You are never locked into the jMonkeyEngine SDK: 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:
 
 [source]
 ----
@@ -104,10 +102,10 @@ ant clean; ant jar; ant run;
 ----
 
 
-==== Development Process
+== Development Process
 
-*  *Creating new files and packages:* Select the Source Packages node (or any of its subnodes), and press ctrl-N (File→New File): Use the New File wizard to create new Java classes, Java packages, Java beans, Swing forms, JUnit files, j3m Materials, j3o scenes, j3f filters, and many more.
-*  *Editing files:* Open the Projects Explorer and double-click a Java file from the Source Packages to open it in the Editor. The <<sdk/code_editor#,jMonkeyEngine SDK Code Editor>> assists you in many ways, including syntactic and semantic code coloring, code completion, and javadoc. 
+*  *Creating new files and packages:* Select the Source Packages node (or any of its subnodes), and press kbd:[Ctrl]+kbd:[N] (`menu:File[New File]`): Use the `New File` wizard to create new Java classes, Java packages, Java beans, Swing forms, JUnit files, j3m Materials, j3o scenes, j3f filters, and many more.
+*  *Editing files:* Open the Projects Explorer and double-click a Java file from the Source Packages to open it in the Editor. The <<sdk/code_editor#,jMonkeyEngine SDK Code Editor>> assists you in many ways, including syntactic and semantic code coloring, code completion, and javadoc.
 *  *Adding Assets:*
 **  You can <<sdk/model_loader_and_viewer#,import models, scenes, and materials>> as assets into your project.
 **  To add sound files and images, use your operating system's file explorer and copy the files into your project's asset directory.
@@ -123,29 +121,29 @@ FIXME
 *  *Integrated tools:* <<sdk/debugging_profiling_testing#,Debugging, Testing, Profiling>>.
 
 
-==== Adding external jar libraries
+=== Adding external jar libraries
 
 You may want to use external Java libraries in your jME project, for example content generators or artificial intelligence implementations.
 
 Add the library to the global library list:
 
-*  Select Tools→Libraries in the main menu.
-*  Click “New Library, enter a name for the library, and press OK
-*  In the “Classpath tab, press “Add JAR/Folder and select the jar file(s) needed for the library
-*  (Optional) In the “JavaDoc tab, press “Add ZIP/Folder and select the javadoc for the library, as zip file or folder.
-*  (Optional) In the “Sources tab you can select a folder or jar file containing the source files of the library.
-*  Press OK
+*  Select menu:Tools[Libraries] in the main menu.
+*  Click "`New Library`", enter a name for the library, and press btn:[OK].
+*  In the "`Classpath`" tab, press "`Add JAR/Folder`" and select the jar file(s) needed for the library.
+*  (Optional) In the "`JavaDoc`" tab, press "`Add ZIP/Folder`" and select the javadoc for the library, as zip file or folder.
+*  (Optional) In the "`Sources`" tab you can select a folder or jar file containing the source files of the library.
+*  Press btn:[OK].
 
 Add the library to a project:
 
-*  Right-Click your project and select “Properties
-*  Select “Libaries on the left and then press “Add Library
-*  Select the library from the list and press OK
+*  btn:[RMB] select your project and select "`Properties`".
+*  Select "`Libaries`" on the left and then press "`Add Library`".
+*  Select the library from the list and press btn:[OK].
 
-That's it, your project can now use the external library. If you also linked the javadoc and sources, the SDK will assist you with javadoc popups, code completion (ctrl-space) and source navigation (ctrl-click).
+That's it, your project can now use the external library. If you also linked the javadoc and sources, the SDK will assist you with javadoc popups, code completion (kbd:[Ctrl]+kbd:[Space]) and source navigation (kbd:[Ctrl]+btn:[LMB] ).
 
 
-==== Application Deployment
+=== Application Deployment
 
 *  You can <<sdk/application_deployment#,deploy>> your game as desktop application (JAR), browser applet, WebStart (JNLP), or on the Android platform.
 
@@ -156,7 +154,7 @@ The SDK contains <<sdk/sample_code#,Sample Code>> (read more).
 
 Open the Source Packages node of the JmeTests project.
 
-*  Right-click the `JME3Tests` project and choose Run. +
+*  btn:[RMB] select the `JME3Tests` project and choose Run. +
 Choose samples from the TestChooser and try out the included demos.
 *  Browse a demo's source code in the SDK's Project window to learn how a feature is implemented and used.
 *  Feel free to modify the code samples and experiment! If you break something, you can always recreate the packaged samples from the `JME3 Tests` template.

BIN
src/docs/images/jme3/external/monkey.png


BIN
src/docs/images/jme3/external/monkey_bump.png


BIN
src/docs/images/jme3/external/monkey_bump2.png


BIN
src/docs/images/jme3/external/monkey_bump2_invert.png


BIN
src/docs/images/jme3/external/monkey_final.gif


BIN
src/docs/images/jme3/external/monkeyprev1.png


+ 0 - 1
src/docs/resources/Scenes/Town/removeme.txt

@@ -1 +0,0 @@
-Remove me when there are files here.

BIN
src/docs/resources/Scenes/Town/town.zip