@ -40,14 +40,20 @@ To create 3D models and scenes, you need a 3D Mesh Editor such as <object classi
</p>
<p>
<strong>Tip:</strong>Consider creating<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics"><paramname="text"value="<html><u>UV textures</u></html>"><paramname="textColor"value="blue"></object> for more complex models, it looks more professional.
<strong>Tip:</strong>Learn how to create<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/UV_Map_Basics"><paramname="text"value="<html><u>UV textures</u></html>"><paramname="textColor"value="blue"></object> for more complex models, it looks more professional.
</p>
<p>
3D mesh editors are third-party products, so please consult their documentation for instructions how to use them. Here is an example workflow for Blender users:
3D model editors are third-party products, so please consult their documentation for instructions how to use them. Here is an example workflow for Blender users:
</p>
<ul>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/external/blender.html">Creating jME3 compatible 3D models in Blender</a></div>
</li>
</ul>
<p>
To export your models as Ogre <acronymtitle="Extensible Markup Language">XML</acronym> meshes with materials:
<td>cleanup()</td><td>This methid is executed after you remove the AppState from the game. Here you implement clean-up code for when this state is detached. You can modify the scene graph from here (e.g. detach nodes).</td>
<td>cleanup()</td><td>This method is executed after you remove the AppState from the game. Here you implement clean-up code for when this state is detached. You can modify the scene graph from here (e.g. detach nodes).</td>
</tr>
<tr>
<td>update(float tpf)</td><td>Here you implement the behaviour that you want to hook into the simpleUpdate() loop while this state is attached to the game. You can modify the scene graph from here.</td>
@ -272,6 +272,11 @@ Convert assets as described above.</div>
<p>
<p><div>If you don't use the <acronymtitle="Software Development Kit">SDK</acronym> for some reason, you can still convert models to j3o format: Load any model in Ogre3D or Wavefront format with the AssetManager.loadModel() as a spatial. Then save the spatial as j3o file using <ahref="/com/jme3/gde/core/docs/jme3/advanced/save_and_load.html">BinaryExporter</a>.
</div></p>
</p>
<p>
<p><div>Use file version control and let team members check out the project. Your developers open the project in Eclipse (etc) as they are used to. Additionally to their graphic tools, ask your graphic designers to install the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym>, and to check out the codeless project that you just prepared. This makes it easy for non-coding team member to browse and preview game assets, to arrange scenes, and to convert files. At the same time, non-coders don't accidentally mess with code, and developers don't accidentally mess with assets. :)
@ -64,7 +64,7 @@ The camera object is created with the following defaults:
<td>cam.resize(width, height, fixAspect)</td><td>Resize an existing camera object while keeping all other settings. Set fixAspect to true to adjust the aspect ratio (?)</td>
</tr>
<tr>
<td>cam.setFrustum( near, far, left, right, top, bottom )</td><td>The frustum is defined by the near/far plane, left/rught plane, top/bottom plane (all distances as float values)</td>
<td>cam.setFrustum( near, far, left, right, top, bottom )</td><td>The frustum is defined by the near/far plane, left/right plane, top/bottom plane (all distances as float values)</td>
</tr>
<tr>
<td>cam.setFrustumPerspective( fovY, aspect ratio, near, far)</td><td>The frustum is defined by view angle along the Y axis (in degrees), aspect ratio, and the near/far plane.</td>
@ -52,7 +52,7 @@ To implement game logic for a type of spatial, you will either extend AbstractCo
Use <span><ahref="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Controls</a></span> to implement the <em>behaviour of types of game entities</em>.
</p>
<ul>
<li><div> Use Controls add a type of behaviour (that is, methods and fields) to individual Spatials. </div>
<li><div> Use Controls to add a type of behaviour (that is, methods and fields) to individual Spatials. </div>
</li>
<li><div> Each Control has its own <code>update()</code> loop that hooks into <code>simpleUpdate()</code>. Use Controls to move blocks of code out of the <code>simpleUpdate()</code> loop.</div>
</li>
@ -91,7 +91,7 @@ The possibilities are endless. <img src="/wiki/lib/images/smileys/icon_smile.gif
</p>
</div>
<!-- EDIT2 SECTION "Usage" [1748-3212] -->
<!-- EDIT2 SECTION "Usage" [1748-3215] -->
<h2><a>Example Code</a></h2>
<div>
@ -115,7 +115,7 @@ Existing examples in the code base include:
<li><div> The recommended solution is to specify each triangle twice, the second time with the opposite order of vertices. The second, reversed triangle makes up the backface. <br/>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">Developer specification of the jME3 material system (.j3md,.j3m)</a></div>
<h3><a>Example: Adding Color Keying to the Lighting.j3md Material Definition</a></h3>
<div>
@ -384,7 +384,7 @@ A result preview can be seen here: <object classid="java:org.netbeans.modules.ja
</p>
</div>
<!-- EDIT12 SECTION "Example: Adding Color Keying to the Lighting.j3md Material Definition" [8877-10367] -->
<!-- EDIT12 SECTION "Example: Adding Color Keying to the Lighting.j3md Material Definition" [8876-10366] -->
<h3><a>Step by step</a></h3>
<div>
<ul>
@ -414,12 +414,12 @@ A result preview can be seen here: <object classid="java:org.netbeans.modules.ja
</p>
</div>
<!-- EDIT13 SECTION "Step by step" [10368-10987] -->
<!-- EDIT13 SECTION "Step by step" [10367-10986] -->
<h3><a>JME3 and OpenGL 3 & 4 compatibility</a></h3>
<div>
<p>
GLSL 1.0 to 1.2 comes with build in attributes and uniforms (ie, gl_Vertex, gl_ModelViewMatrix, etc…).<br/>
GLSL 1.0 to 1.2 comes with built in attributes and uniforms (ie, gl_Vertex, gl_ModelViewMatrix, etc…).<br/>
Those attributes are deprecated since GLSL 1.3 (opengl 3), hence JME3 global uniforms and attributes. Here is a list of deprecated attributes and their equivalent in JME3<br/>
</p>
@ -452,9 +452,9 @@ Those attributes are deprecated since GLSL 1.3 (opengl 3), hence JME3 global uni
Ambient Occlusion refers to the shadows that nearby objects cast on each other under an ambient lighting. It‘s an approximation of how light radiates in a real life scene. To activate Ambient Occlusion shadows, add a jME SceneProcessor named <code>com.jme3.post.SSAOFilter</code> to the viewPort. SSAO stands for the Screen Space Ambient Occlusion technique.
</p>
<pre>FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
SSAOFilter ssaoFilter = new SSAOFilter(12.94f, 43.92f, 0.33f, 0.61);
SSAOFilter ssaoFilter = new SSAOFilter(12.94f, 43.92f, 0.33f, 0.61f);
@ -151,18 +151,20 @@ Only localize messages and UI text!
Typical problems include:
</p>
<ul>
<li><div> Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization</div>
<li><div> Localized strings will be of vastly different lengths and will totally break your UI layout. ⇒ Test every localization.</div>
</li>
<li><div> Strings with variable text or numbers don't work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or find a work-around.</div>
<li><div> Strings with variable text or numbers don't work the same in different languages. ⇒ Either work in grammatical cases/numbers/gender for each language, or use <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms"><paramname="text"value="<html><u>gettext</u></html>"><paramname="textColor"value="blue"></object> or <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://userguide.icu-project.org/formatparse/messages"><paramname="text"value="<html><u>ICU4J</u></html>"><paramname="textColor"value="blue"></object>.</div>
</li>
<li><div> The localizer only sees the strings, without any context. E.g. does "Search History" mean "display the history of searches", or "search through the history"? ⇒ Use clear key labels and work closely with the localizers if they require extra info.</div>
<li><div> The localizer only sees the strings, without any context. E.g. does "Search History" mean "display the history of searches", or "search through the history"? ⇒ Use clear key labels. Work closely with the localizers if they require extra info, and add that info as comments to the translation file.</div>
</li>
<li><div> Broken international characters ⇒ Make sure the files are saved with the right character encoding for the language.</div>
<li><div> Broken international characters ⇒ Make sure the files are saved with the same character encoding as the font file(s) you're using. Nowadays, that usually means UTF-8 since font files tend to come for Unicode.</div>
</li>
<li><div> Missing international characters ⇒ Make sure that there's a glyph for every needed character in your font, either by using more complete font files or by having the translation changed.</div>
All Geometries need a Materual. Every Material is based on a Material Definition. The most common Material Definitions are included in the engine, advanced users can create custom ones.
All Geometries need a Material to be visible. Every Material is based on a Material Definition. Material definitions provide the "logic" for the material, and a shader draws the material according to the parameters specified in the definition. The J3MD file abstracts the shader and its configuration away from the user, allowing a simple interface where the user can simply set a few parameters on the material to change its appearance and the way its handled by the shaders.
</p>
<p>
The most common Material Definitions are included in the engine, advanced users can create custom ones. In this case you will also be interested in the <ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">in-depth developer specification of the jME3 material system</a>.
Material mat = new Material(assetManager, // Create new material and...
@ -13,44 +22,44 @@ mat.setColor("Color", ColorRGBA.Blue); // Set one or more
myGeometry.setMaterial(mat); // Use material on this Geometry.</pre>
<p>
<p><div>If you use one custom material very often, read about storing material configurations in user-friendly<ahref="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3m Material Files</a>. Either <ahref="/com/jme3/gde/core/docs/sdk/material_editing.html">use the jMonkeyEngine SDK to create .j3m files</a> (easier), or<ahref="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">write .j3m files in a text editor</a>.
<p><div>If you use one custom material with certain settings very often, learn about storing material settings in<ahref="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">j3m Material Files</a>. You either <ahref="/com/jme3/gde/core/docs/sdk/material_editing.html">use the jMonkeyEngine SDK to create .j3m files</a> (user-friendly), or you<ahref="/com/jme3/gde/core/docs/jme3/advanced/j3m_material_files.html">write .j3m files in a text editor</a> (IDE-independent).
</div></p>
</p>
</div>
<!-- EDIT1 SECTION "How to Use Material Definitions (.j3md)" [1-987] -->
<!-- EDIT1 SECTION "How to Use Material Definitions (.j3md)" [1-1585] -->
<h2><a>Preparing a Material</a></h2>
<div>
<p>
In the <ahref="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> list,
In the <ahref="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Materials Overview</a> list:
</p>
<ol>
<li><div> Choose a Material Definition that has the features that you need. </div>
<ul>
<li><div> Tip: If you don't know, you can always start with <code>Unshaded.j3md</code>.</div>
<li><div> Tip: If you don't know, start with <code>Unshaded.j3md</code> or <code>Lighting.j3md</code>.</div>
</li>
</ul>
</li>
<li><div> Look at the applicable parameters of the Material Definition and determine which parameters you need to achieve the desired effect (e.g. "glow" or "color"). Most parameters are optional.</div>
<li><div> Look at the applicable parameters of the Material Definition and determine which parameters you need to achieve the desired effect (e.g. "glow" or "color"). Most parameters are optional!</div>
</li>
<li><div> Create and save the necessary Texture files to your assets directory.</div>
<li><div> Create and save the necessary Texture files to your <code>assets/Textures</code> directory.</div>
<ul>
<li><div> E.g. ColorMap; DiffuseMap, NormalMap, AlphaMap, etc…</div>
<li><div> E.g. mytex_diffuse.png as ColorMap / DiffuseMap, mytex_normal.png as NormalMap, mytex_alpha.png as AlphaMap, etc…</div>
</li>
</ul>
</li>
<li><div> Determine the required values to achieve the effect that you want.</div>
<ul>
<li><div> E.g. Colors, floats, booleans, etc… </div>
<li><div> E.g. set colors, floats, booleans, etc… </div>
</li>
</ul>
</li>
</ol>
</div>
<!-- EDIT2 SECTION "Preparing a Material" [988-1647] -->
<!-- EDIT2 SECTION "Preparing a Material" [1586-2329] -->
<h2><a>Using a Material</a></h2>
<div>
@ -68,7 +77,7 @@ In your Java code,
<li><div> Apply your prepared Material to a Geometry: <pre>myGeometry.setMaterial(mat);</pre>
</div>
</li>
<li><div> (Optional) Adjust the texture scale: <pre>geometry.scaleTextureCoordinates(new Vector2f(1f, .5f));</pre>
<li><div> (Optional) Adjust the texture scale of the mesh: <pre>myGeometryMesh.scaleTextureCoordinates(new Vector2f(2f, 2f));</pre>
</div>
</li>
</ol>
@ -79,7 +88,7 @@ For details see also: <a href="/com/jme3/gde/core/docs/jme3/intermediate/how_to_
</p>
</div>
<!-- EDIT3 SECTION "Using a Material" [1648-2337] -->
<!-- EDIT3 SECTION "Using a Material" [2330-3036] -->
<h2><a>Creating a Custom Material Definition</a></h2>
<div>
<p>
Check out the <ahref="/com/jme3/gde/core/docs/jme3/build_from_sources.html">engine source code</a> and have a look at how Material Definitions are implemented. You can create your own Material Definitions and place them in your projects MatDefs directory.
First read the <ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">developer specification of the jME3 material system (.j3md,.j3m)</a>. Also check out the <ahref="/com/jme3/gde/core/docs/jme3/build_from_sources.html">engine source code</a> and have a look at how some Material Definitions are implemented.
</p>
<p>
You can create your own Material Definitions and place them in your project's <code>assets/MatDefs</code> directory.
</p>
<ol>
<li><div> Find the existing MatDefs are in <code>engine/src/core-data/Common/MatDefs/</code>. </div>
<li><div> Find the existing MatDefs in <code>engine/src/core-data/Common/MatDefs/</code>. </div>
</li>
<li><div> Open a Something.j3md file in a text editor. You see that this jme3 file defines Material Parameters and Techniques.</div>
<li><div> Open a Something.j3md file in a text editor. You see that this .j3md file defines Material Parameters and Techniques.</div>
<ul>
<li><div> Material Parameters are the ones that you set in Materials, as shown in the examples above.</div>
</li>
@ -155,11 +168,20 @@ Check out the <a href="/com/jme3/gde/core/docs/jme3/build_from_sources.html">eng
</li>
</ul>
</li>
<li><div> Learn about GLSL (OpenGL Shading Language) to understand the .vert and .frag syntax, and write your own.</div>
<li><div> Learn about GLSL (OpenGL Shading Language) to understand the .vert and .frag syntax, then write your own.</div>
</li>
</ol>
</div>
<!-- EDIT5 SECTION "Creating a Custom Material Definition" [4411-5384] -->
<h2><a>Related Links</a></h2>
<div>
<ul>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">Developer specification of the jME3 material system (.j3md,.j3m)</a></div>
@ -368,7 +368,17 @@ Later, put the Geometry (not the Material!) in the appropriate render queue
<td>getAdditionalRenderState().setPolyOffset();</td><td>Enable polygon offset.</td><td>Use this when you have meshes that have triangles really close to each over (e.g. <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Coplanarity"><paramname="text"value="<html><u>Coplanar</u></html>"><paramname="textColor"value="blue"></object>), it will shift the depth values to prevent <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Z-fighting"><paramname="text"value="<html><u>Z-fighting</u></html>"><paramname="textColor"value="blue"></object>.</td>
</tr>
</table></div>
<!-- EDIT17 TABLE [14511-15277] --><div><span>
<!-- EDIT17 TABLE [14511-15277] -->
<p>
<strong>Related Links</strong>
</p>
<ul>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">Developer specification of the jME3 material system (.j3md,.j3m)</a></div>
You can split the screen and look into the 3D scene from different camera angles at the same time.
You can split the screen and look into the 3D scene from different camera angles at the same time. E.g. you can have two rootnodes with different scene graphs, and two viewPorts, each of which can only see its own subset of the scene with its own subset of port-processing filters, so you get two very different views of the scene.
</p>
<p>
@ -12,13 +12,13 @@ The packages used in this example are <code>com.jme3.renderer.Camera</code> and
</p>
</div>
<!-- EDIT1 SECTION "Multiple Camera Views" [1-418] -->
<!-- EDIT1 SECTION "Multiple Camera Views" [1-650] -->
<h2><a>How to resize and Position ViewPorts</a></h2>
<div>
<p>
The default viewPort is as big as the window. If you have several, the must be of different sizes, either overlapping or adjacent to one another. How do you tell jME which of the ViewPorts should appear where on the screen, and how big it should be?
The default viewPort is as big as the window. If you have several, they must be of different sizes, either overlapping or adjacent to one another. How do you tell jME which of the ViewPorts should appear where on the screen, and how big they should be?
</p>
<p>
@ -74,7 +74,7 @@ Example: Cam2's rectangle is int he bottom right: It extends from mid (x1=0
</p>
</div>
<!-- EDIT2 SECTION "How to resize and Position ViewPorts" [419-2059] -->
<!-- EDIT2 SECTION "How to resize and Position ViewPorts" [651-2294] -->
<h2><a>Four-Time Split Screen</a></h2>
<div>
@ -84,7 +84,7 @@ In this example, you create four views (2x2) with the same aspect ratio as the w
@ -10,17 +10,17 @@ This document introduces you to the SpiderMonkey networking <acronym title="Appl
<ul>
<li><div> The central server (one headless SimpleApplication) coordinates the game in the background.</div>
</li>
<li><div> Each player runs a game client (a standard SimpleApplications) and connects to the central server.</div>
<li><div> Each player runs a game client (a standard SimpleApplication) and connects to the central server.</div>
</li>
</ul>
<p>
Each Client keeps the the Server informed about its player's moves and actions. The Server centrally maintains the game state and broadcasts the state info back to all connected clients. This network synchronization allows all clients share the same game world. Each client then displays the game state to one player from this player's perspective.
Each Client keeps the Server informed about its player's moves and actions. The Server centrally maintains the game state and broadcasts the state info back to all connected clients. This network synchronization allows all clients to share the same game world. Each client then displays the game state to one player from this player's perspective.
You can register several types of listeners to be notified of changes.
@ -56,12 +56,12 @@ You can register several types of listeners to be notified of changes.
</ul>
</div>
<!-- EDIT2 SECTION "SpiderMonkey API Overview" [844-2388] -->
<!-- EDIT2 SECTION "SpiderMonkey API Overview" [842-2386] -->
<h2><a>Client and Server</a></h2>
<div>
</div>
<!-- EDIT4 SECTION "Client and Server" [2389-2419] -->
<!-- EDIT4 SECTION "Client and Server" [2387-2417] -->
<h3><a>Creating a Server</a></h3>
<div>
@ -96,7 +96,7 @@ When you run this app on a host, the server is ready to accept clients. Let'
</p>
</div>
<!-- EDIT5 SECTION "Creating a Server" [2420-3372] -->
<!-- EDIT5 SECTION "Creating a Server" [2418-3370] -->
<h3><a>Creating a Client</a></h3>
<div>
@ -135,7 +135,7 @@ When you run this client, it connects to the server.
</p>
</div>
<!-- EDIT6 SECTION "Creating a Client" [3373-4540] -->
<!-- EDIT6 SECTION "Creating a Client" [3371-4538] -->
<h3><a>Getting Info About a Client</a></h3>
<div>
@ -158,7 +158,7 @@ The server refers to a connected client as com.jme3.network.HostedConnection obj
<td>myServer.getConnection(0)</td><td>Server gets the first (0), second (1), etc, connected HostedConnection object (one client).</td>
</tr>
</table></div>
<!-- EDIT8 TABLE [4717-5096] -->
<!-- EDIT8 TABLE [4715-5094] -->
<p>
Your game can define its own game data based on whatever criteria you want, typically these include player ID and state. If the server needs to look up player/client-specific information, you can store this information directly on the HostedConnection object. The following examples read and write a custom Java object <code>MyState</code> in the HostedConnection object <code>conn</code>:
@ -175,14 +175,14 @@ Your game can define its own game data based on whatever criteria you want, typi
<td> MyState state = conn.getAttribute("MyState")</td><td> Server can read an attribute of the HostedConnection. </td>
</tr>
</table></div>
<!-- EDIT9 TABLE [5471-5700] -->
<!-- EDIT9 TABLE [5469-5698] -->
</div>
<!-- EDIT7 SECTION "Getting Info About a Client" [4541-5701] -->
<!-- EDIT7 SECTION "Getting Info About a Client" [4539-5699] -->
<h2><a>Messaging</a></h2>
<div>
</div>
<!-- EDIT10 SECTION "Messaging" [5702-5724] -->
<!-- EDIT10 SECTION "Messaging" [5700-5722] -->
<h3><a>Creating Message Types</a></h3>
<div>
@ -203,7 +203,7 @@ You must register each message type to the com.jme3.network.serializing.Serializ
The last two broadcasting methods use com.jme3.network.Filters to select a subset of recipients. If you know the exact list of recipients, always send the messages directly to them using the Filters; avoid floodig the network with unnessary broadcasts to all.
The last two broadcasting methods use com.jme3.network.Filters to select a subset of recipients. If you know the exact list of recipients, always send the messages directly to them using the Filters; avoid flooding the network with unnecessary broadcasts to all.
</p>
</div>
<!-- EDIT13 SECTION "Creating and Sending Messages" [8423-9509] -->
<!-- EDIT13 SECTION "Creating and Sending Messages" [8421-9510] -->
<h2><a>Identification and Rejection</a></h2>
<div>
@ -328,7 +328,7 @@ A server has a game version and game name property. Each client expects to commu
<td> myClient.getVersion() </td><td> Client queries the version of the server it is connected to. </td>
</tr>
</table></div>
<!-- EDIT15 TABLE [10101-10470] -->
<!-- EDIT15 TABLE [10102-10471] -->
<p>
<p><div>Typically, your networked game defines its own attributes (such as player ID) based on whatever criteria you want. If you want to look up player/client-specific information beyond the game version, you can set this information directly on the Client/HostedConnection object (see Getting Info About a Client).
@ -336,12 +336,12 @@ A server has a game version and game name property. Each client expects to commu
</p>
</div>
<!-- EDIT14 SECTION "Identification and Rejection" [9510-10798] -->
<!-- EDIT14 SECTION "Identification and Rejection" [9511-10799] -->
<h2><a>Closing Clients and Server Cleanly</a></h2>
<div>
</div>
<!-- EDIT16 SECTION "Closing Clients and Server Cleanly" [10799-10845] -->
<!-- EDIT16 SECTION "Closing Clients and Server Cleanly" [10800-10846] -->
<h3><a>Closing a Client</a></h3>
<div>
@ -357,7 +357,7 @@ You must override the client's destroy() method to close the connection cle
}</pre>
</div>
<!-- EDIT17 SECTION "Closing a Client" [10846-11121] -->
<!-- EDIT17 SECTION "Closing a Client" [10847-11122] -->
<h3><a>Closing a Server</a></h3>
<div>
@ -373,7 +373,7 @@ You must override the server's destroy() method to close the connection whe
}</pre>
</div>
<!-- EDIT18 SECTION "Closing a Server" [11122-11378] -->
<!-- EDIT18 SECTION "Closing a Server" [11123-11379] -->
<h3><a>Kicking a Client</a></h3>
<div>
@ -384,7 +384,7 @@ The server can kick a HostedConnection to make it disconnect. You should provide
<td> public void clientConnected(Client c){} </td><td> Implement here what happens as soon as this clients has fully connected to the server. </td>
<td> public void clientConnected(Client c){} </td><td> Implement here what happens as soon as this client has fully connected to the server. </td>
</tr>
<tr>
<td> public void clientDisconnected(Client c, DisconnectInfo info){} </td><td> Implement here what happens after the server kicks this client. For example, display the DisconnectInfo to the user. </td>
</tr>
</table></div>
<!-- EDIT22 TABLE [12124-12494] -->
<!-- EDIT22 TABLE [12125-12494] -->
<p>
First implement the ClientStateListener interface in the Client class. Then register it to myClient in MyGameClient's simeplInitApp() method:
First implement the ClientStateListener interface in the Client class. Then register it to myClient in MyGameClient's simpleInitApp() method:
In addition to the <code>nifty.addXml()</code> methods to attach many nifty <acronymtitle="Extensible Markup Language">XML</acronym> files, there exists a <code>nifty.registerScreenController()</code> method to explicitly attach more screen controllers.
</p>
<p>
The following code sample shows how you can explicitly attach several screen controllers before adding the <acronymtitle="Extensible Markup Language">XML</acronym> file to nifty, which would otherwise cause nifty to implicitly instantiate the screen controller class.
</p>
<pre>NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, viewPort);
<h1><a>Working Blender and OgreXML Versions</a></h1>
<div>
<p>
Here you can find working combinations of Blender and the OgreXML exporter, with any tips or bugs associated with each.
</p>
<div><table>
<tr>
<th> Blender Version </th><th> OgreXML Exporter Version </th><th> Notes </th>
</tr>
<tr>
<td> 2.6.2 </td><td><objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://code.google.com/p/blender2ogre/downloads/list"><paramname="text"value="<html><u>0.5.5</u></html>"><paramname="textColor"value="blue"></object></td><td> Root bone, no transforms on object, no envelopes </td>
</tr>
<tr>
<td> 2.6.1 </td><td> ? </td><td></td>
</tr>
<tr>
<td> 2.6.0 </td><td> ? </td><td></td>
</tr>
</table></div>
<!-- EDIT2 TABLE [173-391] -->
</div>
<!-- EDIT1 SECTION "Working Blender and OgreXML Versions" [1-392] -->
<h1><a>Tips</a></h1>
<div>
<p>
Tips for exporting animations through OgreXML correctly:
</p>
<ul>
<li><div> apply all transformations</div>
</li>
<li><div> armature should have 0,0,0 transformation (loc,rot,scale)</div>
</li>
<li><div> model object should have 0,0,0 transformation (loc,rot,scale)</div>
</li>
<li><div> root bone should have 0,0,0 transformation (loc,rot,scale)</div>
</li>
<li><div> no envelopes</div>
</li>
</ul>
<p>
Test Character - <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://dl.dropbox.com/u/26887202/123/jme_blender/characterOgre26.zip"><paramname="text"value="<html><u>http://dl.dropbox.com/u/26887202/123/jme_blender/characterOgre26.zip</u></html>"><paramname="textColor"value="blue"></object>
@ -196,7 +196,7 @@ All non-mesh CollisionShapes can be used for dynamic, kinematic, as well as stat
<strong>Limitations:</strong> 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. </td><td> Complex dynamic objects (like spiders) in Virtual Reality or scientific simulations. </td>
</tr>
<tr>
<td> HeightFieldCollisionShape </td><td> A mesh-accurate shape optimized for static terrains. This shape is much faster than other mesh-accurate shapes. <br/>
<td> HeightfieldCollisionShape </td><td> A mesh-accurate shape optimized for static terrains. This shape is much faster than other mesh-accurate shapes. <br/>
<strong>Limitations:</strong> Requires heightmap data. Collisions between two mesh-accurate shapes cannot be detected, only non-mesh shapes can collide with this shape.</td><td>Static terrains.</td>
The PhysicsSpace also manages global physics settings. Typically, you can leave the defaults, and you don't need to change the following settings:
<li><div> Specify global gravity. <pre>bulletAppState.getPhysicsSpace().setGravity(new Vector3f(0, -9.81f, 0));</pre>
</div>
</li>
<li><div> Specify the size of the physics space as two opposite corners (only applies to AXIS_SWEEP broadphase).<pre>bulletAppState.getPhysicsSpace().setWorldMax(new Vector3f(10000f, 10000f, 10000f));
The PhysicsSpace also manages global physics settings. Typically, you can leave the defaults, and you don't need to change the following settings, but it's good to know what they are for:
<td>setGravity(new Vector3f(0, -9.81f, 0));</td><td>Specifies the global gravity.</td>
</tr>
<tr>
<td>setAccuracy(1f/60f);</td><td>Specifies physics accuracy. The higher the accuracy, the slower the game. Increase value if objects are passing through one another, or bounce oddly.</td>
</tr>
<tr>
<td>setMaxSubSteps(4);</td><td>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.</td>
setWorldMin(new Vector3f(-10000f, -10000f, -10000f));</td><td>Specifies the size of the physics space as two opposite corners (only applies to AXIS_SWEEP broadphase).</td>
</tr>
<tr>
<td>setCcdMotionThreshold()</td><td>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.</td>
<td> setRestitution(0.0f) </td><td> Bounciness. By default objects are not bouncy (0.0f). For a bouncy rubber object set this > 0.0f. <br/>
Both the object and the surface must have non-zero restitution for bouncing to occur. <br/>
This setting has an impact on performance, so use it sparingly. </td><td> Brick: 0.0f <br/>
Rubber ball: 1.0f </td>
</tr>
</table></div>
<!-- EDIT17 TABLE [14586-16007] -->
<!-- EDIT18 TABLE [15320-16830] -->
<p>
On a RigidBodyControl, you can apply the following physical forces:
@ -451,17 +462,14 @@ On a RigidBodyControl, you can apply the following physical forces:
<tr>
<td> setPhysicsRotation()</td><td>Rotates the object. Do not use setLocalRotate() for physical objects.</td>
</tr>
<tr>
<td> setCcdMotionThreshold(0.1f) </td><td> The amount of motion in 1 physics tick to trigger the continuous motion detection. Rarely used, but necessary if you need to fiddle with details. </td>
</tr>
<tr>
<td> setKinematic(true) </td><td> 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. <br/>
<!-- EDIT19 SECTION "Kinematic vs Dynamic vs Static" [16870-19271] -->
<!-- EDIT20 SECTION "Kinematic vs Dynamic vs Static" [17513-19914] -->
<h2><a>Forces: Moving Dynamic Objects</a></h2>
<div>
@ -572,7 +580,7 @@ Use the following methods to move dynamic physical objects.
<td> clearForces()</td><td>Cancels out all forces (force, torque) etc and stops the motion.</td>
</tr>
</table></div>
<!-- EDIT22 TABLE [19377-20366] -->
<!-- EDIT23 TABLE [20020-21009] -->
<p>
<p><div>It is technically possible to position PhysicsControls using setLocalTranslation(), e.g. to place them in their start position in the scene. However you must be very careful not to cause an "impossible state" where one physical object overlaps with another! Within the game, you typically use the setters shown here exclusively.
@ -606,13 +614,13 @@ removeCollideWithGroup(COLLISION_GROUP_01)</td><td>Collision Groups are integer
<td> setSleepingThreshold(float,float)</td><td>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). (?) </td>
</tr>
<tr>
<td> setCcdMotionThreshold(0f) </td><td>Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection. This avoids the problem of fast objects moving through other objects. Set to zero to disable (default).</td>
<td> setCcdMotionThreshold(0f) </td><td>Sets the amount of motion that has to happen in one physics tick to trigger the continuous motion detection in movign obejcts that push one another. This avoids the problem of fast objects moving through other objects. Set to zero to disable (default).</td>
</tr>
<tr>
<td> setCcdSweptSphereRadius(.5f)</td><td>Bullet does not use the full collision shape for continuous collision detection, insteadit uses a "swept sphere" shape to approximate a motion. Only relevant for fast moving dynamic bodies. (?)</td>
<td> setCcdSweptSphereRadius(.5f)</td><td>Bullet does not use the full collision shape for continuous collision detection, insteadit uses a "swept sphere" shape to approximate a motion, which can be imprecise and cause strange behaviours such as objects passign through one another or getting stuck. Only relevant for fast moving dynamic bodies. </td>
</tr>
</table></div>
<!-- EDIT23 TABLE [20784-22589] -->
<!-- EDIT24 TABLE [21427-23383] -->
<p>
<p><div> You can <code>setApplyPhysicsLocal(true)</code> for an object to make it move relatively to its local physics space. You would do that if you need a physics space that moves with a node (e.g. a spaceship with artificial gravity surrounded by zero-g space). By default, it's set to false, and all movement is relative to the world.
@ -620,7 +628,7 @@ removeCollideWithGroup(COLLISION_GROUP_01)</td><td>Collision Groups are integer
@ -634,12 +642,17 @@ removeCollideWithGroup(COLLISION_GROUP_01)</td><td>Collision Groups are integer
</li>
</ul>
<ul>
<li><div><strong>Buggy?</strong> If you get weird behaviour, such as 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(). <br/>
<li><div><strong>Eject?</strong> 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(). <br/>
<strong>Solution:</strong> Use the debug mode to make CollisionShapes visible and verify that CollisionShapes do not overlap. <pre>bulletAppState.getPhysicsSpace().enableDebug(assetManager);</pre>
</div>
</li>
</ul>
<ul>
<li><div><strong>Buggy?</strong> If you get weird behaviour, such as physical nodes passing through one another, or getting stuck for no reason. <br/>
<strong>Solution:</strong> Look at the physics space accessors and change the acuracy and other parameters.</div>
</li>
</ul>
<ul>
<li><div><strong>Need more interactivity?</strong> You can actively <em>control</em> a physical game by triggering forces. You may also want to be able <em>respond</em> to collisions, e.g. by substracting health, awarding points, or by playing a sound. <br/>
<strong>Solution:</strong> To specify how the game responds to collisions, you use <ahref="/com/jme3/gde/core/docs/jme3/advanced/physics_listeners.html">Physics Listeners</a>.</div>
</li>
@ -651,7 +664,7 @@ removeCollideWithGroup(COLLISION_GROUP_01)</td><td>Collision Groups are integer
The awesome SeaMonkey water Filter is highly configurable. It can render any type of water and also simulates the underwater part of the effect, including "caustics". It is is based on <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://www.gamedev.net/page/reference/index.html/_//feature/fprogramming/rendering-water-as-a-post-process-effect-r2642"><paramname="text"value="<html><u>Wojciech Toman’s Rendering Water as a Post-process Effect</u></html>"><paramname="textColor"value="blue"></object> published on gamedev.net. Here's a video:
The awesome SeaMonkey WaterFilter is highly configurable. It can render any type of water and also simulates the underwater part of the effect, including light effects called caustics. The effect is based on <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://www.gamedev.net/page/reference/index.html/_//feature/fprogramming/rendering-water-as-a-post-process-effect-r2642"><paramname="text"value="<html><u>Wojciech Toman’s Rendering Water as a Post-process Effect</u></html>"><paramname="textColor"value="blue"></object> published on gamedev.net. Here's a video:
</p>
<p>
@ -12,11 +12,12 @@ The awesome SeaMonkey water Filter is highly configurable. It can render any typ
</p>
<p>
Need simpler <ahref="/com/jme3/gde/core/docs/jme3/advanced/water.html">water</a>?
<p><div>The SeaMonkey WaterFilter is ideal for oceans and lakes, and expecially for under-water scenes. If you only need a small simple water surface, such as a water trough or a shallow fountain, the <ahref="/com/jme3/gde/core/docs/jme3/advanced/water.html">SimpleWaterProcessor</a> may already be all you need.
</div></p>
</p>
</div>
<!-- EDIT1 SECTION "Rendering Water as Post-Process Effect" [1-590] -->
<!-- EDIT1 SECTION "Rendering Water as Post-Process Effect" [1-855] -->
<h2><a>The Theory</a></h2>
<div>
@ -34,7 +35,7 @@ The GameDev.net article describes how those effects are achieved, but the main i
</p>
</div>
<!-- EDIT2 SECTION "The Theory" [591-1706] -->
<!-- EDIT2 SECTION "The Theory" [856-1971] -->
<h2><a>How Did We Implement it in jME3?</a></h2>
<div>
@ -56,7 +57,7 @@ Now we have the rendered scene in a texture, and we can reconstruct the position
</p>
</div>
<!-- EDIT3 SECTION "How Did We Implement it in jME3?" [1707-2442] -->
<!-- EDIT3 SECTION "How Did We Implement it in jME3?" [1972-2707] -->
<h2><a>Sample Code</a></h2>
<div>
@ -68,20 +69,20 @@ There are two test cases in the jME3 repository:
<li><div><objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestPostWaterLake.java"><paramname="text"value="<html><u>jme3/src/test/jme3test/water/TestPostWaterLake.java</u></html>"><paramname="textColor"value="blue"></object> (calm and muddy water pond)</div>
</li>
<li><div><objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/water/TestMultiPostWater.java"><paramname="text"value="<html><u>jme3/src/test/jme3test/water/TestMultiPostWater.java</u></html>"><paramname="textColor"value="blue"></object> (several ponds of different sizes at different heights etc)</div>
</li>
</ul>
</div>
<!-- EDIT4 SECTION "Sample Code" [2443-2901] -->
<!-- EDIT4 SECTION "Sample Code" [2708-3399] -->
<h3><a>Using the Water Filter</a></h3>
<div>
<p>
In the <code>simpleInitApp()</code> method, you attach your scene to the rootNode, typically a terrain with a sky. Remember to add a directional light, since the water relies on the light direction vector. The WaterFilter constrcutor expects a node with the scene attached that should be reflected in the water, and vector information from the light source's direction.
In the <code>simpleInitApp()</code> method, you attach your scene to the rootNode, typically a terrain with a sky. Remember to add a directional light, since the water relies on the light direction vector. The WaterFilter constructor expects a node with the scene attached that should be reflected in the water, and vector information from the light source's direction.
</p>
<p>
@ -108,7 +109,7 @@ Usually you make the water reflect everything attached to the rootNode. But you
</p>
</div>
<!-- EDIT5 SECTION "Using the Water Filter" [2902-4206] -->
<!-- EDIT5 SECTION "Using the Water Filter" [3400-4704] -->
<h3><a>Optional: Waves</a></h3>
<div>
@ -128,7 +129,7 @@ public void simpleUpdate(float tpf) {
<h3><a>Optional: Water Wave and Color Effects</a></h3>
<div>
@ -175,7 +176,7 @@ manager.loadTexture("Textures/wavenormals.png") )</td><td>This normal
<td>water.setNormalScale(0.5f)</td><td>Sets the normal scaling factors to apply to the normal map. The higher the value, the more small ripples will be visible on the waves.</td><td>1.0f</td>
</tr>
</table></div>
<!-- EDIT8 TABLE [4898-6062] --><div><table>
<!-- EDIT8 TABLE [5396-6560] --><div><table>
<tr>
<th> Water method example</th><th> Effects: Color</th><th>Default</th>
<td>water.setColorExtinction(new Vector3f(10f,20f,30f));</td><td>Sets At what depth the refraction color extincts. The three values are RGB (red, green, blue) in this order. Play with these parameters to "muddy" the water.</td><td>Vector3f(5f,20f,30f)</td>
</tr>
</table></div>
<!-- EDIT9 TABLE [6064-7068] --><div><table>
<!-- EDIT9 TABLE [6562-7566] --><div><table>
<tr>
<th> Water method example</th><th> Effects: Shore</th><th>Default</th>
</tr>
<tr>
<td>water.setCenter(Vector3f.ZERO); <br/>
water.setRadius(260);</td><td>Limit the water filter to a semisphere with the given center and radius. Use this for lakes and smaller bodies of water. Skip this for oceans.</td><td>unused</td>
</tr>
<tr>
<td>water.setShoreHardness(1.0f);</td><td>Sets how soft the transition between shore and water should be. High values mean a harder transition between shore and water.</td><td>0.1f</td>
manager.loadTexture("Textures/foam.png") )</td><td>This foam texture will be used with WrapMode.Repeat</td><td>"Common/MatDefs/Water/Textures/foam.jpg"</td>
</tr>
</table></div>
<!-- EDIT11 TABLE [7361-8006] --><div><table>
<!-- EDIT11 TABLE [8068-8713] --><div><table>
<tr>
<th> Water method example</th><th> Effects: Light</th><th>Default</th>
</tr>
@ -255,9 +260,9 @@ manager.loadTexture("Textures/foam.png") )</td><td>This foam texture w
<td>water.setReflectionMapSize(256)</td><td>Sets the size of the reflection map. The higher, the better the quality, but the slower the effect.</td><td>512</td>
</tr>
</table></div>
<!-- EDIT12 TABLE [8008-8923] -->
<!-- EDIT12 TABLE [8715-9630] -->
</div>
<!-- EDIT7 SECTION "Optional: Water Wave and Color Effects" [4732-8925] -->
<!-- EDIT7 SECTION "Optional: Water Wave and Color Effects" [5230-9632] -->
<h3><a>Sound Effects</a></h3>
<div>
@ -268,6 +273,11 @@ You should also add audio nodes with water sounds to complete the effect.
<pre>AudioNode waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", false);
waves.setLooping(true);
audioRenderer.playSource(waves);</pre>
<p>
See also: <ahref="/com/jme3/gde/core/docs/jme3/advanced/audio.html">audio</a>.
Spatials can contain Nodes, Geometries, and user data (player score, health, inventory, etc). You can save and load individual Nodes or Geometries, as well as whole scenes using <code>com.jme3.export.binary.BinaryExporter</code> and <code>com.jme3.export.binary.BinaryImporter</code>. The jMonkeyEngine's serialization system is the<code>com.jme3.export.Savable</code> interface; the jMonkeyEngine's binary file format is called <code>.j3o</code>. You can open, view, and edit .j3o files in the jMonkeyEngine <ahref="/com/jme3/gde/core/docs/sdk.html">SDK</a>.
Spatials (that is Nodes and Geometries) can contain audio and light nodes, particle emitters, controls, and user data (player score, health, inventory, etc). For your game distribution, you must convert all original models to a faster binary format. You save individual Spatials as well as scenes using<code>com.jme3.export.binary.BinaryExporter</code>.
</p>
<p>
<p><div>JME's BinaryExporter/BinaryImporter can read and write standard Java objects, JME objects, and primitive data types that are included in a <ahref="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">spatial's user data</a>. See below how to make additional custom classes "Savable".
The jMonkeyEngine's binary file format is called <code>.j3o</code>. You can convert, view and edit .j3o files and their materials in the jMonkeyEngine <ahref="/com/jme3/gde/core/docs/sdk.html">SDK</a> and compose scenes (this does not include editing meshes). For the conversion, you can either use the BinaryExporters, or a context menu in the <acronymtitle="Software Development Kit">SDK</acronym>.
</p>
<p>
<p><div>The jMonkeyEngine's serialization system is the <code>com.jme3.export.Savable</code> interface. JME3's BinaryExporter can write standard Java objects, JME3 objects, and primitive data types that are included in a <ahref="/com/jme3/gde/core/docs/jme3/advanced/spatial.html">spatial's user data</a>. If you use custom game data classes, see below how to make them "Savable".
</div></p>
</p>
<p>
There is also a com.jme3.export.xml.XMLExporter and com.jme3.export.xml.XMLImporter that similarly converts jme3 spatials to an <acronymtitle="Extensible Markup Language">XML</acronym> format. But you wouldn't use that to load models at runtime (quite slow).
</p>
</div>
<!-- EDIT1 SECTION "Saving and Loading Games" [1-781] -->
<!-- EDIT1 SECTION "Saving and Loading Games (.j3o)" [1-1239] -->
<h2><a>Sample Code</a></h2>
<div>
<ul>
@ -22,70 +30,50 @@ Spatials can contain Nodes, Geometries, and user data (player score, health, inv
</ul>
</div>
<!-- EDIT2 SECTION "Sample Code" [782-939] -->
<!-- EDIT2 SECTION "Sample Code" [1240-1397] -->
<h2><a>Saving a Node</a></h2>
<div>
<p>
The following example overrides <code>destroy()</code> to save the rootNode to a file when the user quits the application. The saved rootNode is a normal .j3o binary file that you open in the <ahref="/com/jme3/gde/core/docs/sdk.html">SDK</a>.
The following example overrides <code>stop()</code>in SimpleApplication to save the rootNode to a file when the user quits the application. The saved rootNode is a normal .j3o binary file that you can open in the <ahref="/com/jme3/gde/core/docs/sdk.html">SDK</a>.
</p>
<p>
<p><div>Note that when you save a model that has textures the textures are references to those textures are stored as absolute paths, so when loading the j3o file they have to be accessible at the exact location (relative to the assetmanager root) they were loaded from. This is why the <acronymtitle="Software Development Kit">SDK</acronym> manages the conversion on the project level.
<p><div>Note that when you save a model that has textures, the references to those textures are stored as absolute paths, so when loading the j3o file again, the textures have to be accessible at the exact location (relative to the assetmanager root, by default the <code>assets</code> directory) they were loaded from. This is why the <acronymtitle="Software Development Kit">SDK</acronym> manages the conversion on the project level.
</div></p>
</p>
<pre> /* This is called when the user quits the app. */
File file = new File(userHome+"/MySuperGame/"+"/SavedGame-"+timestamp+".j3o");</pre>
<p>
</div></p>
</p>
</div>
<!-- EDIT3 SECTION "Saving a Node" [940-2256] -->
<!-- EDIT3 SECTION "Saving a Node" [1398-2548] -->
<h2><a>Loading a Node</a></h2>
<div>
<p>
The following example uses simpleInitApp() to load the last saved game when the game is initialized.
The following example overrides <code>simpleInitApp()</code> in SimpleApplication to load <code>Models/MyModel.j3o</code> when the game is initialized.
@ -94,13 +82,13 @@ The following example uses simpleInitApp() to load the last saved game when the
</p>
</div>
<!-- EDIT4 SECTION "Loading a Node" [2257-3344] -->
<!-- EDIT4 SECTION "Loading a Node" [2549-3302] -->
<h2><a>Custom Savable Class</a></h2>
<div>
<p>
JME's BinaryExporter/BinaryImporter can read and write standard Java objects (String, ArrayList, buffers, etc), JME objects (Savables, such as Material), and primitive data types (int, float, etc). If you are using any custom class together with a Spatial, then the custom class must implement the <code>com.jme3.export.Savable</code> interface. There are two common cases where this is relevant:
JME's BinaryExporter can write standard Java objects (String, ArrayList, buffers, etc), JME objects (Savables, such as Material), and primitive data types (int, float, etc). If you are using any custom class together with a Spatial, then the custom class must implement the <code>com.jme3.export.Savable</code> interface. There are two common cases where this is relevant:
</p>
<ul>
@ -182,7 +170,18 @@ To make a custom class savable:
<p><div>As with all serialization, remember that if you ever change data types in custom classes, the updated read() methods will no longer be able to read your old files.
The default screenshot key is KeyInput.KEY_SYSRQ, alos known as "System Request / Print Screen" key. On Mac <acronymtitle="Operating System">OS</acronym>, you can take screenshots using Command+Shift+3 (fullscreen) or Command+Shift+4, and then press space to select a window.
The default screenshot key is KeyInput.KEY_SYSRQ, alos known as "System Request / Print Screen" key. On Mac keyboards, this key does not exist, so on Mac <acronymtitle="Operating System">OS</acronym> you take screenshots using Command+Shift+3 (fullscreen) or Command+Shift+4 (windowed: press space to select a window and then click).
* <ahref="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a> – The GeometryBatchFactory class combines several of your shapes with the same texture into one mesh with one texture.
@ -22,7 +22,7 @@ If you think you need to understand the scene graph concept better, please read
<p>
In your Java code, a Spatial is either a <code>com.jme3.scene.Node</code> or a <code>com.jme3.scene.Geometry</code>. You use the two for different purposes:
In your Java code, a Spatial is either a <code>com.jme3.scene.Node</code> or a <code>com.jme3.scene.Geometry</code> instance. You use the two types of Spatials for different purposes:
</p>
<p>
@ -34,7 +34,7 @@ In your Java code, a Spatial is either a <code>com.jme3.scene.Node</code> or a <
<td></td><th>com.jme3.scene.Spatial </th>
</tr>
<tr>
<th> Purpose: </th><td> A Spatial is an abstract data structure that stores transformations (translation, rotation, scale) of elements of the 3D scene graph. Spatials can be saved and loaded using the <ahref="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a>. </td>
<th> Purpose: </th><td> A Spatial is an abstract data structure that stores transformations (= translation, rotation, scale) of elements of the 3D scene graph. Spatials can be saved and loaded using the <ahref="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a>. </td>
@ -44,27 +44,27 @@ In your Java code, a Spatial is either a <code>com.jme3.scene.Node</code> or a <
</tr>
<tr>
<th> Purpose: </th><td> Use Geometries to represent an object's <strong>looks</strong>: Every Geometry contains a polygon mesh and a material, specifying its shape, color, texture, and opacity/transparency. <br/>
You can attach a Geometry to a Node. </td><td> Use Nodes to <strong>structure and group</strong> Geometries and other Nodes. Every Node is attached to one parent node, and each node can have zero or more children attached to itself. <br/>
You attach Geometries to Nodes. </td><td> Use Nodes to <strong>structure and group</strong> Geometries and other Nodes. Every Node is attached to one parent node, and each node can have zero or more children (Nodes or Geometries) attached to itself. <br/>
<strong>When you transform (move, rotate, etc) a parent node, all its children are transformed (moved, rotated, etc).</strong></td>
</tr>
<tr>
<th> Content: </th><td> Transformations; custom user data; <br/>
mesh, material; </td><td> Transformations; custom user data; <br/>
mesh and material; </td><td> Transformations; custom user data; <br/>
no mesh, no material.</td>
</tr>
<tr>
<th> Examples: </th><td> Box, sphere, player, building, terrain, vehicle, missiles, NPCs, etc… </td><td> rootNode, guiNode, audioNode, a custom vehicleNode or shipNode with passengers attached, etc. </td>
<th> Examples: </th><td> Box, sphere, player, building, terrain, vehicle, missiles, NPCs, etc… </td><td> rootNode, guiNode, audioNode, a custom grouping node such as vehicleNode or shipNode with passengers attached, etc. </td>
</tr>
</table></div>
<!-- EDIT3 TABLE [1151-2451] -->
<!-- EDIT3 TABLE [1178-2522] -->
<p>
<p><div>You never create a Spatial with <code><del>Spatial s = new Spatial();</del></code>! A Spatial is an abstract concept, like a mammal (there is no actual creature called "mammal" walking around here). You either create a Node or a Geometry object. Some methods however require a Spatial argument: This is because they are able to accept both Nodes and Geometries as arguments. In this case, you must<em>cast</em> a Node or Geometry to Spatial.
<p><div>You never create a Spatial with <code><del>Spatial s = new Spatial();</del></code>! A Spatial is an abstract concept, like a mammal (there is no actual creature called "mammal" walking around here). You create either a com.jme3.scene.Node, or a com.jme3.scene.Geometry object. Some methods, however, require a spatial as argument: This is because they are able to accept both Nodes and Geometries as arguments. In this case, you simply<em>cast</em> a Node or Geometry to Spatial.
</div></p>
</p>
</div>
<!-- EDIT2 SECTION "Node versus Geometry" [935-2905] -->
<!-- EDIT2 SECTION "Node versus Geometry" [935-3014] -->
<h3><a>Mesh</a></h3>
<div>
@ -83,7 +83,36 @@ The polygon <a href="/com/jme3/gde/core/docs/jme3/advanced/mesh.html">Mesh</a> i
</ul>
</div>
<!-- EDIT4 SECTION "Mesh" [2906-3585] -->
<!-- EDIT4 SECTION "Mesh" [3015-3694] -->
<h2><a>What is a Clone?</a></h2>
<div>
<p>
Cloned spatials share the same mesh, while each cloned spatial can have its own local transformation (translation, rotation, and scale) in the scene. This means you only use <code>clone()</code> on spatials whose meshes never change. The most common use case for cloning is when you use several Spatials that are based on the same <ahref="/com/jme3/gde/core/docs/jme3/advanced/shape.html">Shape</a>s.
</p>
<p>
The second use case is: When you load a model using <code>loadModel()</code> from the AssetManager, you may get a <code>clone()</code>ed object. In particular:
</p>
<ul>
<li><div> If the model is not animated (it has no <code><ahref="/com/jme3/gde/core/docs/jme3/advanced/animation.html">AnimControl</a></code>), you get a clone. All clones share one mesh object. (Uses less memory)</div>
</li>
<li><div> If the model is animated (it has a <code><ahref="/com/jme3/gde/core/docs/jme3/advanced/animation.html">AnimControl</a></code>), then <code>loadModel()</code> duplicates the mesh for each loaded instance. (Uses more memory)</div>
</li>
</ul>
<p>
Usually there is no need to manually use any of the <code>clone()</code> methods on models. Using the <ahref="/com/jme3/gde/core/docs/jme3/advanced/asset_manager.html">Asset Manager</a>'s <code>loadModel()</code> method will automatically do the right thing for your models.
</p>
<p>
<p><div>"Box worlds" are not made up of statically cloned <code>Box()</code> shapes, this would still be too slow for large worlds. To learn how to make real fast box worlds, search the web for <em>voxelization</em> techniques.
</div></p>
</p>
</div>
<!-- EDIT5 SECTION "What is a Clone?" [3695-4950] -->
<h2><a>How to Add Fields and Methods to a Spatial</a></h2>
<div>
@ -93,24 +122,23 @@ You can include custom user data –that is, custom Java objects and methods–
</p>
<p>
<p><div>Neither do you need to ever extend Node to be able to add custom accessor methods to a spatial – use <ahref="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead. There is no need to create a custom class that extends Node or Geometry to be able to add custom fields – use the provided<code>setUserData()</code> method instead. Where ever the Spatial is accessible, you can easily access the object's game data and accessors this way.
<p><div>You want to add custom accessor methods to a spatial? Do not extend <code>Node</code> or <code>Geometry</code>, use <ahref="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead. You want to add custom fields to a spatial? Do not extend <code>Node</code> or <code>Geometry</code>, use the built-in<code>setUserData()</code> method instead. Where ever the Spatial is accessible, you can easily access the object's class fields (user data) and accessors (control methods) this way.
</div></p>
</p>
<p>
The following example adds an integer field named <code>health</code> to the Spatil <code>player_node</code>, and initializes it to 100.
This first example adds an integer field named <code>health</code> to the Spatial <code>player_node</code>, and initializes it to 100.
To be able to add accessors to the player, you create a <ahref="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">custom PlayerControl</a> class and add it to the Spatial.
The second example adds a set of custom accessor methods to the player object. You create a <ahref="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">custom PlayerControl() class</a> and you add this control to the Spatial:
In PlayerControl you define methods that set and get your users data in the <code>spatial</code> object.
In your PlayerControl() class, you define custom methods that set and get your user data in the <code>spatial</code> object. Forexample, the control could add accessors that set and get the player's health:
<li><div> You can add as many data objects (including Strings, Integers, Floats, Arrays,) to a Spatial as you want. Just make sure to label them with unique Strings (<code>health</code>, <code>inventory</code>, <code>equipment</code>, etc). </div>
<li><div> You can add as many data objects (of String, Boolean, Integer, Float, Array types) to a Spatial as you want. Just make sure to label them with unique case-sensitive strings (<code>health</code>, <code>Inventory</code>, <code>equipment</code>, etc). </div>
</li>
<li><div> The saved data can be custom Java objects if you make the custom Java class <ahref="/com/jme3/gde/core/docs/jme3/advanced/save_and_load#custom_savable_class.html">implement the Savable interface</a>.</div>
<li><div> The saved data can even be a custom Java object if you make the custom Java class <ahref="/com/jme3/gde/core/docs/jme3/advanced/save_and_load#custom_savable_class.html">implement the Savable interface</a>!</div>
</li>
<li><div> When you save a Spatial as a .j3o file, the custom data is saved, too, and it will be restored the next time you load the .j3o!</div>
<li><div> When you save a Spatial as a .j3o file, the custom data is saved, too, and all Savables are restored the next time you load the .j3o! </div>
</li>
</ul>
@ -143,7 +171,7 @@ This is how you list all data keys that are already defined for one Spatial:
}</pre>
</div>
<!-- EDIT5 SECTION "How to Add Fields and Methods to a Spatial" [3586-5973] -->
<!-- EDIT6 SECTION "How to Add Fields and Methods to a Spatial" [4951-7527] -->
<h2><a>How to Access a Named Sub-Mesh</a></h2>
<div>
@ -168,5 +196,15 @@ In the following example, the Node <code>house</code> is the loaded model. The s
<!-- EDIT6 SECTION "How to Access a Named Sub-Mesh" [5974-] -->
<!-- EDIT7 SECTION "How to Access a Named Sub-Mesh" [7528-8331] -->
<h2><a>See also</a></h2>
<div>
<p>
* <ahref="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a> – The GeometryBatchFactory class batches several Geometries into meshes with each their own texture.
jMonkeyEngine offers a SimpleWaterProcessor that turns any quad (flat rectangle) into a reflective water surface with waves. You can use this quad for simple limited water surfaces such as water troughs, shallow fountains, puddles, shallow water in channels. The SimpleWaterProcessor has less performance impact on your game than the full featured <ahref="/com/jme3/gde/core/docs/jme3/advanced/post-processor_water.html">SeaMonkey WaterFilter</a>; the main difference is that the SimpleWaterProcessor does not include under-water effects.
</p>
<p>
Here is some background info for JME3's basic water implementation:
</p>
<ul>
@ -21,7 +25,7 @@ Here is some background info for JME3's basic water implementation:
</p>
</div>
<!-- EDIT1 SECTION "Simple Water" [1-362] -->
<!-- EDIT1 SECTION "Simple Water" [1-865] -->
<h2><a>SimpleWaterProcessor</a></h2>
<div>
@ -60,7 +64,7 @@ To achieve a water effect, JME3 uses shaders and a special material, <code>Commo
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
@ -93,7 +99,7 @@ public class HelloAnimation extends SimpleApplication
}</pre>
</div>
<!-- EDIT2 SECTION "Sample Code" [312-2738] -->
<!-- EDIT2 SECTION "Sample Code" [515-2941] -->
<h2><a>Creating and Loading Animated Models</a></h2>
<div>
@ -122,7 +128,7 @@ Don't forget to add a light source to make the material visible.
</p>
</div>
<!-- EDIT3 SECTION "Creating and Loading Animated Models" [2739-4159] -->
<!-- EDIT3 SECTION "Creating and Loading Animated Models" [2942-4362] -->
<h2><a>Animation Controler and Channel</a></h2>
<div>
@ -151,8 +157,27 @@ After you load the animated model, you register it to the Animation Controller.
channel.setAnim("stand");
...</pre>
<p>
<p><div>In response to a question about animations on different channels interefering with each other, <strong>Nehon on the jME forum <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://jmonkeyengine.org/groups/general-2/forum/topic/helloanimation-animations-seem-to-be-clashing/#post-180994"><paramname="text"value="<html><u>wrote</u></html>"><paramname="textColor"value="blue"></object>,</strong>
</p>
<p>
"You have to consider channels as part of the skeleton that are animated. The default behavior is to use the whole skeleton for a channel.
In your example the first channel plays the walk anim, then the second channel plays the dodge animation.
Arms and feet are probably not affected by the doge animation so you can see the walk anim for them, but the rest of the body plays the dodge animation.
</p>
<p>
Usually multiple channels are used to animate different part of the body. For example you create one channel for the lower part of the body and one for the upper part. This allow you to play a walk animation with the lower part and for example a shoot animation with the upper part. This way your character can walk while shooting.
</p>
<p>
In your case, where you want animations to chain for the whole skeleton, you just have to use one channel."
</div></p>
</p>
</div>
<!-- EDIT4 SECTION "Animation Controler and Channel" [4160-4997] -->
<!-- EDIT4 SECTION "Animation Controler and Channel" [4363-6301] -->
<h2><a>Responding to Animation Events</a></h2>
<div>
@ -177,7 +202,7 @@ Add <code>implements AnimEventListener</code> to the class declaration. This int
}</pre>
</div>
<!-- EDIT5 SECTION "Responding to Animation Events" [4998-5885] -->
<!-- EDIT5 SECTION "Responding to Animation Events" [6302-7189] -->
<h2><a>Trigger Animations After User Input</a></h2>
<div>
@ -233,7 +258,7 @@ Test for each action by name, and set the channel to the corresponding animation
};</pre>
</div>
<!-- EDIT6 SECTION "Trigger Animations After User Input" [5886-7774] -->
<!-- EDIT6 SECTION "Trigger Animations After User Input" [7190-9078] -->
<h2><a>Exercises</a></h2>
<div>
@ -302,7 +327,7 @@ Can you identify individual bones in the skeleton?
</p>
</div>
<!-- EDIT7 SECTION "Exercises" [7775-9642] -->
<!-- EDIT7 SECTION "Exercises" [9079-10946] -->
<h2><a>Conclusion</a></h2>
<div>
@ -332,5 +357,5 @@ See also: <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer">
This tutorial explains how to add 3D sound to a game, and how make sounds play together with events, such as clicking. You learn how to use an Audio Listener and Audio Nodes. You also make use of an Action Listener and a MouseButtonTrigger from the previous <ahref="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system.html">Hello Input</a> tutorial to make a mouse click trigger a gun shot sound.
</p>
<p>
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
@ -239,7 +245,7 @@ Now every sound knows whether it should loop or not.
</p>
<p>
Apart from the looping boolean, another difference is where <code>play()</code> (<code>playInstace()</code>) is called on those nodes:
Apart from the looping boolean, another difference is where <code>play().playInstance()</code> is called on those nodes:
</p>
<ul>
<li><div> You start playing the background nature sound right after you have created it, in the initAudio() method.<pre> audio_nature.play(); // play continuously!</pre>
@ -259,7 +265,7 @@ Apart from the looping boolean, another difference is where <code>play()</code>
</ul>
</div>
<!-- EDIT6 SECTION "Ambient or Situational?" [8051-9286] -->
<!-- EDIT6 SECTION "Ambient or Situational?" [8254-9484] -->
<h2><a>Buffered or Streaming?</a></h2>
<div>
@ -282,7 +288,7 @@ Note that streamed sounds can not loop (i.e. setLooping will not work as you exp
</p>
</div>
<!-- EDIT7 SECTION "Buffered or Streaming?" [9287-9868] -->
<!-- EDIT7 SECTION "Buffered or Streaming?" [9485-10066] -->
<h2><a>Play() or PlayInstance()?</a></h2>
<div>
<div><table>
@ -299,9 +305,9 @@ Note that streamed sounds can not loop (i.e. setLooping will not work as you exp
<td>The same sound cannot play twice at the same time.</td><td>The same sounds can play multiple times and overlap.</td>
</tr>
</table></div>
<!-- EDIT9 TABLE [9908-10152] -->
<!-- EDIT9 TABLE [10106-10350] -->
</div>
<!-- EDIT8 SECTION "Play() or PlayInstance()?" [9869-10153] -->
<!-- EDIT8 SECTION "Play() or PlayInstance()?" [10067-10351] -->
<h2><a>Your Ear in the Scene</a></h2>
<div>
@ -323,7 +329,7 @@ If you don't do that, the results of 3D audio will be quite random.
</p>
</div>
<!-- EDIT10 SECTION "Your Ear in the Scene" [10154-10856] -->
<!-- EDIT10 SECTION "Your Ear in the Scene" [10352-11054] -->
<h2><a>Global, Directional, Positional?</a></h2>
<div>
@ -350,7 +356,7 @@ In short, you must choose in every situation whether it makes sense for a sound
@ -46,8 +46,13 @@ These scene elements cannot be modeled by meshes. In very simple terms:
Particle effects can be animated (e.g. sparks, drops) and static (strands of grass, hair). Non-particle effects include bloom/glow, and motion blur/afterimage. In this tutorial you learn how to make animated particles (com.jme3.effect).
</p>
<p>
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
<td> gravity </td><td><code>setGravity()</code></td><td> 0,1,0 </td><td> Whether particles fall down (positive) or fly up (negative). Set to 0f for a zero-g effect where particles keep flying. </td>
</tr>
</table></div>
<!-- EDIT8 TABLE [8160-9632] -->
<!-- EDIT8 TABLE [8364-9836] -->
<p>
You can find details about <ahref="/com/jme3/gde/core/docs/jme3/advanced/particle_emitters#configure_parameters.html">effect parameters</a> here.
@ -331,7 +336,7 @@ Add and modify one parameter at a time, and try different values until you get t
@ -284,16 +284,22 @@ Mappings registered to the <strong>AnalogListener</strong> are triggered repeate
<ol>
<li><div> JME gives you access to the name of the triggered action.</div>
</li>
<li><div> JME gives you access to a gradual value how long the key has been pressed.</div>
<li><div> 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 <ahref="/com/jme3/gde/core/docs/jme3/beginner/hello_input_system/timekeypressed.html">jMonkeyEngine 3 Tutorial (5) - Hello Input System - Variation over time key is pressed</a></div>
</li>
</ol>
</li>
</ul>
<p>
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 they key is released.
</p>
<ul>
<li><div> Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously. </div>
</li>
</ul>
<p>
Mappings registered to the <strong>ActionListener</strong> are digital either-or actions – "Pressed or released? On or off?"
</p>
<ul>
@ -318,7 +324,7 @@ Mappings registered to the <strong>ActionListener</strong> are digital either-or
}</pre>
</div>
<!-- EDIT5 SECTION "Analog, Pressed, or Released?" [9012-10381] -->
<!-- EDIT5 SECTION "Analog, Pressed, or Released?" [9012-11037] -->
<h2><a>Table of Triggers</a></h2>
<div>
@ -354,14 +360,14 @@ You can find the list of input constants in the files <code>src/core/com/jme3/in
<strong>Tip:</strong> If you don't recall an input constant during development, you benefit from an IDE's code completion functionality: Place the caret after e.g. <code>KeyInput.|</code> and trigger code completion to select possible input identifiers.
</p>
</div>
<!-- EDIT6 SECTION "Table of Triggers" [10382-11444] -->
<!-- EDIT6 SECTION "Table of Triggers" [11038-12100] -->
<h2><a>Exercises</a></h2>
<div>
<ol>
@ -380,8 +386,16 @@ inputManager.addMapping("Pause", new KeyTrigger(usersPauseKey
</li>
</ol>
<p>
<p><div>Link to user-proposed solutions: <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://jmonkeyengine.org/wiki/doku.php/jm3:solutions"><paramname="text"value="<html><u>http://jmonkeyengine.org/wiki/doku.php/jm3:solutions</u></html>"><paramname="textColor"value="blue"></object>
<em>Be sure to try to solve them for yourself first!</em>
</div></p>
</p>
</div>
<!-- EDIT8 SECTION "Exercises" [11445-11967] -->
<!-- EDIT8 SECTION "Exercises" [12101-12785] -->
<h2><a>Conclusion</a></h2>
<div>
@ -403,5 +417,5 @@ Now you can already write a little interactive game! But wouldn't it be coo
@ -181,8 +181,15 @@ Here are some fun things to try:
Look back at the <ahref="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> tutorial if you do not remember the transformation methods for scaling, translating, and rotating.
</p>
<p>
<p><div>Link to user-proposed solutions: <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://jmonkeyengine.org/wiki/doku.php/jm3:solutions"><paramname="text"value="<html><u>http://jmonkeyengine.org/wiki/doku.php/jm3:solutions</u></html>"><paramname="textColor"value="blue"></object>
<em>Be sure to try to solve them for yourself first!</em>
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
For a game, you create custom Materials based on these existing MaterialDefintions – as you have just seen in the example with the shiny rock's material.
</p>
</div>
<!-- EDIT6 SECTION "Default Material Definitions" [11058-11824] -->
<!-- EDIT6 SECTION "Default Material Definitions" [11261-12027] -->
<h2><a>Exercises</a></h2>
<div>
</div>
<!-- EDIT8 SECTION "Exercises" [11825-11847] -->
<!-- EDIT8 SECTION "Exercises" [12028-12050] -->
<h3><a>Exercise 1: Custom .j3m Material</a></h3>
<div>
@ -364,7 +370,7 @@ Using this new custom material <code>LeakThrough.j3m</code> only takes one line.
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
@ -459,10 +443,12 @@ Shooting boxes isn't very exciting – can you add code that loads and posi
<ul>
<li><div> Tip: You can use <code>Spatial golem = assetManager.loadModel("Models/Oto/Oto.mesh.xml");</code> from the engine's jme3-test-data.jar.</div>
</li>
<li><div> Tip: Models are shaded! You need some light!</div>
</li>
</ul>
</div>
<!-- EDIT12 SECTION "Exercise 2: Shoot a Character" [15537-15827] -->
<!-- EDIT12 SECTION "Exercise 2: Shoot a Character" [14991-15329] -->
<h3><a>Exercise 3: Pick up into Inventory</a></h3>
<div>
@ -487,8 +473,16 @@ Change the code as follows to simulate the player picking up objects into the in
</li>
</ol>
<p>
<p><div>Link to user-proposed solutions: <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://jmonkeyengine.org/wiki/doku.php/jm3:solutions"><paramname="text"value="<html><u>http://jmonkeyengine.org/wiki/doku.php/jm3:solutions</u></html>"><paramname="textColor"value="blue"></object>
<em>Be sure to try to solve them for yourself first!</em>
</div></p>
</p>
</div>
<!-- EDIT13 SECTION "Exercise 3: Pick up into Inventory" [15828-16799] -->
<!-- EDIT13 SECTION "Exercise 3: Pick up into Inventory" [15330-16463] -->
@ -19,8 +19,13 @@ One way to create a 3D landscape is to sculpt a huge terrain model. This gives y
Note: If you get an error when trying to create your ImageBasedHeightMap object, you may need to update the <acronymtitle="Software Development Kit">SDK</acronym>, click on "Help" / "Check for updates"
</p>
<p>
<p><div>To use the example assets in a new jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> project, right-click your project, select "Properties", go to "Libraries", press "Add Library" and add the "jme3-test-data" library.
@ -480,14 +487,15 @@ Instead, you can also let JME3 generate a random landscape for you:
</p>
<ol>
<li><div> What result do you get when you replace the above two heightmap lines by the following lines and run the sample?<pre>HillHeightMap heightmap = null;
HillHeightMap.NORMALIZE_RANGE = 100; // optional
try {
heightmap = new HillHeightMap(513, 1000, 50, 100, (byte) 3);
heightmap = new HillHeightMap(513, 1000, 50, 100, (byte) 3); // byte 3 is a random seed
} catch (Exception ex){
ex.printStackTrace();
}</pre>
</div>
</li>
<li><div> Change one parameter at a time, and the run the sample again. Note the differences. Can you find out which of the values has which effect on the generated terrain?</div>
<li><div> Change one parameter at a time, and the run the sample again. Note the differences. Can you find out which of the values has which effect on the generated terrain (look at the javadoc also)?</div>
<ul>
<li><div> Which value controls the size?</div>
<ul>
@ -497,15 +505,15 @@ try {
</li>
<li><div> Which value controls the number of hills generated?</div>
</li>
<li><div> Which values control the minimum and maximum radius of the hills?</div>
<li><div> Which values control the size and steepness of the hills?</div>
<ul>
<li><div> What happens if the minimum is bigger than the maximum?</div>
<li><div> What happens if the min is bigger than or equal to max? </div>
</li>
</ul>
<li><div> What happens if both min and max are small values (e.g. 10/20)?</div>
</li>
<li><div> Which value controls the flattening of the hills?</div>
<ul>
<li><div> What happens if this value is 1 ?</div>
<li><div> What happens if both min and max are large values (e.g. 1000/1500)?</div>
</li>
<li><div> What happens if min and max are very close(e.g. 1000/1001, 20/21)? Very far apart (e.g. 10/1000)?</div>
</li>
</ul>
</li>
@ -514,12 +522,16 @@ try {
</ol>
<p>
You see the variety of hilly landscapes that can be generated using this method.
</p>
<strong>Tip:</strong> For this exercise, you can keep using the splat Material from the sample code above. Just don't be surprised that the Material does not match the shape of the newly randomized landscape. If you want to generate real matching splat textures for randomized heightmaps, you need to write a custom method that, for example, creates an alphamap from the heightmap by replacing certain grayscales with certain RGB values.
<p>
<p><div>For this exercise, you can keep using the splat Material from the sample code above. Just don't be surprised that the Material does not match the shape of the newly randomized landscape. If you want to generate real matching splat textures for randomized heightmaps, you need to write a custom method that, for example, creates an alphamap from the heightmap by replacing certain grayscales with certain RGB values.
You have learned how to create terrains that are more efficient as loading one giant model. You know how to create generate random or handmade heightmaps. You can add a LOD control to render large terrains faster. You are aware that you can combine what you learned about collison detection to make the terrain solid to a physical player. You are also able to texture a terrain "like a boss" using layered Materials and texture splatting. You are aware that the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> provides a TerrainEditor that helps with most of these manual tasks.
You have learned how to create terrains that are more efficient than loading one giant model. You know how to create generate random or handmade heightmaps. You can add a LOD control to render large terrains faster. You are aware that you can combine what you learned about collison detection to make the terrain solid to a physical player. You are also able to texture a terrain "like a boss" using layered Materials and texture splatting. You are aware that the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> provides a TerrainEditor that helps with most of these manual tasks.
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.
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.
</p>
</div>
<!-- EDIT1 SECTION "Creating jME3 models in Blender3D" [1-184] -->
<!-- EDIT1 SECTION "Creating assets in Blender3D" [1-320] -->
<h2><a>Asset Management</a></h2>
<div>
@ -16,8 +16,42 @@ For the managing of assets in general, be sure to read the <a href="/com/jme3/gd
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.
</p>
<p>
Note that BMeshes are not yet supported by the importers and exporters so please use the "legacy mesh format" for now in blender 2.63+
To successfully import a texture, the texture <strong>has to</strong> be UV-mapped to the model. Heres how to assign diffuse, normal and specular maps:
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.
@ -25,25 +59,37 @@ To export an animated model in Blender make sure the following conditions are me
</p>
<ol>
<li><div> The animation bas to be a <strong>bone animation</strong></div>
</li>
<li><div> Apply Location, Rotation and Scate to the mesh on Blender: On 3D View editor on Blender, select the mesh in Object Mode and go to the 3D View Editor’s header → Object Menu → Apply → Location / Rotation / Scale.</div>
</li>
<li><div> Apply Location, Rotation and Scate to the armature on Blender: On 3D View editor on Blender, select the armature in Object Mode and go to the 3D View Editor’s header → Object Menu → Apply → Location / Rotation / Scale.</div>
</li>
<li><div> Set the mesh’s origin point in the bottom of the mesh (see the images bellow).</div>
</li>
<li><div> Set the armature’s origin point in the bottom of the armature (see the images bellow).</div>
<li><div> Set the mesh’s origin point in the bottom of the mesh (see the images below).</div>
</li>
<li><div>Armature’s origin point and mesh’s origin point must be in the same location(see the images bellow).</div>
<li><div> Set the armature’s origin point in the bottom of the armature (see the images below).</div>
</li>
<li><div>Use a root bone located in the armature’s origin. This root bone must be in vertical position (see the images bellow) 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)).</div>
<li><div>Armature’s origin point and mesh’s origin point must be in the same location(see the images below).</div>
</li>
<li><div> Uncheck “Bone Envelopes” checkbox on the Armature modifier for the mesh (see the images bellow).</div>
<li><div> Use a root bone located in the armature’s origin. This root bone must be in vertical position (see the images 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)).</div>
</li>
<li><div> Uncheck “Envelopes” checkbox on the armature (see the images bellow).</div>
<li><div> Uncheck “Bone Envelopes” checkbox on the Armature modifier for the mesh (see the images below).</div>
</li>
<li><div> Use SkeletonDebugger to show the skeleton on your game in order to check if the mesh and the skeleton are loaded correctly:</div>
<li><div> Uncheck “Envelopes” checkbox on the armature (see the images below).</div>
@ -95,5 +130,343 @@ Also check out these videos and resources:
</ul>
</div>
<!-- EDIT3 SECTION "Creation Process" [418-] -->
<!-- EDIT5 SECTION "Animations" [1723-5066] -->
<h1><a>NormalMap baking</a></h1>
<div>
<p>
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.
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.
</p>
<p>
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.
</p>
<p>
Here is an example of Prewiew 1, it's more smooth than the original mesh:
<!-- EDIT8 SECTION "Fixing the normal colors in Blender" [6469-7262] -->
<h1><a>LightMap baking</a></h1>
<div>
<p>
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.
<h2><a>Importing the model in the SDK and creating the appropriate material</a></h2>
<div>
<p>
Once this is done, export your model with the ogre exporter, and turn it into J3o with the <acronymtitle="Software Development Kit">SDK</acronym>. <br/>
Create material for it using the lighting definition.<br/>
Add the colorMap in the diffuse map slot and the lightMap in the light map slot.<br/>
Make sure you check "SeparateTexCoords"<br/>
<!-- EDIT11 SECTION "Importing the model in the SDK and creating the appropriate material" [8579-9263] -->
<h1><a>SkyBox baking</a></h1>
<div>
<p>
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 <imgsrc="/wiki/lib/images/smileys/icon_smile.gif"class="middle"alt=":-)"/> Check the links below for other ways and prettier skies.
</p>
<p>
A sky box is a texture mapped cube, it can also, loosely, be called en EnvMap or a CubeMap. The camera is inside the cube and the clever thing that jME does is to draw the sky so it is always behind whatever else is in your scene. Imagine the monkey is the camera in the picture.
But a real sky is not a box around our heads, it is more like a sphere. So if we put any old image in the sky it will look strange and might even look like a box. This is not what we want. The trick is to distort the image so that it will <em>look</em> like a sphere even if it in fact is a picture pasted on a box. Luckily blender can do that tricky distortion for us.
</p>
<p>
The screenshots are from Blender 2.63 but the equivalent operations have been in blender for years so with minor tweaks should work for almost any version.
</p>
<p>
So let's get started, fire up blender and you'll see something like this.
The cube in the start scene is perfect for us. What we'll do is have Blender render the scene onto that cube. The resulting image is what we'll use for our sky box. So our jME sky will look like we stood inside the blender box and looked out on the scene in blender.
</p>
<p>
Start by selecting the box and set its material to shadeless.
Now we will create a texture for the box. Make sure the texture is an <code>Environment Map</code>, that the <code>Viewpoint Object</code> is set to the cube. The resolution is how large the resulting image will be. More pixels makes the sky look better but comes at the cost of texture memory. You'll have to trim the resolution to what works in your application.
Next up is the fun part, create the sky scene in blender. You can do whatever fits your application, include models for a city landscape, set up a texture mapped sphere in blender with a nice photographed sky, whatever you can think will make a good sky.
That is it for Blender. Open the saved image in some image editor (I use the Gimp from <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://www.gimp.org"><paramname="text"value="<html><u>http://www.gimp.org</u></html>"><paramname="textColor"value="blue"></object> here).
<p><div>The <acronymtitle="Software Development Kit">SDK</acronym> also contains an image editor, right-click the image and select "edit image" to open it.
</div></p>
You will notice that Blender has taken the 6 sides of the cube and pasted together into one image (3x2). So now we need to cut it up again into 6 separate images. In gimp I usually set the guides to where I want to cut and then go into Filters→Web→Slice and let gimp cut it up for me.
Next up is to move the image files into your assets directory and create the sky in jME. You can do that in the Scene Composer by right clicking the scene node, select <code>Add Spatial</code> and then select <code>Skybox</code>.
If you want to do it from code, here is an example:
final Vector3f normalScale = new Vector3f(-1, 1, 1);
Spatial skySpatial = SkyFactory.createSky(
assetManager,
westTex,
eastTex,
northTex,
southTex,
upTex,
downTex,
normalScale);
rootNode.attachChild(skySpatial);
}</pre>
<p>
<p><div>This example uses a strange normalScale, this is to flip the image on the X-axis and might not be needed in your case. Hint: the texture is applied on the outside of the cube but we are inside so what do we see?
Follow our best practices for the <ahref="/com/jme3/gde/core/docs/jme3/intermediate/multi-media_asset_pipeline.html">multi-media asset pipeline</a>. <br/>
You create 3-D models in a 3-D mesh editor, for example Blender, and export it in Ogre Mesh <acronymtitle="Extensible Markup Language">XML</acronym> or Wavefront OBJ format.
You create 3-D models in a 3-D mesh editor, for example Blender, and export it in Ogre Mesh <acronymtitle="Extensible Markup Language">XML</acronym>(animated objects, scenes) or Wavefront OBJ format (static objects, scenes).
You create textures in a graphic editor, for exmaple Gimp, and export them as <acronymtitle="Portable Network Graphics">PNG</acronym> or <acronymtitle="Joint Photographics Experts Group">JPG</acronym>.
You create sounds in an audio editor, for example, Audacity, and export them as WAVE or OGG.
<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://blender.org"><paramname="text"value="<html><u>Download Blender</u></html>"><paramname="textColor"value="blue"></object>, <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro"><paramname="text"value="<html><u>Blender intro tutorial</u></html>"><paramname="textColor"value="blue"></object>, <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://www.ogre3d.org/wiki/index.php/Blender_Exporter"><paramname="text"value="<html><u>Blender-to-Ogre plugin</u></html>"><paramname="textColor"value="blue"></object>, <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Comparison_of_3D_computer_graphics_software#Features"><paramname="text"value="<html><u>Comparison of 3D graphic software features (Wikipedia)</u></html>"><paramname="textColor"value="blue"></object>.
</p>
</div>
<!-- EDIT13 SECTION "How do I Create 3-D models, textures, sounds?" [4821-5568] -->
<!-- EDIT13 SECTION "How do I Create 3-D models, textures, sounds?" [4821-5818] -->
<h3><a>How do I load a 3-D model into the scene?</a></h3>
Use an <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Issue_tracking_system"><paramname="text"value="<html><u>issue and bug tracker</u></html>"><paramname="textColor"value="blue"></object> to outline what features you want and what components are needed.
</p>
<ol>
<li><div> Pre-Alpha</div>
<li><div> Pre-Alpha Development</div>
<ul>
<li><div> Artwork: Test asset loading and saving with mock-ups and stock art.</div>
</li>
<li><div> Lay out the overall application flow, i.e. switching between intro / options / game screen, etc.</div>
</li>
<li><div> Get one typical level working. E.g. if the game is a "Jump'n'Run", jumping and running must work before you can announce Alpha.</div>
<li><div> Get one typical level working before you can announce the Alpha Release. <br/>
E.g. if the game is a "Jump'n'Run", jumping and running must work.</div>
</li>
</ul>
</li>
<li><div> Alpha Release</div>
</li>
<li><div> Pre-Beta Development</div>
<ul>
<li><div> Artwork: Replace all mock-ups with first drafts of real media and level maps.</div>
<li><div>Have your team members review and "alpha test" it on various systems, track bugs, debug, optimize.</div>
</li>
<li><div> Declare <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Feature_freeze"><paramname="text"value="<html><u>Feature Freeze</u></html>"><paramname="textColor"value="blue"></object> before you announce Beta. This prevents a bottomless pit of new bugs.</div>
<li><div> Declare <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Feature_freeze"><paramname="text"value="<html><u>Feature Freeze</u></html>"><paramname="textColor"value="blue"></object> before you announce the Beta Release to prevent a bottomless pit of new bugs.</div>
</li>
</ul>
</li>
<li><div> Beta Release</div>
</li>
<li><div> Post-Beta Development</div>
<ul>
<li><div> Artwork: Fill in the final media and level maps.</div>
</li>
<li><div> Have external people review and "beta test" it (track bugs).</div>
<li><div> Have external people review and "beta test" it, make it easy to report bugs.</div>
</li>
<li><div>Even out the kinks in code and gameplay – don't add any more new features.</div>
<li><div>Fix high-priority bugs, even out the kinks in code and gameplay, don't add new features for now!</div>
<li><div> Test the heck out of it. Last chance to find a horrible bug.</div>
<li><div> Think you're done? Make test runs incl. packaging and distribution. (Order form? download?)</div>
</li>
<li><div> Test the heck out of it. Last chance to find and fix a horrible bug.</div>
</li>
</ul>
</li>
@ -137,7 +144,7 @@ How you name or number these stages is fully up to your team. Development teams
</p>
</div>
<!-- EDIT4 SECTION "Planning Development Milestones" [2001-3484] -->
<!-- EDIT4 SECTION "Planning Development Milestones" [2001-3785] -->
<h3><a>Use File Version Control</a></h3>
<div>
@ -156,7 +163,7 @@ If you don't know which to choose, Subversion is a good choice for starters
</ul>
</div>
<!-- EDIT5 SECTION "Use File Version Control" [3485-4317] -->
<!-- EDIT5 SECTION "Use File Version Control" [3786-4618] -->
<h2><a>Multi-Media Asset Pipeline</a></h2>
<div>
<div><table>
@ -182,14 +189,14 @@ If you don't know which to choose, Subversion is a good choice for starters
<td> Convert Models to j3o format. Move j3o files into <code>assets/Models</code>. </td><td>Don't reference Blender/Ogre/OBJ files in your load() code, because these unoptimized files are not packaged into the JAR.</td>
</tr>
</table></div>
<!-- EDIT7 TABLE [4358-5244] -->
<!-- EDIT7 TABLE [4659-5545] -->
<p>
Learn details about the <ahref="/com/jme3/gde/core/docs/jme3/intermediate/multi-media_asset_pipeline.html">Multi-Media Asset Pipeline</a> here.
@ -229,26 +236,26 @@ For your future game releases, you will want to rely on your own base framework:
You have a list of features that you want in game, but which one do you implement first? You will keep adding features to a project that grows more and more complex, how can you minimize the amount of rewriting required?
</p>
<ol>
<li><div> Make sure the game's high-level frame (screen switching, networking, loading/saving) is sound and solid. </div>
<li><div> Make sure the game's high-level frame (screen switching, network sync, loading/saving) is sound and solid. </div>
</li>
<li><div> Start with implementing the most complex game feature first – the one that imposes most constraints on the structure of your project (for example: networking or physics.)</div>
<li><div> 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.)</div>
</li>
<li><div> Add only one larger feature at a time. If there are complex interactions (such as "networking + physics"), start with a small test case ("one cube") and work your way up, don't start with a whole scene.</div>
<li><div> 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 soruces of error.</div>
</li>
<li><div> Implement low-complexity decorations (audio and visual effects) last.</div>
</li>
<li><div> Test for side-effects on existing code after you add a feature.</div>
<li><div> Test for side-effects on existing code after you add a new feature (regression test).</div>
</li>
</ol>
<p>
<p><div>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 but 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.
<p><div>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 <em>drop</em>.
</div></p>
</p>
</div>
<!-- EDIT10 SECTION "Where to Start?" [7092-8371] -->
<!-- EDIT10 SECTION "Where to Start?" [7393-8760] -->
<h3><a>The Smart Way to Add Custom Methods and Fields</a></h3>
<div>
@ -272,28 +279,25 @@ Game entities (<code>Nodes</code> and <code>Geometry</code>s) often carry custom
</ul>
</div>
<!-- EDIT11 SECTION "The Smart Way to Add Custom Methods and Fields" [8372-9720] -->
<!-- EDIT11 SECTION "The Smart Way to Add Custom Methods and Fields" [8761-10109] -->
<h3><a>The Smart Way to Access Game Features</a></h3>
<div>
<p>
<ahref="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> gives you access to game features such as a the rootNode, assetManager, guiNode, inputManager, audioManager, physicsSpace, viewPort, and the camera. But what if you need access to the assetManager or rootNode etc from another class? Don't pass around lots of object references in constructors. This is a sign that this class should be designed as an <ahref="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">AppState</a> (read details there).
</p>
<p>
An AppState has access to all game features in the SimpleApplication via the <code>this.app</code> and <code>this.stateManager</code> objects.
<ahref="/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html">SimpleApplication</a> gives you access to game features such as a the rootNode, assetManager, guiNode, inputManager, audioManager, physicsSpace, viewPort, and the camera. But what if you need this access also from another class? Don't extend SimpleApplication a second time, and don't pass around tons of object references in constructors! Needing access to application level objects is a sign that this class should be designed as an <ahref="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">AppState</a> (read details there).
</p>
<p>
Examples:
An AppState has access to all game features in the SimpleApplication via the <code>this.app</code> and <code>this.stateManager</code> objects. Examples:
<!-- EDIT12 SECTION "The Smart Way to Access Game Features" [9721-10493] -->
<!-- EDIT12 SECTION "The Smart Way to Access Game Features" [10110-10947] -->
<h3><a>The Smart Way to Implement Game Logic</a></h3>
<div>
@ -355,38 +359,38 @@ Read all about <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.ht
</p>
</div>
<!-- EDIT13 SECTION "The Smart Way to Implement Game Logic" [10494-13296] -->
<!-- EDIT13 SECTION "The Smart Way to Implement Game Logic" [10948-13750] -->
<h3><a>Optimize Application Performance</a></h3>
<div>
<ul>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a> – how to avoid wasting cycles</div>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/intermediate/optimization.html">Optimization</a> – How to avoid wasting cycles</div>
</li>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/multithreading.html">Multithreading</a> – use concurrency, and don't change the scene graph from outside the update loop.</div>
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/multithreading.html">Multithreading</a> – Use concurrency for long-running backgroudn tasks, but don't manipulate the scene graph from outside the main thread (update loop)!</div>
</li>
<li><div> You can add a <ahref="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">Java Profiler</a> to the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often (try to cache values to avoid this). If object creation and garbage collection counts keep increasing, you are looking at a memory leak.</div>
<h3><a>Don't Mess With Geometric State</a></h3>
<div>
<p>
These tips are especially for users who already know jME2. Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to <em>not</em> mess with it.
<strong>These tips are especially important for users who already know jME2.</strong> Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to <em>not</em> mess with it.
</p>
<ul>
<li><div> Do not call updateGeometricState() on anything but the root node!</div>
<li><div> Do not call <code>updateGeometricState()</code> on anything but the root node!</div>
</li>
<li><div> Do not override or mess with updateGeometricState() at all.</div>
<li><div> Do not override or mess with <code>updateGeometricState()</code> at all.</div>
</li>
<li><div> Do not use getLocalTranslation().set() to move a spatial, always use setLocalTranslation().</div>
<li><div> Do not use <code>getLocalTranslation().set()</code> to move a spatial in jME3, always use <code>setLocalTranslation()</code>.</div>
</li>
</ul>
</div>
<!-- EDIT15 SECTION "Don't Mess With Geometric State" [13970-14421] -->
<!-- EDIT15 SECTION "Don't Mess With Geometric State" [14475-14964] -->
<h3><a>Maintain Internal Documentation</a></h3>
<div>
@ -397,7 +401,7 @@ It's unlikely you will fully document <em>every</em> class you write, we he
<ul>
<li><div> What is this? How does it solve its task (input, algorithm used, output, side-effects)? </div>
</li>
<li><div> Write down limits (e.g. min/max values) and defaults while you still remember.</div>
<li><div> Write down implicit limits (e.g. min/max values) and defaults while you still remember.</div>
</li>
<li><div> 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? </div>
</li>
@ -409,13 +413,13 @@ Treat javadoc as messages to your future self. "genNextVal() generates the
<strong>A <ahref="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">Java Debugger</a></strong> is included in the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym>. It allows you to set a break point in your code near the point where an exception happens. Then you step through the execution line by line and watch object and variable states to detect where the bug starts.
<strong>A <ahref="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">Java Debugger</a></strong> is included in the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym>. It allows you to set a break point in your code near the line of code where an exception happens. Then you step through the execution line by line and watch object and variable states live, to detect where the bug starts.
</p>
<p>
@ -423,7 +427,7 @@ Treat javadoc as messages to your future self. "genNextVal() generates the
</p>
<p>
<strong>Unit Testing (<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://download.oracle.com/javase/1.4.2/docs/guide/lang/assert.html"><paramname="text"value="<html><u>Java Assertions</u></html>"><paramname="textColor"value="blue"></object>)</strong> has a different status in 3D graphics development than in other types of software. You cannot write assertions that automatically test whether the rendered image <em>looks</em> correct, or whether interactions are <em>intuitive</em>. Still you should <ahref="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">create simple test cases</a> for individual game features such as loaders, content generators, effects. Run the test cases now and then to see whether they still work as intended – or whether they are suffering from side-effects. Keep the test classes in a test directory in the project, don't include them in the distribution.
<strong>Unit Testing (<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://download.oracle.com/javase/1.4.2/docs/guide/lang/assert.html"><paramname="text"value="<html><u>Java Assertions</u></html>"><paramname="textColor"value="blue"></object>)</strong> has a different status in 3D graphics development than in other types of software. You cannot write assertions that automatically test whether the rendered image <em>looks</em> correct, or whether interactions are <em>intuitive</em>. Still you should <ahref="/com/jme3/gde/core/docs/sdk/debugging_profiling_testing.html">create simple test cases</a> for individual game features such as loaders, content generators, effects. Run the test cases now and then to see whether they still work as intended – or whether they are suffering from regressions or side-effects. Keep the test classes in the <code>test</code> directory of your project, don't include them in the distribution.
</p>
<p>
@ -431,20 +435,20 @@ Treat javadoc as messages to your future self. "genNextVal() generates the
</p>
<p>
<strong>Alpha and Beta Testing</strong> means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure the gameplay out by themselves (you only can include the usual read-me and help docs). Provide the testers with an easy method to report back problems, or why they gave up. Evaluate whether these problems are exceptions or must be fixed for the game to be playable.
<strong>Alpha and Beta Testing</strong> means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure out the installation and gameplay by themselves–you only can include the usual read-me and help docs. Provide the testers with an easy method to report back what problems they encountered, what they liked best, or why they gave up. Evaluate whether reported problems are one-off glitches, or whether they must be fixed for the game to be playable for everyone.
</p>
</div>
<!-- EDIT17 SECTION "Debugging and Test Phase" [15150-17635] -->
<!-- EDIT17 SECTION "Debugging and Test Phase" [15702-18318] -->
<li><div> Prepare a web page, advertise, etc</div>
<li><div> Prepare a web page, a cool slogan, advertisements, etc</div>
</li>
<li><div> Verify that all assets are up-to-date and converted to .j3o. </div>
</li>
@ -454,28 +458,28 @@ Treat javadoc as messages to your future self. "genNextVal() generates the
</li>
<li><div> Switch off fine <ahref="/com/jme3/gde/core/docs/jme3/advanced/logging.html">logging</a> output.</div>
</li>
<li><div> Prepare promotional art: Cool screenshots (in thumbnail, square, vertical, horizontal, and fullscreen formats) and video clips. Include name, contact info, slogan, etc., so future customers can find you.</div>
<li><div> Prepare promotional art: The most awesome screenshots (in thumbnail, square, vertical, horizontal, and fullscreen formats) and video clips. Include name, contact info, slogan, etc., so future customers can find you.</div>
</li>
<li><div> Prepare a readme.txt file, or installation guide, or handbook – if applicable.</div>
</li>
<li><div> Get a certificate if it is required for your distribution method (see below).</div>
<li><div> Get a certificate if one is required for your distribution method (see below).</div>
</li>
<li><div> Specify a classification rating.</div>
<li><div> Specify a <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://en.wikipedia.org/wiki/Video_game_content_rating_system#Comparison"><paramname="text"value="<html><u>classification rating</u></html>"><paramname="textColor"value="blue"></object> (needed for e.g. app stores).</div>
The <ahref="/com/jme3/gde/core/docs/sdk/application_deployment.html">jMonkeyEngine SDK helps you with deployment</a>: You specify your branding and deployment options in the Project Properties dialog, and then choose Clean and Build from the context menu. If you use another IDE, then consult the IDE's documentation.
The <ahref="/com/jme3/gde/core/docs/sdk/application_deployment.html">jMonkeyEngine SDK helps you with deployment</a>: You specify your branding and deployment options in the Project Properties dialog, and then choose Clean and Build from the context menu. <strong>If you use another IDE, consult this IDE's documentation.</strong>
</p>
<p>
Decide whether you want to release your game as WebStart, Desktop JAR, or Applet – Each has its pros and cons.
Decide whether you want to release your game as WebStart, desktop JAR, mobile APK, or browser Applet – Each has its pros and cons.
</p>
<div><table>
@ -503,7 +507,7 @@ Decide whether you want to release your game as WebStart, Desktop JAR, or Applet
(.APK)</td><td>Game runs on Android devices.</td><td>Android devices do not support post-procesor effects.</td>
</tr>
</table></div>
<!-- EDIT21 TABLE [18909-20129] -->
<!-- EDIT21 TABLE [19751-20971] -->
<p>
Which ever method you choose, a Java-Application works on the main operating systems: Windows, Mac <acronymtitle="Operating System">OS</acronym>, Linux, Android.
@ -515,5 +519,5 @@ The distribution appears in a newly generated <code>dist</code> directory inside
</p>
</div>
<!-- EDIT20 SECTION "Distributing the Executables" [18476-] -->
<!-- EDIT20 SECTION "Distributing the Executables" [19298-] -->
@ -26,7 +26,7 @@ You want to make the most of your 3D models by specifying good looking material
</p>
<p>
If you want more advanced background info: You can learn more about <ahref="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> in general here. You can find the full list of Material Parameters in the <ahref="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material Definitions Properties</a> overview. The following sections introduce you to the most commonly used cases. You typically initialize Material objects in the <code>initSimpleApp()</code> method, and configure them using the setters described here. Then load the Materials using <code>myGeometry.setMaterial(mat)</code>.
If you want more advanced background info: You can learn more about <ahref="/com/jme3/gde/core/docs/jme3/advanced/material_definitions.html">Material Definitions</a> in general here. You can find the full list of Material Parameters in the <ahref="/com/jme3/gde/core/docs/jme3/advanced/materials_overview.html">Material Definitions Properties</a> overview. The following sections introduce you to the most commonly used cases. You typically initialize Material objects in the <code>simpleInitApp()</code> method, and configure them using the setters described here. Then load the Materials using <code>myGeometry.setMaterial(mat)</code>.
<li><div> Specify a <code>Glow</code> color. <br/>
A ColorRGBA value of your choice, e.g. choose a warm or cold color for different effects, or white for a neutral glow.<pre>mat.setColor("Glow",ColorRGBA.White);</pre>
A ColorRGBA value of your choice, e.g. choose a warm or cold color for different effects, or white for a neutral glow.<pre>mat.setColor("GlowColor",ColorRGBA.White);</pre>
</div>
</li>
<li><div> (Optional) Specify a <code>GlowMap</code> texture. <br/>
@ -244,7 +244,7 @@ This texture outlines in detail where the DiffuseMap texture glows. If you don&#
To deactivate glow:
</p>
<ul>
<li><div> Set the <code>Glow</code> color to <code>ColorRGBA.Black</code>.<pre>mat.setFloat("Glow", ColorRGBA.Black);</pre>
<li><div> Set the <code>Glow</code> color to <code>ColorRGBA.Black</code>.<pre>mat.setColor("GlowColor", ColorRGBA.Black);</pre>
</div>
</li>
</ul>
@ -255,7 +255,7 @@ Learn more about <a href="/com/jme3/gde/core/docs/jme3/advanced/bloom_and_glow.h
@ -293,12 +293,13 @@ To make a Geometry transparent or translucent:
<li><div> Specify BlendMode Alpha for the Material. <pre>mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);</pre>
</div>
</li>
<li><div> Put the Geometry (not the Material!) in the appropriate render queue</div>
<li><div> Put the Geometry (not the Material!) in the appropriate render queue bucket. <br/>
Objects in the translucent bucket (e.g. particles) are not affected by SceneProcessors (e.g. shadows). Obejcts in the transparent bucket (e.g. foliage) are affected by SceneProcessors (e.g. shadows).</div>
@ -355,7 +356,7 @@ Additionally to the above settings, you can switch off and on a wireframe render
<td>getAdditionalRenderState().setWireframe(true);</td><td>Switch to showing the (textured) Material in wireframe mode. The wireframe optionally uses the Material's <code>Color</code> value.</td><td>Use wireframes to debug meshes, or for a "matrix" or "holodeck" effect.</td>
@ -14,7 +14,7 @@ This page is intended as a reference collection of optimization tricks that can
<p>
The more Geometry objects are added to the scene, the harder it gets to handle them in a speedy fashion.
The reason for this is, that for every object a render command must be done, here is a bottleneck between the CPU and the graphics card.
The reason for this is that a render command must be done for every object, potentially creating a bottleneck between the CPU and the graphics card.
</p>
<p>
@ -32,80 +32,65 @@ You can optimize nodes using the SceneComposer in the <acronym title="Software D
<ul>
<li><div> Using GeometryBatchFactory merges individual Geometries into a single mesh. Thereby it becomes hard to apply specific Materials or to remove a single Geometry. Therefore it should be used for static Geometry only that does not require frequent changes or individual materials/texturing. </div>
</li>
<li><div>Using Texture atlases might be a way to provide a limited individual texturing.</div>
<li><div> Using a <ahref="/com/jme3/gde/core/docs/jme3/advanced/texture_atlas.html">Texture Atlas</a> provides limited individual texturing of batched geometries.</div>
When you use math operations like vectorA.mult(vectorB); new objects are created that have to be garbage collected when you don't use them anymore. Check your math operations for opportunities to use the local version of the math operations, e.g. vectorA.multLocal(vectorB). This way the result is stored in vectorA and no new object needs to be created.
When you use math operations like <code>vectorA.mult(vectorB);</code>, they create new objects for the result. These objects have to be garbage collected when you don't use them anymore.
</p>
<p>
Check your math operations for opportunities to use the <em>local</em> version of the math operations, e.g. <code>vectorA.multLocal(vectorB)</code>. Local methods store the result in vectorA and do not create a new object. Use local methods if you do not need to keep the previous vectorA.
</p>
</div>
<!-- EDIT3 SECTION "Avoid creating new objects" [1157-1550] -->
<!-- EDIT3 SECTION "Avoid creating new objects" [1194-1690] -->
<h2><a>Avoid large objects in physics</a></h2>
<div>
<p>
To offload much computation to the less CPU intense physics broadphase collision check, avoid having large meshes that cover e.g. the whole map of your level. Instead separate the collision shapes into multiple smaller parts. Obviously this can also be overdone as excessive amounts of physics objects can bring other performance problems.
To offload much computation to the less CPU intense physics broadphase collision check, avoid having large meshes that cover e.g. the whole map of your level. Instead, separate the collision shapes into multiple smaller chunks. Obviously, don't exaggerate the chunking, because having excessive amounts of physics objects similarly cause performance problems.
</p>
</div>
<!-- EDIT4 SECTION "Avoid large objects in physics" [1551-1933] -->
<!-- EDIT4 SECTION "Avoid large objects in physics" [1691-2095] -->
<h2><a>Check the Statistics</a></h2>
<div>
<p>
SimpleApplication displays a HUD with statistics. Use <code>app.setDisplayStatView(true);</code> to activate it, and false to deactivate it.
It counts how many FrameBuffers, Textures, or Shaders…
SimpleApplication displays a HUD with statistics. Use <code>app.setDisplayStatView(true);</code> to activate it, and false to deactivate it.
The StatsView counts Objects,Uniforms,Triangles,Vertices are in the scene, and it counts how many FrameBuffers, Textures, or Shaders:
</p>
<ul>
<li><div> … were switched in the last frame (S)</div>
</li>
<li><div> … were used during the last frame (F)</div>
</li>
<li><div> … exist in memory (M)</div>
<li><div> … exist in OpenGL memory (M)</div>
</li>
</ul>
<p>
Example:
For example, <code>Textures (M)</code> tells you how many textures are currently in OpenGL memory.
</p>
<ul>
<li><div> Textures (M) = how many textures are currently in the OpenGL driver</div>
</li>
<li><div> Textures(F) = how many textures were used in the last frame</div>
</li>
<li><div> Textures(S) = how many texture switches were done in the last frame.</div>
</li>
</ul>
<p>
Genereally jME3 is well optimized and optimizes these things correctly. The normal state is that the (S/F/M) values should be in the same order of magnitude; (S) values can be lower than (F).
Generally jME3 is well optimized and optimizes these things correctly. Read <ahref="/com/jme3/gde/core/docs/jme3/advanced/statsview.html">statsview</a> to learn the details about how to interpret the statistics, how to tell whether your values are off, or whether they point out a problem.
</p>
<ul>
<li><div> If the (S) values are significantly higher than the (F) values, that means there are a lot of extra switches happening which can cause a performance loss. Switches happen for instance if you have many transparent materials in your scene. In that case this tells you that you should use fewer transparent materials.</div>
</li>
<li><div> If the (M) values are much higher than the (F) values, that means a lot more GL objects are in memory than are actually used. This can happen in rare cases, such as extremely large scenes (> 2000 wu) with lots of spatials or lots of different materials. In this case, you should can optimize performance by identifying spatials to cull or detach.</div>
</li>
<li><div> The Object Count (Batch Count) is a very important value that indicates how many geometries were rendered in the last frame. In general, try to keep the object count around 100-200 to keep your game fast and responsive. If the count is permanently higher, hand-code rules that detach remote objects, or optimize a complex multi-material scene using: <pre>GeometryBatchFactory.optimize(complexNode, true);</pre>
</div>
</li>
<li><div> Same for Triangle Counts. If your game runs sluggishly and triangle (polygon) count is high, then you are rendering too many too detailed meshes. Tell your graphic designers to create models with lower polygon counts.</div>
</li>
<li><div> FrameBuffers: If you don't use any post-processing effects (FilterPostProcessor), this count should be zero. The more effects you use, the more FrameBuffers are in use. If this value is high while others are normal, you can speed up the application by using fewer post-processing effects.</div>
@ -187,7 +187,7 @@ A browser Applet is a Java application that runs in the web browser while the us
</p>
<p>
These instrcutions assume that you have already written a game that you want to turn into an Applet. As opposed to other jME3 games, Applets cannot capture the mouse for navigation, so the camera will be switched to dragToRotate mode. The jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> and the included build script already contain what you need.
These instructions assume that you have already written a game that you want to turn into an Applet. As opposed to other jME3 games, Applets cannot capture the mouse for navigation, so the camera will be switched to dragToRotate mode. The jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> and the included build script already contain what you need.
@ -16,8 +16,13 @@ It was important to have always the lates version of the script that is compatib
Now we have an opportunity to simplify the import process by loading data directly from blender binary files: *.blend.
</p>
<p>
<p><div>Before you try to import models, make sure you <ahref="/com/jme3/gde/core/docs/jme3/external/blender.html">created them properly</a>.
</div></p>
</p>
</div>
<!-- EDIT2 SECTION "Introduction" [53-791] -->
<!-- EDIT2 SECTION "Introduction" [53-911] -->
<h2><a>Usage</a></h2>
<div>
@ -27,7 +32,7 @@ By default a BlenderModelLoader is registered with your assetManager to load ble
</p>
</div>
<!-- EDIT3 SECTION "Usage" [792-1108] -->
<!-- EDIT3 SECTION "Usage" [912-1228] -->
<h2><a>Currently supported features</a></h2>
<div>
<ol>
@ -43,6 +48,8 @@ By default a BlenderModelLoader is registered with your assetManager to load ble
</li>
<li><div> User defined UV coordinates are read.</div>
</li>
<li><div> Loading BMesh is supported.</div>
</li>
</ul>
</li>
<li><div> Loading textures.</div>
@ -73,6 +80,8 @@ By default a BlenderModelLoader is registered with your assetManager to load ble
</li>
<li><div> Generated textures are 'baked' into 2D textures and merged to create one flat texture. They can be freely merged with image textures.</div>
</li>
<li><div> Generated textures can be used as normal maps (but this looks poor when large amount of small triangles is used; incleasing generated texture ppu in blender key might help a little)</div>
</li>
</ul>
</li>
<li><div> Loading materials.</div>
@ -152,12 +161,10 @@ By default a BlenderModelLoader is registered with your assetManager to load ble
<li><div><ahref="/com/jme3/gde/core/docs/jme3/advanced/material_specification.html">Developer specification of the jME3 material system (.j3md,.j3m)</a></div>
@ -96,13 +96,25 @@ Now let's have a look at the project's file structure in the File Expl
</li>
</ul>
</div>
<!-- EDIT2 SECTION "Creating a New jMonkeyEngine Project" [159-2931] -->
<h2><a>Working With Your Game Project</a></h2>
<div>
<p>
Project Configuration
</p>
<p>
Right-Click the project to open the Project properties.
</p>
<p>
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 <strong>(in most cases set the-Xms VMOption [NUMBER] m for the memory usage. for example (-Xms500m). see <objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://performance.netbeans.org/howto/jvmswitches/"><paramname="text"value="<html><u>http://performance.netbeans.org/howto/jvmswitches/</u></html>"><paramname="textColor"value="blue"></object>)</strong>.
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.
</p>
</div>
<!-- EDIT3 SECTION "Working With Your Game Project" [2932-2975] -->
<!-- EDIT2 SECTION "Creating a New jMonkeyEngine Project" [159-3635] -->
<h3><a>Project Configuration</a></h3>
<div>
@ -122,7 +134,7 @@ Right-Click the project to open the Project properties.
<h3><a>Getting error messages and reporting issues</a></h3>
<div>
<p>
When an exception happens in the <acronymtitle="Software Development Kit">SDK</acronym>, a small warning sign appears in the lower right corner of the main window. Double-click it to open a window that allows you to see the exception stack trace. When posting about issues in the forum, always post the stack trace along with a description of what happens and how it can be reproduced.
For a list of known issues and possible workarounds see the following link:
<objectclassid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><paramname="content"value="http://code.google.com/p/jmonkeyengine/issues/list?can=2&q=label%3AProduct-Platform+Type%3DDefect+&colspec=ID+Type+Status+Component+Priority+Product+Milestone+Owner+Summary&cells=tiles"><paramname="text"value="<html><u>List of known issues on googlecode</u></html>"><paramname="textColor"value="blue"></object>
</p>
@ -124,5 +132,5 @@ For a list of known issues and possible workarounds see the following link:
@ -8,11 +8,24 @@ Whether you work in a development team or alone: File versioning is a handy meth
</p>
<p>
For every team member, the file versioning workflow is as follows:
</p>
<ol>
<li><div> Once: Download a working copy of the project from the repository ("checkout").</div>
</li>
<li><div> Regularly: Upload your own changes to the repository ("commit").</div>
</li>
<li><div> Regularly: Download updates by others from the repository ("update"). </div>
</li>
</ol>
<p>
Note: Since the jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> is based on the NetBeans Platform framework, you can learn about certain jMonkeyEngine <acronymtitle="Software Development Kit">SDK</acronym> features by reading the corresponding NetBeans IDE tutorials (in the "see also links").
</p>
</div>
<!-- EDIT1 SECTION "jMonkeyEngine SDK: Version Control" [1-579] -->
<!-- EDIT1 SECTION "jMonkeyEngine SDK: Version Control" [1-878] -->
<h2><a>Version Control Systems</a></h2>
<div>
@ -26,7 +39,7 @@ You can use file versioning alone or in a team. The advantages are that you can
</p>
</div>
<!-- EDIT2 SECTION "Version Control Systems" [580-1076] -->
<!-- EDIT2 SECTION "Version Control Systems" [879-1375] -->
<h2><a>Creating a Repository (Upload)</a></h2>
<div>
@ -39,11 +52,11 @@ Requirements:
</li>
<li><div> You must have version control software installed (Subversion, Mercurial, or <acronymtitle="Concurrent Versions System">CVS</acronym>) and have initialized a repository.</div>
<ul>
<li><div> Tip: For Subversion, the init command looks like this example: <code>svnadmin create /home/joe/mysvnrepo</code></div>
<li><div> Tip: For Subversion, for example, the init command looks like this example: <code>svnadmin create /home/joe/jMonkeyProjects/MyGame</code></div>
</li>
</ul>
</li>
<li><div> The computer where the repository is to be hosted must be available in your network, or you will only be able to use your repo locally.</div>
<li><div> The computer where the repository is to be hosted must be available in your team's network, or you will only be able to use your repo locally.</div>
<ul>
<li><div> Tip: Hosts such as SourceForge, GoogleCode, dev.java.net offer free version control services for open-source projects.</div>
</li>
@ -68,7 +81,7 @@ Now you create a repository to store your project's files.
</ol>
</div>
<!-- EDIT3 SECTION "Creating a Repository (Upload)" [1077-2106] -->
<!-- EDIT3 SECTION "Creating a Repository (Upload)" [1376-2438] -->
<h2><a>Checking Out a Repository (Download)</a></h2>
<div>
@ -104,7 +117,7 @@ Of course you can also check out existing repositories and access code from othe
</p>
</div>
<!-- EDIT4 SECTION "Checking Out a Repository (Download)" [2107-3080] -->
<!-- EDIT4 SECTION "Checking Out a Repository (Download)" [2439-3412] -->
<h2><a>Updating and Committing Changes (Send and Receive)</a></h2>
<div>
@ -143,7 +156,7 @@ Receiving the latest changes from the team's repository is referred to as <
</ol>
</div>
<!-- EDIT5 SECTION "Updating and Committing Changes (Send and Receive)" [3081-4329] -->
<!-- EDIT5 SECTION "Updating and Committing Changes (Send and Receive)" [3413-4661] -->
<h2><a>Comparing and Reverting Changes</a></h2>
<div>
<ul>
@ -174,7 +187,7 @@ Receiving the latest changes from the team's repository is referred to as <
</ul>
</div>
<!-- EDIT6 SECTION "Comparing and Reverting Changes" [4330-5121] -->
<!-- EDIT6 SECTION "Comparing and Reverting Changes" [4662-5453] -->
<h2><a>No Version Control? Local History!</a></h2>
<div>
@ -208,5 +221,5 @@ See also:
</span></div>
</div>
<!-- EDIT7 SECTION "No Version Control? Local History!" [5122-] -->
<!-- EDIT7 SECTION "No Version Control? Local History!" [5454-] -->