Bladeren bron

Fixed broken link

mitm 8 jaren geleden
bovenliggende
commit
48e21f481f
1 gewijzigde bestanden met toevoegingen van 136 en 126 verwijderingen
  1. 136 126
      src/docs/asciidoc/jme3/advanced/physics.adoc

+ 136 - 126
src/docs/asciidoc/jme3/advanced/physics.adoc

@@ -1,16 +1,25 @@
 = Physics: Gravity, Collisions, Forces
-:author: 
-:revnumber: 
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
 :keywords: physics, documentation, control
 :relfileprefix: ../../
 :imagesdir: ../..
+ifdef::backend-html5[]
+:twoinches: width='144'
+:full-width: width='100%'
+:half-width: width='50%'
+:third-width: width='33%'
+:quarter-width: width='25%'
+:half-size:
+:thumbnail: width='60'
+endif::[]
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
 A physics simulation is used in games and applications where objects are exposed to physical forces: Think of games like pool billiard and car racing simulators. Massive objects are pulled by gravity, forces cause objects to gain momentum, friction slows them down, solid objects collide and bounce off one another, etc. Action and Adventure games also make use of physics to implement solid obstacles, falling, and jumping.
 
-The jMonkeyEngine3 has built-in support for link:http://jbullet.advel.cz[jBullet Physics] (based on link:http://bulletphysics.org[Bullet Physics]) via the `com.jme3.bullet` package. This article focuses mostly on the RigidBodyControl, but also introduces you to others. 
+The jMonkeyEngine3 has built-in support for link:http://jbullet.advel.cz[jBullet Physics] (based on link:http://bulletphysics.org[Bullet Physics]) via the `com.jme3.bullet` package. This article focuses mostly on the RigidBodyControl, but also introduces you to others.
 
 If you are looking for info on how to respond to physics events such as collisions, read about <<jme3/advanced/physics_listeners#,Physics Listeners>>.
 
@@ -46,11 +55,11 @@ Due to some differences in how bullet and jME handle the scene and other objects
 
 When you use this physics simulation, values correspond to the following units:
 
-*  1 length unit (1.0f) equals 1 meter, 
+*  1 length unit (1.0f) equals 1 meter,
 *  1 weight unit (1.0f) equals 1 kilogram,
 *  most torque and rotation values are expressed in radians.
 
-Bullet physics runs internally at 60fps by default. This rate is not dependent on the actual framerate and it does not lock the framerate at 60fps. Instead, when the actual fps is higher than the physics framerate the system will display interpolated positions for the physics objects. When the framerate is lower than the physics framerate, the physics space will be stepped multiple times per frame to make up for the missing calculations. 
+Bullet physics runs internally at 60fps by default. This rate is not dependent on the actual framerate and it does not lock the framerate at 60fps. Instead, when the actual fps is higher than the physics framerate the system will display interpolated positions for the physics objects. When the framerate is lower than the physics framerate, the physics space will be stepped multiple times per frame to make up for the missing calculations.
 
 Internally, the updating and syncing of the actual physics objects in the BulletAppState happens in the following way:
 
@@ -77,14 +86,14 @@ A short overview of how to write a jME application with Physics capabilities:
 Do the following once per application to gain access to the `physicsSpace` object:
 
 .  Make your application extend `com.jme3.app.SimpleApplication`.
-.  Create a BulletAppState field: 
+.  Create a BulletAppState field:
 +
 [source,java]
 ----
 private BulletAppState bulletAppState;
 ----
 
-.  Initialize your bulletAppState and attach it to the state manager: 
+.  Initialize your bulletAppState and attach it to the state manager:
 +
 [source,java]
 ----
@@ -97,7 +106,7 @@ public void simpleInitApp() {
 
 [TIP]
 ====
-In your application, you can always access the `BulletAppState` via the ApplicationStateManager: 
+In your application, you can always access the `BulletAppState` via the ApplicationStateManager:
 
 [source,java]
 ----
@@ -117,7 +126,7 @@ For each Spatial that you want to be physical:
 .  Attach the Spatial to the rootNode (as usual).
 .  (Optional) Implement the `PhysicsCollisionListener` interface to respond to `PhysicsCollisionEvent`s.
 
-Let's look at the details: 
+Let's look at the details:
 
 
 == Create a CollisionShape
@@ -128,38 +137,38 @@ Before you can create a Physics Control, you must create a CollisionShape from t
 [cols="25,40,35", options="header"]
 |===
 
-<a| Non-Mesh CollisionShape     
-<a| Usage                                
-a| Examples 
+<a| Non-Mesh CollisionShape
+<a| Usage
+a| Examples
 
-<a| BoxCollisionShape()         
-a| Box-shaped behaviour, does not roll. 
-<a| Oblong or cubic objects like bricks, crates, furniture.  
+<a| BoxCollisionShape()
+a| Box-shaped behaviour, does not roll.
+<a| Oblong or cubic objects like bricks, crates, furniture.
 
-<a| SphereCollisionShape()      
-<a| Spherical behaviour, can roll.       
-a| Compact objects like apples, soccer balls, cannon balls, compact spaceships. 
+<a| SphereCollisionShape()
+<a| Spherical behaviour, can roll.
+a| Compact objects like apples, soccer balls, cannon balls, compact spaceships.
 
-<a| CylinderCollisionShape()    
-a| Tube-shaped and disc-shaped behaviour, can roll on one side. 
+<a| CylinderCollisionShape()
+a| Tube-shaped and disc-shaped behaviour, can roll on one side.
 a| Oblong objects like pillars. +
-Disc-shaped objects like wheels, plates. 
+Disc-shaped objects like wheels, plates.
 
-<a| CompoundCollisionShape()    
-a| A CompoundCollisionShape allows custom combinations of shapes. Use the `addChildShape()` method on the compound object to add other shapes to it and position them relative to one another. 
-a| A car with wheels (1 box + 4 cylinders), etc. 
+<a| CompoundCollisionShape()
+a| A CompoundCollisionShape allows custom combinations of shapes. Use the `addChildShape()` method on the compound object to add other shapes to it and position them relative to one another.
+a| A car with wheels (1 box + 4 cylinders), etc.
 
-<a| CapsuleCollisionShape()     
-<a| A built-in compound shape of a vertical cylinder with one sphere at the top and one sphere at the bottom. Typically used with <<jme3/advanced/walking_character#,CharacterControls>>: A cylinder-shaped body does not get stuck at corners and vertical obstacles; the rounded top and bottom do not get stuck on stair steps and ground obstacles.  
-a| Persons, animals. 
+<a| CapsuleCollisionShape()
+<a| A built-in compound shape of a vertical cylinder with one sphere at the top and one sphere at the bottom. Typically used with <<jme3/advanced/walking_character#,CharacterControls>>: A cylinder-shaped body does not get stuck at corners and vertical obstacles; the rounded top and bottom do not get stuck on stair steps and ground obstacles.
+a| Persons, animals.
 
-<a| SimplexCollisionShape()     
+<a| SimplexCollisionShape()
 a| A physical point, line, triangle, or rectangle Shape, defined by one to four points.
 a|Guardrails
 
-<a| PlaneCollisionShape()       
-a| A 2D plane. Very fast. 
-a| Flat solid floor or wall. 
+<a| PlaneCollisionShape()
+a| A 2D plane. Very fast.
+a| Flat solid floor or wall.
 
 |===
 
@@ -167,26 +176,26 @@ All non-mesh CollisionShapes can be used for dynamic, kinematic, as well as stat
 [cols="25,40,35", options="header"]
 |===
 
-<a| Mesh CollisionShapes   
-<a| Usage                                
-a| Examples 
+<a| Mesh CollisionShapes
+<a| Usage
+a| Examples
 
-<a| MeshCollisionShape        
+<a| MeshCollisionShape
 a| A mesh-accurate shape for static or kinematic Spatials. Can have complex shapes with openings and appendages. +
-*Limitations:* Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape. This Shape does not work with dynamic Spatials. 
-a| A whole static game level model. 
+*Limitations:* Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape. This Shape does not work with dynamic Spatials.
+a| A whole static game level model.
 
-<a| HullCollisionShape        
+<a| HullCollisionShape
 a| A less accurate shape for dynamic Spatials that cannot easily be represented by a CompoundShape. +
-*Limitations:* The shape is convex (behaves as if you gift-wrapped the object), i.e. openings, appendages, etc, are not individually represented. 
-a| A dynamic 3D model. 
+*Limitations:* The shape is convex (behaves as if you gift-wrapped the object), i.e. openings, appendages, etc, are not individually represented.
+a| A dynamic 3D model.
 
-<a| GImpactCollisionShape     
+<a| GImpactCollisionShape
 a| A mesh-accurate shape for dynamic Spatials. It uses link:http://gimpact.sourceforge.net/[http://gimpact.sourceforge.net/]. +
-*Limitations:* CPU intensive, use sparingly! We recommend using HullCollisionShape (or CompoundShape) instead to improve performance. Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape. 
-a| Complex dynamic objects (like spiders) in Virtual Reality or scientific simulations. 
+*Limitations:* CPU intensive, use sparingly! We recommend using HullCollisionShape (or CompoundShape) instead to improve performance. Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape.
+a| Complex dynamic objects (like spiders) in Virtual Reality or scientific simulations.
 
-a| HeightfieldCollisionShape 
+a| HeightfieldCollisionShape
 a| A mesh-accurate shape optimized for static terrains. This shape is much faster than other mesh-accurate shapes. +
 *Limitations:* Requires heightmap data. Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape.
 a|Static terrains.
@@ -197,12 +206,12 @@ On a CollisionShape, you can apply a few properties
 [cols="30,45,25", options="header"]
 |===
 
-a| CollisionShape Method 
-a| Property 
-a| Examples 
+a| CollisionShape Method
+a| Property
+a| Examples
 
-a| setScale(new Vector3f(2f,2f,2f)) 
-a| You can change the scale of collisionshapes (whether it be, Simple or Mesh). You cannot change the scale of a CompoundCollisionShape however. A sphere collision shape, will change its radius based on the X component of the vector passed in. You must scale a collision shape before attaching it to the physicsSpace, or you must readd it to the physicsSpace each time the scale changes. 
+a| setScale(new Vector3f(2f,2f,2f))
+a| You can change the scale of collisionshapes (whether it be, Simple or Mesh). You cannot change the scale of a CompoundCollisionShape however. A sphere collision shape, will change its radius based on the X component of the vector passed in. You must scale a collision shape before attaching it to the physicsSpace, or you must readd it to the physicsSpace each time the scale changes.
 a| Scale a player in the Y axis by 2: +
 `new Vector3f(1f,2f,1f)`
 
@@ -213,7 +222,7 @@ The mesh-accurate shapes can use a CollisionShapeFactory as constructor (code sa
 
 [IMPORTANT]
 ====
-Pick the simplest and most applicable shape for the mesh for what you want to do: If you give a box a sphere collision shape, it will roll; if you give a ball a box collision shape, it will sit on a slope. If the shape is too big, the object will seem to float; if the shape is too small it will seem to sink into the ground. During development and debugging, you can make collision shapes visible by adding the following line after the bulletAppState initialization: 
+Pick the simplest and most applicable shape for the mesh for what you want to do: If you give a box a sphere collision shape, it will roll; if you give a ball a box collision shape, it will sit on a slope. If the shape is too big, the object will seem to float; if the shape is too small it will seem to sink into the ground. During development and debugging, you can make collision shapes visible by adding the following line after the bulletAppState initialization:
 
 [source,java]
 ----
@@ -236,14 +245,14 @@ bulletAppState.setDebugEnabled(true);
 *  One way of using a constructor and a Geometry's mesh for static Spatials:
 [source,java]
 ----
-MeshCollisionShape level_shape = 
+MeshCollisionShape level_shape =
     new MeshCollisionShape(level_geo.getMesh());
 ----
 
 *  One way of using a constructor and a Geometry's mesh for dynamic Spatials:
 [source,java]
 ----
-HullCollisionShape shape = 
+HullCollisionShape shape =
     new HullCollisionShape(katamari_geo.getMesh());
 ----
 
@@ -257,7 +266,7 @@ CompoundCollisionShape myComplexShape =
 *  Creating a dynamic HullCollisionShape shape (or CompoundCollisionShape with HullCollisionShapes as children) for a Geometry:
 [source,java]
 ----
-CollisionShape shape = 
+CollisionShape shape =
     CollisionShapeFactory.createDynamicMeshShape(spaceCraft);
 ----
 
@@ -268,7 +277,7 @@ CompoundCollisionShape boxShape =
     CollisionShapeFactory.createBoxShape((Node) crate_geo);
 ----
 
-*  A round, non-mesh-accurate compound shape: 
+*  A round, non-mesh-accurate compound shape:
 [source,java]
 ----
 SphereCollisionShape sphereShape =
@@ -279,22 +288,22 @@ SphereCollisionShape sphereShape =
 
 == Create PhysicsControl
 
-BulletPhysics are available in jME3 through PhysicsControls classes from the com.jme3.bullet.control package. jME3's PhysicsControl classes directly extend BulletPhysics objects and are the recommended way to use physics in a jME3 application. PhysicsControls are flexible and can be added to any Spatial to make it act according to physical properties. 
+BulletPhysics are available in jME3 through PhysicsControls classes from the com.jme3.bullet.control package. jME3's PhysicsControl classes directly extend BulletPhysics objects and are the recommended way to use physics in a jME3 application. PhysicsControls are flexible and can be added to any Spatial to make it act according to physical properties.
 [cols="20,40,40", options="header"]
 |===
 
 a|Standard PhysicsControls
 a| Usage
-a| Examples 
+a| Examples
 
 a|RigidBodyControl
-a|The most commonly used PhysicsControl. You can use it for dynamic objects (solid objects that freely affected by collisions, forces, or gravity), for static objects (solid but not affected by any forces), or kinematic objects (remote-controlled solid objects). 
+a|The most commonly used PhysicsControl. You can use it for dynamic objects (solid objects that freely affected by collisions, forces, or gravity), for static objects (solid but not affected by any forces), or kinematic objects (remote-controlled solid objects).
 a|Impacting projectiles, moving obstacles like crates, rolling and bouncing balls, elevators, flying aircaft or space ships. +
 Solid immobile floors, walls, static obstacles.
 
 a|GhostControl
-a|Use for collision and intersection detection between physical objects. A GhostControl itself is _non-solid_ and invisible. GhostControl moves with the Spatial it is attached to. Use GhostControls to <<jme3/advanced/physics_listeners#,implement custom game interactions>> by adding it to a visible Geometry. 
-a|A monster's “aggro radius, CharacterControl collisions, motion detectors, photo-electric alarm sensors, poisonous or radioactive perimeters, life-draining ghosts, etc. 
+a|Use for collision and intersection detection between physical objects. A GhostControl itself is _non-solid_ and invisible. GhostControl moves with the Spatial it is attached to. Use GhostControls to <<jme3/advanced/physics_listeners#,implement custom game interactions>> by adding it to a visible Geometry.
+a|A monster's “aggro radius, CharacterControl collisions, motion detectors, photo-electric alarm sensors, poisonous or radioactive perimeters, life-draining ghosts, etc.
 
 |===
 [cols="20,40,40", options="header"]
@@ -302,19 +311,19 @@ a|A monster's “aggro radius, CharacterControl collisions, motion detectors, ph
 
 a|Special PhysicsControls
 a| Usage
-a| Examples 
+a| Examples
 
 a|VehicleControl +
 PhysicsVehicleWheel
-a| Special Control used for <<jme3/advanced/vehicles#,&quot;terrestrial&quot;  vehicles with suspension and wheels>>. 
+a| Special Control used for <<jme3/advanced/vehicles#,&quot;terrestrial&quot;  vehicles with suspension and wheels>>.
 a|Cars, tanks, hover crafts, ships, motorcycles…
 
 a|CharacterControl
 a|Special Control used for <<jme3/advanced/walking_character#,Walking Character>>s.
-a|Upright walking persons, animals, robots… 
+a|Upright walking persons, animals, robots…
 
 a|RagDollControl
-a|Special Control used for <<jme3/advanced/ragdoll#,collapsing, flailing, or falling characters>> 
+a|Special Control used for <<jme3/advanced/ragdoll#,collapsing, flailing, or falling characters>>
 a|Falling persons, animals, robots, “Rag dolls
 
 |===
@@ -324,18 +333,18 @@ Click the links for details on the special PhysicsControls. This article is abou
 
 === Physics Control Code Samples
 
-The most commonly used physics control is RigidBodyControl.  The RigidBodyControl constructor takes up to two parameters:  a collision shape and a mass (a float in kilograms).  The mass parameter also determines whether the object is dynamic (movable) or static (fixed). For a static object such as a floor or wall, specify zero mass. 
+The most commonly used physics control is RigidBodyControl.  The RigidBodyControl constructor takes up to two parameters:  a collision shape and a mass (a float in kilograms).  The mass parameter also determines whether the object is dynamic (movable) or static (fixed). For a static object such as a floor or wall, specify zero mass.
 
 [source,java]
 ----
-RigidBodyControl myThing_phys = 
+RigidBodyControl myThing_phys =
     new RigidBodyControl( myThing_shape , 123.0f ); // dynamic
 ----
 
 [source,java]
 ----
-RigidBodyControl myDungeon_phys = 
-    new RigidBodyControl( myDungeon_shape , 0.0f ); // static 
+RigidBodyControl myDungeon_phys =
+    new RigidBodyControl( myDungeon_shape , 0.0f ); // static
 ----
 
 
@@ -375,7 +384,7 @@ Spheres and Boxes automatically fall back on the correct default CollisionShape
 
 For each physical Spatial in the scene:
 
-.  Add a PhysicsControl to a Spatial. 
+.  Add a PhysicsControl to a Spatial.
 +
 [source,java]
 ----
@@ -387,16 +396,16 @@ myThing_geo.addControl(myThing_phys);
 
 == Add PhysicsControl to PhysicsSpace
 
-The PhysicsSpace is an object in BulletAppState that is like a rootNode for Physics Controls. 
+The PhysicsSpace is an object in BulletAppState that is like a rootNode for Physics Controls.
 
-*  Just like you add the Geometry to the rootNode, you add its PhysicsControl to the PhysicsSpace. 
+*  Just like you add the Geometry to the rootNode, you add its PhysicsControl to the PhysicsSpace.
 [source,java]
 ----
-bulletAppState.getPhysicsSpace().add(myThing_phys); 
-rootNode.attachChild(myThing_geo); 
+bulletAppState.getPhysicsSpace().add(myThing_phys);
+rootNode.attachChild(myThing_geo);
 ----
 
-*  When you remove a Geometry from the scene and detach it from the rootNode, also remove the PhysicsControl from the PhysicsSpace: 
+*  When you remove a Geometry from the scene and detach it from the rootNode, also remove the PhysicsControl from the PhysicsSpace:
 [source,java]
 ----
 bulletAppState.getPhysicsSpace().remove(myThing_phys);
@@ -425,10 +434,10 @@ When you import a model from blender, it often comes as a Node (even if it only
 
 // Doesn't scale
 // This modified version contains Node -> Geometry (name = "MonkeyHeadGeom")
-Spatial model = assetManager.loadModel("Models/MonkeyHead.j3o"); 
+Spatial model = assetManager.loadModel("Models/MonkeyHead.j3o");
 model.addControl(new RigidBodyControl(0));
 // Won't work as this is now a CompoundCollisionShape containing a MeshCollisionShape
-model.getControl(RigidBodyControl.class).getCollisionShape().setScale(new Vector3f(2, 2, 2)); 
+model.getControl(RigidBodyControl.class).getCollisionShape().setScale(new Vector3f(2, 2, 2));
 bulletAppState.getPhysicsSpace().add(model);
 
 // Works fine
@@ -436,15 +445,16 @@ Spatial model = assetManager.loadModel("Models/MonkeyHead.j3o"); // Same Model
  // IMPORTANT : You must navigate to the Geometry for this to work
 Geometry geom = ((Geometry) ((Node) model).getChild("MonkeyHeadGeom"));
 geom.addControl(new RigidBodyControl(0));
-// Works great (scaling of a MeshCollisionShape)	
+// Works great (scaling of a MeshCollisionShape)
 geom.getControl(RigidBodyControl.class).getCollisionShape().setScale(new Vector3f(2, 2, 2));
 bulletAppState.getPhysicsSpace().add(geom);
 
 ----
 
 With the corresponding output below:
-link:http://i.imgur.com/fAXlF.png[External Link]
-link:http://i.imgur.com/Josua.png[External Link]
+
+image:http://i.imgur.com/fAXlF.png[http://i.imgur.com/fAXlF.png,{third-width}]
+image:http://i.imgur.com/Josua.png[http://i.imgur.com/fAXlF.png,{third-width}]
 
 
 === PhysicsSpace Code Samples
@@ -460,7 +470,7 @@ a|setGravity(new Vector3f(0, -9.81f, 0));
 a|Specifies the global gravity.
 
 a|setAccuracy(1f/60f);
-a|Specifies physics accuracy. The higher the accuracy, the slower the game. Decrease value if objects are passing through one another, or bounce oddly. (e.g. Change value from 1f/60f to something like 1f/80f.) 
+a|Specifies physics accuracy. The higher the accuracy, the slower the game. Decrease value if objects are passing through one another, or bounce oddly. (e.g. Change value from 1f/60f to something like 1f/80f.)
 
 a|setMaxSubSteps(4);
 a|Compensates low FPS: Specifies the maximum amount of extra steps that will be used to step the physics when the game fps is below the physics fps. This maintains determinism in physics in slow (low-fps) games. For example a maximum number of 2 can compensate for framerates as low as 30 fps (physics has a default accuracy of 60 fps). Note that setting this value too high can make the physics drive down its own fps in case its overloaded.
@@ -480,35 +490,35 @@ On a RigidBodyControl, you can set the following physical properties.
 [cols="3", options="header"]
 |===
 
-a| RigidBodyControl Method 
-a| Property 
-a| Examples 
+a| RigidBodyControl Method
+a| Property
+a| Examples
 
-a| setGravity(new Vector3f(0f,-9.81f,0f)) 
+a| setGravity(new Vector3f(0f,-9.81f,0f))
 a| You can change the gravity of individual physics objects after they were added to the PhysicsSpace. Gravity is a vector pointing from this Spatial towards the source of gravity. The longer the vector, the stronger is gravity. +
 If gravity is the same absolute direction for all objects (e.g. on a planet surface), set this vector globally on the PhysicsSpace object and not individually. +
 If the center of gravity is relative (e.g. towards a black hole) then setGravity() on each Spatial to constantly adjust the gravity vectors at each tick of their update() loops.
 a|For planet earth: +
 `new Vector3f(0f,-9.81f,0f)`
 
-a| setMass(1f) 
+a| setMass(1f)
 a| Sets the mass in kilogram. Dynamic objects have masses &gt; 0.0f. Heavy dynamic objects need more force to be moved and light ones move with small amounts of force. +
-Static immobile objects (walls, floors, including buildings and terrains) must have a mass of zero! 
+Static immobile objects (walls, floors, including buildings and terrains) must have a mass of zero!
 a| Person: 60f, ball: 1.0f +
 Floor: 0.0f (!)
 
-a| setFriction(1f) 
+a| setFriction(1f)
 a| Friction. +
-Slippery objects have low friction. The ground has high friction. 
+Slippery objects have low friction. The ground has high friction.
 a| Ice, slides: 0.0f +
-Soil, concrete, rock: 1.0f 
+Soil, concrete, rock: 1.0f
 
-a| setRestitution(0.0f) 
+a| setRestitution(0.0f)
 a| Bounciness. By default objects are not bouncy (0.0f). For a bouncy rubber object set this &gt; 0.0f. +
 Both the object and the surface must have non-zero restitution for bouncing to occur. +
-This setting has an impact on performance, so use it sparingly. 
+This setting has an impact on performance, so use it sparingly.
 a| Brick: 0.0f +
-Rubber ball: 1.0f 
+Rubber ball: 1.0f
 
 a|setCcdMotionThreshold()
 a|The amount of motion in 1 physics tick to trigger the continuous motion detection in moving objects that push one another. Rarely used, but necessary if your moving objects get stuck or roll through one another.
@@ -520,18 +530,18 @@ On a RigidBodyControl, you can apply the following physical forces:
 [cols="2", options="header"]
 |===
 
-a| RigidBodyControl Method 
-a| Motion 
+a| RigidBodyControl Method
+a| Motion
 
 a| setPhysicsLocation()
-a|Positions the objects. Do not use setLocalTranslation() for physical objects. Important: Make certain not to make CollisionShapes overlap when positioning them. 
+a|Positions the objects. Do not use setLocalTranslation() for physical objects. Important: Make certain not to make CollisionShapes overlap when positioning them.
 
 a| setPhysicsRotation()
 a|Rotates the object. Do not use setLocalRotate() for physical objects.
 
-a| setKinematic(true) 
+a| setKinematic(true)
 a| By default, RigidBodyControls are dynamic (kinematic=false) and are affected by forces. If you set kinematic=true, the object is no longer affected by forces, but it still affects others. A kinematic is solid, and must have a mass. +
-(See detailed explanation below.) 
+(See detailed explanation below.)
 
 |===
 
@@ -540,12 +550,12 @@ a| By default, RigidBodyControls are dynamic (kinematic=false) and are affected
 
 All physical objects…
 
-*  must not overlap. 
+*  must not overlap.
 *  can detect collisions and report several values about the impact.
 *  can respond to collisions dynamically, or statically, or kinematically.
 [cols="4", options="header"]
 |===
-|Property |Static |Kinematic |Dynamic 
+|Property |Static |Kinematic |Dynamic
 
 a|Examples
 a|Immobile obstacles: Floors, walls, buildings, …
@@ -554,7 +564,7 @@ a|Interactive objects: Rolling balls, movable crates, falling pillars, zero-g sp
 
 a|Does it have a mass?
 a|no, 0.0f
-a|yesfootnote:[Inertia is calculated for kinematic objects, and you need mass to do that.], &gt;0.0f 
+a|yesfootnote:[Inertia is calculated for kinematic objects, and you need mass to do that.], &gt;0.0f
 a|yes, &gt;0.0f
 
 a|How does it move?
@@ -582,9 +592,9 @@ a|no
 a|no
 a|yes
 
-a|How to activate this behaviour? 
+a|How to activate this behaviour?
 a|setMass(0f); +
-setKinematic(false); 
+setKinematic(false);
 a|setMass(1f); +
 setKinematic(true);
 a|setMass(1f); +
@@ -595,14 +605,14 @@ setKinematic(false);
 ==== When Do I Use Kinematic Objects?
 
 *  Kinematics are solid and characters can “stand on them.
-*  When they collide, Kinematics push dynamic objects, but a dynamic object never pushes a Kinematic. 
-*  You can hang kinematics up “in mid-air and attach other PhysicsControls to them using <<jme3/advanced/hinges_and_joints#,hinges and joints>>. Picture them as “air hooks for flying aircraft carriers, floating islands in the clouds, suspension bridges, swings, chains… 
+*  When they collide, Kinematics push dynamic objects, but a dynamic object never pushes a Kinematic.
+*  You can hang kinematics up “in mid-air and attach other PhysicsControls to them using <<jme3/advanced/hinges_and_joints#,hinges and joints>>. Picture them as “air hooks for flying aircraft carriers, floating islands in the clouds, suspension bridges, swings, chains…
 *  You can use Kinematics to create mobile remote-controlled physical objects, such as moving elevator platforms, flying blimps/airships. You have full control how Kinematics move, they never “fall or “topple over.
 
 
 [IMPORTANT]
 ====
-The position of a kinematic RigidBodyControl is updated automatically depending on its spatial's translation. You move Spatials with a kinematic RigidBodyControl programmatically, that means you write translation and rotation code in the update loop. You describe the motion of kinematic objects either by using methods such as `setLocalTranslation()` or `move()`, or by using a <<jme3/advanced/motionpath#,MotionPath>>. 
+The position of a kinematic RigidBodyControl is updated automatically depending on its spatial's translation. You move Spatials with a kinematic RigidBodyControl programmatically, that means you write translation and rotation code in the update loop. You describe the motion of kinematic objects either by using methods such as `setLocalTranslation()` or `move()`, or by using a <<jme3/advanced/motionpath#,MotionPath>>.
 ====
 
 
@@ -613,29 +623,29 @@ Use the following methods to move dynamic physical objects.
 [cols="2", options="header"]
 |===
 
-a| PhysicsControl Method 
-a| Motion 
+a| PhysicsControl Method
+a| Motion
 
-a| setLinearVelocity(new Vector3f(0f,0f,1f)) 
-a| Set the linear speed of this object. 
+a| setLinearVelocity(new Vector3f(0f,0f,1f))
+a| Set the linear speed of this object.
 
-a| setAngularVelocity(new Vector3f(0f,0f,1f)) 
-a| Set the rotational speed of the object; the x, y and z component are the speed of rotation around that axis. 
+a| setAngularVelocity(new Vector3f(0f,0f,1f))
+a| Set the rotational speed of the object; the x, y and z component are the speed of rotation around that axis.
 
-a| applyCentralForce(…) 
-<a| Move (push) the object once with a certain moment, expressed as a Vector3f.  
+a| applyCentralForce(…)
+<a| Move (push) the object once with a certain moment, expressed as a Vector3f.
 
-a| applyForce(…) 
-a| Move (push) the object once with a certain moment, expressed as a Vector3f. Optionally, you can specify where on the object the pushing force hits. 
+a| applyForce(…)
+a| Move (push) the object once with a certain moment, expressed as a Vector3f. Optionally, you can specify where on the object the pushing force hits.
 
-a| applyTorque(…) 
-a| Rotate (twist) the object once around its axes, expressed as a Vector3f. 
+a| applyTorque(…)
+a| Rotate (twist) the object once around its axes, expressed as a Vector3f.
 
-a| applyImpulse(…) 
-a| An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball. 
+a| applyImpulse(…)
+a| An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball.
 
-a| applyTorqueImpulse(…) 
-a| An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball. 
+a| applyTorqueImpulse(…)
+a| An idealised change of momentum. This is the kind of push that you would use on a pool billiard ball.
 
 a| clearForces()
 a|Cancels out all forces (force, torque) etc and stops the motion.
@@ -653,8 +663,8 @@ PhysicsControls also support the following advanced features:
 [cols="2", options="header"]
 |===
 
-a| PhysicsControl Method 
-a| Property 
+a| PhysicsControl Method
+a| Property
 
 a| setCollisionShape(collisionShape)
 a|Changes the collision shape after creation.
@@ -672,13 +682,13 @@ a| setAngularFactor(1f)
 a|Set the amount of rotation that will be applied. A value of zero will cancel all rotational force outcome. (?)
 
 a| setSleepingThreshold(float,float)
-a|Sets the sleeping thresholds which define when the object gets deactivated to save resources. The first value is the linear threshold and the second the angular. Low values keep the object active when it barely moves (slow precise performance), high values put the object to sleep immediately (imprecise fast performance). (?) 
+a|Sets the sleeping thresholds which define when the object gets deactivated to save resources. The first value is the linear threshold and the second the angular. Low values keep the object active when it barely moves (slow precise performance), high values put the object to sleep immediately (imprecise fast performance). (?)
 
-a| setCcdMotionThreshold(0f) 
+a| setCcdMotionThreshold(0f)
 a|Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection in moving objects that push one another. This avoids the problem of fast objects moving through other objects. Set to zero to disable (default).
 
 a| setCcdSweptSphereRadius(.5f)
-a|Bullet does not use the full collision shape for continuous collision detection, instead it uses a “swept sphere shape to approximate a motion, which can be imprecise and cause strange behaviors such as objects passing through one another or getting stuck. Only relevant for fast moving dynamic bodies. 
+a|Bullet does not use the full collision shape for continuous collision detection, instead it uses a “swept sphere shape to approximate a motion, which can be imprecise and cause strange behaviors such as objects passing through one another or getting stuck. Only relevant for fast moving dynamic bodies.
 
 |===
 
@@ -699,7 +709,7 @@ You can `setApplyPhysicsLocal(true)` for an object to make it move relatively to
 *Solution:* A huge static city or terrain model should never be loaded as one huge mesh. Divide the scene into multiple physics objects, with each its own CollisionShape. Choose the most simple CollisionShape possible; use mesh-accurate shapes only for the few cases where precision is more important than speed. For example, you can use the very fast `PlaneCollisionShape` for flat streets, floors and the outside edge of the scene, if you keep these pieces separate.
 
 *  *Eject?* If you have physical nodes jittering wildy and being ejected “for no apparent reason, it means you have created an impossible state – solid objects overlapping. This can happen when you position solid spatials too close to other solid spatials, e.g. when moving them with setLocalTranslation(). +
-*Solution:* Use the debug mode to make CollisionShapes visible and verify that CollisionShapes do not overlap. 
+*Solution:* Use the debug mode to make CollisionShapes visible and verify that CollisionShapes do not overlap.
 [source,java]
 ----
 bulletAppState.getPhysicsSpace().enableDebug(assetManager);