- some cleanups in Material Editor

- add new wiki pages
- improve "development" section in manual

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7194 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 14 years ago
parent 6407e5617d
commit 0e6e586c05
  1. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/core-toc.xml
  2. 5
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/custom_meshes.html
  3. 20
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/multithreading.html
  4. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/nifty_gui_projection.html
  5. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/advanced/update_loop.html
  6. 19
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/api_feature_mapping.html
  7. 7
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html
  8. 21
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/jme3/intermediate/simpleapplication.html
  9. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/application_deployment.html
  10. 89
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development.html
  11. 44
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/projects_assets.html
  12. 17
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/scene.html
  13. 118
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/sceneexplorer.html
  14. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/development/setup.html
  15. 4
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/sdk/material_editing.html
  16. 2
      sdk/jme3-core/javahelp/com/jme3/gde/core/docs/wiki-map.xml
  17. 2
      sdk/jme3-core/javahelp/wiki_help.properties
  18. 6
      sdk/jme3-materialeditor/src/com/jme3/gde/materials/EditableMaterialFile.java
  19. 2
      sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPropertyEditor.java
  20. 44
      sdk/jme3-materialeditor/src/com/jme3/gde/materials/multiview/MaterialEditorTopComponent.java
  21. 1
      sdk/jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/MaterialPropertyWidget.java

@ -61,7 +61,7 @@
<tocitem text="Deployment" target="sdk.application_deployment"/>
</tocitem>
<tocitem text="jMP Plugin Development" expand="false">
<tocitem text="About jMP Plugin Development" target="com.jme3.gde.development"/>
<tocitem text="About jMP Plugin Development" target="sdk.development"/>
<tocitem text="Creating a plugin" target="sdk.development.setup"/>
<tocitem text="Creating components" target="sdk.development.general"/>
<tocitem text="Accessing the Scene" target="sdk.development.scene"/>

@ -126,10 +126,13 @@ The Mesh data is stored in a buffer.
</li>
<li><div> The third parameter describes the number of components of the values. Vertex postions are 3 float values, texture coordinates are 2 float values, and the indices are single ints. </div>
</li>
<li><div> In order for JMonkey to correctly show the mesh in the scene, it needs to know the bounds of our new mesh. This can easily be achieved by calling the updateBound() method on it.</div>
</li>
</ol>
<pre>m.setBuffer&#40;Type.Position, 3, BufferUtils.createFloatBuffer&#40;vertices&#41;&#41;;
m.setBuffer&#40;Type.TexCoord, 2, BufferUtils.createFloatBuffer&#40;texCoord&#41;&#41;;
m.setBuffer&#40;Type.Index, 1, BufferUtils.createIntBuffer&#40;indexes&#41;&#41;;</pre>
m.setBuffer&#40;Type.Index, 1, BufferUtils.createIntBuffer&#40;indexes&#41;&#41;;
m.updateBound&#40;&#41;;</pre>
<p>
Our Mesh is ready! Now we want to see it.
</p>

@ -8,15 +8,15 @@ First, make sure you know what <a href="/com/jme3/gde/core/docs/jme3/advanced/ap
</p>
<p>
More complex games may feature complex mathematical operations or artificially intelligent calculations (such as path finding for several NPCs). If you make many time-intensive calls on the same thread (e.g. in the simpleUpdate() loop), they will block one another, and thus slow down the game to a degree that makes it unplayable. If your game requires long running tasks, you should run them concurrently on separate threads, which speeds up the application considerably.
More complex games may feature complex mathematical operations or artificially intelligent calculations (such as path finding for several NPCs). If you make many time-intensive calls on the same thread (in the update loop), they will block one another, and thus slow down the game to a degree that makes it unplayable. If your game requires long running tasks, you should run them concurrently on separate threads, which speeds up the application considerably.
</p>
<p>
Often multithreading means having separate detached logical loops going on in parallel, which communicate about their state. (For example, one thread for AI, one Sound, one Graphics). However many programmers use a global update loop for game logic, and then just do multithreading within that loop when it is appropriate. This scales way better to multiple cores and does not break up your code logic.
Often multithreading means having separate detached logical loops going on in parallel, which communicate about their state. (For example, one thread for AI, one Sound, one Graphics). However we recommend to use a global update loop for game logic, and do multithreading within that loop when it is appropriate. This approach scales way better to multiple cores and does not break up your code logic.
</p>
<p>
Effectively, each for-loop in the main event loop might be a chance for multithreading, if you can break it up into self-contained tasks.
Effectively, each for-loop in the main update loop might be a chance for multithreading, if you can break it up into self-contained tasks.
</p>
</div>
@ -26,7 +26,7 @@ Effectively, each for-loop in the main event loop might be a chance for multithr
<p>
The java.util.concurrent package provides a good foundation for multithreading and dividing work into tasks that can be executed concurrently (hence the name). The three basic components are the Executor, Callable Objects (the tasks), and Future Objects. You can read about the concurrent package more <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://download.oracle.com/javase/tutorial/essential/concurrency/"><param name="text" value="<html><u>here</u></html>"><param name="textColor" value="blue"></object>, I will give just a short introduction.
The java.util.concurrent package provides a good foundation for multithreading and dividing work into tasks that can be executed concurrently (hence the name). The three basic components are the Executor, Callable Objects (the tasks), and Future Objects. You can <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="http://download.oracle.com/javase/tutorial/essential/concurrency/"><param name="text" value="<html><u>read about the concurrent package more here</u></html>"><param name="textColor" value="blue"></object>, I will give just a short introduction.
</p>
<ul>
@ -49,7 +49,7 @@ So how do we implement multithreading in jME3?
</p>
<p>
Let&#039;s take the example of a Control that controls an NPC Spatial. The NPC Control has to compute a lengthy pathfinding operation for each NPC. If we would execute the operations directly in the simpleUpdate() loop, it would block the game each time a NPC wants to move from A to B. Even if we move this behaviour into the update() method of a dedicated NPC Control, we would still get annoying freeze frames, because it still runs on the same event loop thread.
Let&#039;s take the example of a Control that controls an NPC Spatial. The NPC Control has to compute a lengthy pathfinding operation for each NPC. If we would execute the operations directly in the simpleUpdate() loop, it would block the game each time a NPC wants to move from A to B. Even if we move this behaviour into the update() method of a dedicated NPC Control, we would still get annoying freeze frames, because it still runs on the same update loop thread.
</p>
<p>
@ -87,7 +87,7 @@ MyWayList wayList = null;
//The future that is used to check the execution status:
Future future = null;</pre>
<p>
Here we also created the Future object to track the state of this task.
Here we also created the Future variable to track the state of this task.
</p>
</div>
@ -198,6 +198,14 @@ private Callable&lt;MyWayList&gt; findWay = new Callable&lt;MyWayList&gt;&#40;&#
The cool thing about this appraoch is that every entity creates one self-contained Callable for the Executor, and they are all executed in parallel. In theory, you can have one thread per entity without changing anything else but the settings of the executor.
</p>
<div><span>
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>,
<a href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>,
<a href="/wiki/doku.php/tag:performance?do=showtag&amp;tag=tag%3Aperformance">performance</a>,
<a href="/wiki/doku.php/tag:state?do=showtag&amp;tag=tag%3Astate">state</a>,
<a href="/wiki/doku.php/tag:states?do=showtag&amp;tag=tag%3Astates">states</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading?do=export_xhtmlbody">view online version</a></em></p>

@ -38,7 +38,7 @@ On this page, we look at the projection variant (less commonly used).
<p>
You can project the Nifty <acronym title="Graphical User Interface">GUI</acronym> onto a texture, load the texture into a material, and assign it to a 3D mesh. Allthough this is possible the approach is rarely used since it is difficult to record clicks this way, you can only interact with this UI by keyboard.
You can project the Nifty <acronym title="Graphical User Interface">GUI</acronym> onto a texture, load the texture into a material, and assign it to a 3D mesh. Allthough this is possible the approach is rarely used since it is difficult to record clicks this way, you can only interact with this UI by keyboard or programmatically. (e.g. an action performed by a character standing in front of a “computer”)
</p>
<pre>/** Create a new viewport for the GUI */
ViewPort niftyView = renderManager.createPreView&#40;&quot;NiftyView&quot;, new Camera&#40;1024, 768&#41;&#41;;

@ -53,7 +53,7 @@ Use…
</p>
<ul>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/application_states.html">Application States</a> to implement global game mechanics <br/>
Example: Physics</div>
Example: Physics, Global gameplay control</div>
</li>
<li><div> <a href="/com/jme3/gde/core/docs/jme3/advanced/custom_controls.html">Custom Controls</a> to implement entity behavior <br/>
Example: Enemy AI</div>

@ -23,8 +23,15 @@ Knowing exactly what you are looking for allows you to search more efficiently,
<th>Start with a preconfigured game </th><td>com.jme3.app.SimpleApplication </td><td><a href="/com/jme3/gde/core/docs/jme3/beginner/hello_simpleapplication.html">Hello SimpleApplication</a> </td>
</tr>
<tr>
<th>Make an object appear in the scene </th><td>Attach nodes and geometries to the rootNode: rootNode.attach(geo); <br/>
com.jme3.scene.Node, com.jme3.scene.Geometry </td><td><a href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/>
<th>Make an object appear in the scene</th><td>Attach nodes and geometries to the rootNode: rootNode.attachChild(geo); <br/>
com.jme3.scene.Node, com.jme3.scene.Geometry <br/>
node.setCullHint(CullHint.Never); </td><td><a href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/>
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/>
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> </td>
</tr>
<tr>
<th>Make an object disappear from the scene</th><td>Detach nodes and geometries from the rootNode: rootNode.detachChild(geo); <br/>
node.setCullHint(CullHint.Always);</td><td><a href="/com/jme3/gde/core/docs/jme3/the_scene_graph.html">The Scene Graph</a> <br/>
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_asset.html">Hello Asset</a> <br/>
<a href="/com/jme3/gde/core/docs/jme3/beginner/hello_node.html">Hello Node</a> </td>
</tr>
@ -50,10 +57,7 @@ Knowing exactly what you are looking for allows you to search more efficiently,
<a href="/com/jme3/gde/core/docs/jme3/intermediate/appsettings.html">AppSettings</a> </td>
</tr>
<tr>
<th>Force or disable culling</th><td>rootNode.setCullHint(CullHint.Never);</td><td>N/A </td>
</tr>
<tr>
<th>Disable the logger</th><td>Logger.getLogger(””).setLevel(Level.SEVERE); <br/>
<th>Disable the logger output</th><td>Logger.getLogger(””).setLevel(Level.SEVERE); <br/>
java.util.logging.*</td><td> <a href="/com/jme3/gde/core/docs/jme3/advanced/logging.html">Logging</a> </td>
</tr>
</table>
@ -264,7 +268,8 @@ Knowing exactly what you are looking for allows you to search more efficiently,
Logger.getLogger(HelloJME3.class.getName()).log(Level.INFO, “Caps: {0}” + caps.toString()); </td><td> N/A </td>
</tr>
<tr>
<th>Optimize the heck out of the scenegraph</th><td>jme3tools.optimize.GeometryBatchFactory <br/>
GeometryBatchFactory.optimize(rootNode); </td><td> N/A </td>
</tr>
</table>

@ -61,7 +61,7 @@ value="groups">Groups</option><option
value="members">Members</option><option
value="links">Links</option></select> <input
type="submit" name="search-submit" id="search-submit" value="Search" /> <input
type="hidden" id="_wpnonce" name="_wpnonce" value="401c23b197" /><input
type="hidden" id="_wpnonce" name="_wpnonce" value="9f69e1a059" /><input
type="hidden" name="_wp_http_referer" value="/com/jme3/gde/core/docs/jme3/intermediate/my_first_game.html" /></form></div></div><div
id="access"><ul
id="menu-mainmenu"><li
@ -242,11 +242,10 @@ class="random-list"><li><a
href="http://jmonkeyengine.org/members/?random-member">Random Member</a></li><li
class="alt"><a
href="http://jmonkeyengine.org/groups/?random-group">Random Group</a></li><li><a
href="http://jmonkeyengine.org/links/?random-link">Random Link</a></li></ul></li></ul></div></div> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.core.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.widget.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.mouse.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.resizable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.draggable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.button.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.position.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.dialog.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-ui-custom.min.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-cookie.min.js?ver=3.1'></script> <script type="text/javascript">var $rotateoptions=new Array();$rotateoptions[2]=new Array();$rotateoptions[2]["style"]="";$rotateoptions[2]["rotate"]=0;$rotateoptions[2]["random_start"]=0;$rotateoptions[2]["start_tab"]=0;$rotateoptions[2]["interval"]=10000;$rotateoptions[3]=new Array();$rotateoptions[3]["style"]="tabs";$rotateoptions[3]["rotate"]=0;$rotateoptions[3]["random_start"]=0;$rotateoptions[3]["start_tab"]=0;$rotateoptions[3]["interval"]=10000;</script> <script type="text/javascript" src="http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/init-plugin.js"></script>
<script src="http://stats.wordpress.com/e-201113.js" type="text/javascript"></script> <script type="text/javascript">st_go({blog:'14883676',v:'ext',post:'0'});var load_cmc=function(){linktracker_init(14883676,0,2);};if(typeof addLoadEvent!='undefined')addLoadEvent(load_cmc);else load_cmc();</script> </body></html>
href="http://jmonkeyengine.org/links/?random-link">Random Link</a></li></ul></li></ul></div></div> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.core.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.widget.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.mouse.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.resizable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.draggable.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.button.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.position.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-includes/js/jquery/ui.dialog.js?ver=1.8.9'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-ui-custom.min.js?ver=3.1'></script> <script type='text/javascript' src='http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/jquery-cookie.min.js?ver=3.1'></script> <script type="text/javascript">var $rotateoptions=new Array();$rotateoptions[2]=new Array();$rotateoptions[2]["style"]="";$rotateoptions[2]["rotate"]=0;$rotateoptions[2]["random_start"]=0;$rotateoptions[2]["start_tab"]=0;$rotateoptions[2]["interval"]=10000;$rotateoptions[3]=new Array();$rotateoptions[3]["style"]="tabs";$rotateoptions[3]["rotate"]=0;$rotateoptions[3]["random_start"]=0;$rotateoptions[3]["start_tab"]=0;$rotateoptions[3]["interval"]=10000;</script> <script type="text/javascript" src="http://jmonkeyengine.org/wp-content/plugins/tabbed-widgets/js/init-plugin.js"></script> <script type="text/javascript">function wo_map_console(url){window.open(url,"wo_map_console","height=650,width=800,toolbar=no,statusbar=no,scrollbars=yes").focus();}</script> <script src="http://stats.wordpress.com/e-201114.js" type="text/javascript"></script> <script type="text/javascript">st_go({blog:'14883676',v:'ext',post:'0'});var load_cmc=function(){linktracker_init(14883676,0,2);};if(typeof addLoadEvent!='undefined')addLoadEvent(load_cmc);else load_cmc();</script> </body></html>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/
Minified using apc
Served from: jmonkeyengine.org @ 2011-03-28 14:38:52 -->
Served from: jmonkeyengine.org @ 2011-04-05 22:34:18 -->
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:my_first_game?do=export_xhtmlbody">view online version</a></em></p>

@ -21,12 +21,17 @@ public class HelloWorld extends SimpleApplication &#123;
&nbsp;
@Override
public void simpleInitApp&#40;&#41; &#123;
/* Initialize your game scene here */
/* Initialize the game scene here */
&#125;
&nbsp;
@Override
public void simpleUpdate&#40;float tpf&#41; &#123;
/* Interact with game events here in the main loop */
/* (optional) Interact with game events in the main loop */
&#125;
&nbsp;
@Override
public void simpleRender&#40;RenderManager rm&#41; &#123;
/* (optional) Make advanced modifications to frameBuffer and scene graph. */
&#125;
&#125;</pre>
<p>
@ -262,6 +267,18 @@ If useInput() is true, the default Flyby Cam is active. Then the following so-ca
<td>Rotate drag</td><td>Hold left mouse button and move</td>
</tr>
</table>
<div><span>
<a href="/wiki/doku.php/tag:display?do=showtag&amp;tag=tag%3Adisplay">display</a>,
<a href="/wiki/doku.php/tag:basegame?do=showtag&amp;tag=tag%3Abasegame">basegame</a>,
<a href="/wiki/doku.php/tag:documentation?do=showtag&amp;tag=tag%3Adocumentation">documentation</a>,
<a href="/wiki/doku.php/tag:intro?do=showtag&amp;tag=tag%3Aintro">intro</a>,
<a href="/wiki/doku.php/tag:intermediate?do=showtag&amp;tag=tag%3Aintermediate">intermediate</a>,
<a href="/wiki/doku.php/tag:init?do=showtag&amp;tag=tag%3Ainit">init</a>,
<a href="/wiki/doku.php/tag:input?do=showtag&amp;tag=tag%3Ainput">input</a>,
<a href="/wiki/doku.php/tag:game?do=showtag&amp;tag=tag%3Agame">game</a>,
<a href="/wiki/doku.php/tag:loop?do=showtag&amp;tag=tag%3Aloop">loop</a>,
<a href="/wiki/doku.php/tag:rootnode?do=showtag&amp;tag=tag%3Arootnode">rootnode</a>
</span></div>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/jme3:intermediate:simpleapplication?do=export_xhtmlbody">view online version</a></em></p>

@ -298,7 +298,7 @@ To remove unused libraries:
</li>
<li><div> Press the “Add Library” button</div>
</li>
<li><div> Select the “jme3-libraries-lwjgl-minimum” or “jme3-libraries-jogl-minimum” library (depening on which renderer you use).</div>
<li><div> Select the “jme3-libraries-lwjgl-minimum” library</div>
</li>
<li><div> Add other jME3 libraries in the same way depending which features you use (jme3-libraries-gui, jme3-libraries-physics, jme3-libraries-video etc.) </div>
</li>

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

@ -0,0 +1,44 @@
<h1><a>Projects and Assets</a></h1>
<div>
<p>
The <acronym title="Software Development Kit">SDK</acronym> heavily uses the systems provided by the base platform for the handling of assets and projects and extends the system with jME3 specific features.
</p>
</div>
<h2><a>AssetDataObject</a></h2>
<div>
<p>
Most “files” that you encounter in the <acronym title="Software Development Kit">SDK</acronym> come in the form of AssetDataObjects. All Nodes that you encounter contain the AssetDataObject they were loaded from. It provides not just access to the FileObject of the specific file but also an AssetData object that allows access to jME specific properties and data. The AssetData object also allows loading the object via the jME3 assetManager. It is accessible via the lookup of the Node or AssetDataObject:
</p>
<pre>assetDataObject.getLookup&#40;&#41;.lookup&#40;AssetData.class&#41;</pre>
</div>
<h2><a>ProjectAssetManager</a></h2>
<div>
<p>
All AssetDataObjects and SceneExplorerNodes allow access to the ProjectAssetManager of the project they were loaded from.
</p>
<pre>ProjectAssetManager pm = node.getLookup&#40;&#41;.lookup&#40;ProjectAssetManager.class&#41;</pre>
<p>
The ProjectAssetManager is basically a normal DesktopAssetManager for each project with some added functionality:
</p>
<ul>
<li><div> Access to the FileObject of the assets folder of the project to load and save data</div>
</li>
<li><div> Convert absolute file paths to relative asset paths and vice versa</div>
</li>
<li><div> Get lists of all textures, materials etc. in the project</div>
</li>
<li><div> more convenient stuff.. :)</div>
</li>
</ul>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:projects_assets?do=export_xhtmlbody">view online version</a></em></p>

@ -31,23 +31,6 @@ There are several ways for your plugin to interact with the Scene:
</div>
<h5><a>Notes</a></h5>
<div>
<ul>
<li><div> <em>Although the scene can be accessed at any time via SceneApplication.getApplication() it is not recommended to modify the scene like that. Other plugins might be accessing the scene and updates will not be properly recognized.</em></div>
</li>
<li><div> <em>Remember the scene runs on the render thread and most everything you do in the plugin (button events etc.) runs on the AWT thread, always encapsulate calls to either side correctly via Callables/Runnables or register as an AppState to the SceneApplication to have an update() call by the render thread.</em></div>
</li>
<li><div> <em>It became a standard in jMP to start the name of methods that execute directly on the OpenGL thread with “do” e.g “doMoveSpatial”, this makes identifying threading issues easier.</em></div>
</li>
<li><div> <em>The AssetManager of jme3 is threadsafe and can be used from any thread to load assets</em></div>
</li>
<li><div> <em>Use org.openide.filesystems.FileObject instead of java.io.File for file access, it always uses system-independent ”/” path separators and has some more advanced functions that make file handling easier. You can get a file from a string using Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(“aaa/bbb/ccc/whatever”);</em></div>
</li>
</ul>
</div>
<h2><a>Listening for Node selection</a></h2>
<div>

@ -15,19 +15,24 @@ If your plugin brings in its own SceneGraph objects you can still have them work
<p>
You will have to create your own class that extends org.openide.nodes.Node and implement the interface com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode. Then you register that class by adding
</p>
<pre>@org.openide.util.lookup.ServiceProvider(service=com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode.class)</pre>
<pre>@org.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)</pre>
<p>
above the “public class MyClass” line in your class. Thats all, your Spatial type will automatically be used and displayed in the SceneExplorer. Make sure you register a jar with the used classes in the plugin preferences under “wrapped libraries”, otherwise the IDE cannot access those classes.
above the body of your class. Thats all, your Spatial type will automatically be used and displayed in the SceneExplorer. Make sure you register a jar with the used classes in the plugin preferences under “wrapped libraries”, otherwise the IDE cannot access those classes.
</p>
<p>
Theres also AbstractSceneExplorerNode which brings some other useful features you might want to include like automatic creation of properly threaded properties etc. JmeSpatial for example bases on it. A simple SceneExplorerNode example for an object extending Spatial would be JmeGeometry (see below).
Theres also AbstractSceneExplorerNode which brings some other useful features you might want to include like automatic creation of properly threaded properties etc. JmeSpatial for example bases on it. A simple SceneExplorerNode example for an object extending Spatial would be JmeGeometry (see below). Editors for special variable types can be added using the SceneExplorerPropertyEditor interface, which can be registered as a ServiceProvider as well.
</p>
<p>
The SceneExplorerNode can be used for Spatial and Control type objects.
</p>
<ul>
<li><div><em>Add the “Nodes <acronym title="Application Programming Interface">API</acronym>” and “Lookup <acronym title="Application Programming Interface">API</acronym>” libraries to your project when you want to use this</em></div>
</li>
</ul>
</div>
@ -201,7 +206,7 @@ public class JmeGhostControl extends AbstractSceneExplorerNode &#123;
<div>
<p>
For adding Spatials, Contols and for general tools theres premade abstract classes that you can use to extend the options. Undo/Redo is handled by the abstract class.
For adding Spatials, Contols and for general tools theres premade abstract classes that you can use to extend the options. Undo/Redo is handled by the abstract class. AbstractNewSpatial<strong>Wizard</strong>Action allows you to show an AWT wizard before creating the Spatial. You can also just implement the base ServiceProvider class and return any kind of action (such as a wizard), in this case you have to handle the threading yourself!
</p>
<p>
@ -286,5 +291,110 @@ public class NewRigidBodyAction extends AbstractNewControlAction &#123;
return control;
&#125;
&#125;</pre>
</div>
<h4><a>Adding using a Wizard</a></h4>
<div>
<p>
You can create a new wizard using the wizard template in the <acronym title="Software Development Kit">SDK</acronym>. The Action the wizard creates can easily be changed to a Wizard for adding a Control or Spatial or for applying a Tool. Note that we extend AbstractNewSpatial<strong>Wizard</strong>Action here.
</p>
<p>
A good example is the “Add SkyBox” Wizard:
</p>
<pre>@org.openide.util.lookup.ServiceProvider&#40;service = NewSpatialAction.class&#41;
public class AddSkyboxAction extends AbstractNewSpatialWizardAction &#123;
&nbsp;
private WizardDescriptor.Panel&#91;&#93; panels;
&nbsp;
public AddSkyboxAction&#40;&#41; &#123;
name = &quot;Skybox..&quot;;
&#125;
&nbsp;
@Override
protected Object showWizard&#40;org.openide.nodes.Node node&#41; &#123;
WizardDescriptor wizardDescriptor = new WizardDescriptor&#40;getPanels&#40;&#41;&#41;;
wizardDescriptor.setTitleFormat&#40;new MessageFormat&#40;&quot;{0}&quot;&#41;&#41;;
wizardDescriptor.setTitle&#40;&quot;Skybox Wizard&quot;&#41;;
Dialog dialog = DialogDisplayer.getDefault&#40;&#41;.createDialog&#40;wizardDescriptor&#41;;
dialog.setVisible&#40;true&#41;;
dialog.toFront&#40;&#41;;
boolean cancelled = wizardDescriptor.getValue&#40;&#41; != WizardDescriptor.FINISH_OPTION;
if &#40;!cancelled&#41; &#123;
return wizardDescriptor;
&#125;
return null;
&#125;
&nbsp;
@Override
protected Spatial doCreateSpatial&#40;Node parent, Object properties&#41; &#123;
if &#40;properties != null&#41; &#123;
return generateSkybox&#40;&#40;WizardDescriptor&#41; properties&#41;;
&#125;
return null;
&#125;
&nbsp;
private Spatial generateSkybox&#40;WizardDescriptor wiz&#41; &#123;
if &#40;&#40;Boolean&#41; wiz.getProperty&#40;&quot;multipleTextures&quot;&#41;&#41; &#123;
Texture south = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureSouth&quot;&#41;;
Texture north = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureNorth&quot;&#41;;
Texture east = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureEast&quot;&#41;;
Texture west = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureWest&quot;&#41;;
Texture top = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureTop&quot;&#41;;
Texture bottom = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureBottom&quot;&#41;;
Vector3f normalScale = &#40;Vector3f&#41; wiz.getProperty&#40;&quot;normalScale&quot;&#41;;
return SkyFactory.createSky&#40;pm, west, east, north, south, top, bottom, normalScale&#41;;
&#125; else &#123;
Texture textureSingle = &#40;Texture&#41; wiz.getProperty&#40;&quot;textureSingle&quot;&#41;;
Vector3f normalScale = &#40;Vector3f&#41; wiz.getProperty&#40;&quot;normalScale&quot;&#41;;
boolean useSpheremap = &#40;Boolean&#41; wiz.getProperty&#40;&quot;useSpheremap&quot;&#41;;
return SkyFactory.createSky&#40;pm, textureSingle, normalScale, useSpheremap&#41;;
&#125;
&#125;
&nbsp;
<span>/**
* Initialize panels representing individual wizard's steps and sets
* various properties for them influencing wizard appearance.
*/</span>
private WizardDescriptor.Panel&#91;&#93; getPanels&#40;&#41; &#123;
if &#40;panels == null&#41; &#123;
panels = new WizardDescriptor.Panel&#91;&#93;&#123;
new SkyboxWizardPanel1&#40;&#41;,
new SkyboxWizardPanel2&#40;&#41;
&#125;;
String&#91;panels.length&#93;;
for &#40;int i = 0; i &lt; panels.length; i++&#41; &#123;
Component c = panels&#91;i&#93;.getComponent&#40;&#41;;
// Default step name to component name of panel. Mainly useful
// for getting the name of the target chooser to appear in the
// list of steps.
steps&#91;i&#93; = c.getName&#40;&#41;;
if &#40;c instanceof JComponent&#41; &#123; // assume Swing components
JComponent&#41; c;
// Sets step number of a component
// TODO if using org.openide.dialogs &gt;= 7.8, can use WizardDescriptor.PROP_*:
jc.putClientProperty&#40;&quot;WizardPanel_contentSelectedIndex&quot;, new Integer&#40;i&#41;&#41;;
// Sets steps names for a panel
jc.putClientProperty&#40;&quot;WizardPanel_contentData&quot;, steps&#41;;
// Turn on subtitle creation on each step
jc.putClientProperty&#40;&quot;WizardPanel_autoWizardStyle&quot;, Boolean.TRUE&#41;;
// Show steps on the left side with the image on the background
jc.putClientProperty&#40;&quot;WizardPanel_contentDisplayed&quot;, Boolean.TRUE&#41;;
// Turn on numbering of all steps
jc.putClientProperty&#40;&quot;WizardPanel_contentNumbered&quot;, Boolean.TRUE&#41;;
&#125;
&#125;
&#125;
return panels;
&#125;
&#125;</pre>
<p>
The
</p>
</div>
<p><em><a href="http://jmonkeyengine.org/wiki/doku.php/sdk:development:sceneexplorer?do=export_xhtmlbody">view online version</a></em></p>

@ -98,7 +98,7 @@ To add your plugin to the repository, do the following:
</li>
<li><div> Enter <code><object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param name="content" value="https://jmonkeyplatform-contributions.googlecode.com/svn/trunk"><param name="text" value="<html><u>https://jmonkeyplatform-contributions.googlecode.com/svn/trunk</u></html>"><param name="textColor" value="blue"></object></code> in the <acronym title="Uniform Resource Locator">URL</acronym> field</div>
</li>
<li><div> Enter your googlecode username and password and press “Next”</div>
<li><div> Enter your googlecode username and commit password (different than login pass!) and press “Next”</div>
</li>
<li><div> Check that the “Repository Folder” is <code>trunk/mypluginfolder</code> and enter an import message</div>
</li>

@ -68,9 +68,9 @@ When the material is ready and saved into your projects assets directory, you ca
In the jMonkeyPlatform
</p>
<ol>
<li><div> Open the SceneExplorer window</div>
<li><div> Right-click the j3o file and select “Edit in SceneComposer”</div>
</li>
<li><div> Select the .j3o file in the Project window to view it in the SceneExplorer</div>
<li><div> Open the SceneExplorer window</div>
</li>
<li><div> In the SceneExplorer, click the geometry to which you want to assign the material.</div>
</li>

File diff suppressed because one or more lines are too long

@ -16,9 +16,11 @@ sdk:troubleshooting,\
sdk:use_own_jme,\
sdk:vehicle_creator,\
sdk:version_control,\
sdk:development,\
sdk:development:extension_library,\
sdk:development:general,\
sdk:development:model_loader,\
sdk:development:projects_assets,\
sdk:development:scene,\
sdk:development:sceneexplorer,\
sdk:development:setup,\

@ -31,7 +31,7 @@ import org.openide.util.Exceptions;
* Provides an editable j3m file
* @author normenhansen
*/
public class MaterialProperties {
public class EditableMaterialFile {
private String name;
private String matDefName;
@ -44,7 +44,7 @@ public class MaterialProperties {
private FileSystem fs;
public static final String[] variableTypes = new String[]{"Int", "Boolean", "Float", "Vector2", "Vector3", "Vector4", "Color", "Texture2D", "TextureCubeMap"};
public MaterialProperties(FileObject material, ProjectAssetManager manager) {
public EditableMaterialFile(FileObject material, ProjectAssetManager manager) {
this.material = material;
this.manager = manager;
}
@ -236,7 +236,7 @@ public class MaterialProperties {
Exceptions.printStackTrace(ex);
}
} else {
Logger.getLogger(MaterialProperties.class.getName()).log(Level.WARNING, "Could not read MaterialDef!");
Logger.getLogger(EditableMaterialFile.class.getName()).log(Level.WARNING, "Could not read MaterialDef!");
}
for (Iterator<Map.Entry<String, MaterialProperty>> it = materialParameters.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, MaterialProperty> entry = it.next();

@ -114,7 +114,7 @@ public class MaterialPropertyEditor implements PropertyEditor, SceneExplorerProp
newFile = currentFolder.getFileObject(currentFile.getName() + "_" + i, "j3m");
}
newFile = currentFolder.createData(currentFile.getName() + "_" + i, "j3m");
MaterialProperties properties = new MaterialProperties(newFile, pm);
EditableMaterialFile properties = new EditableMaterialFile(newFile, pm);
material.setAssetName(pm.getRelativeAssetPath(newFile.getPath()));
properties.setAsMaterial(material);
currentFolder.refresh();

@ -12,7 +12,7 @@ import com.jme3.gde.core.scene.PreviewRequest;
import com.jme3.gde.core.scene.SceneApplication;
import com.jme3.gde.core.scene.SceneListener;
import com.jme3.gde.core.scene.SceneRequest;
import com.jme3.gde.materials.MaterialProperties;
import com.jme3.gde.materials.EditableMaterialFile;
import com.jme3.gde.materials.MaterialProperty;
import com.jme3.gde.materials.multiview.widgets.MaterialPropertyWidget;
import com.jme3.gde.materials.multiview.widgets.MaterialWidgetListener;
@ -65,7 +65,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
private final InstanceContent lookupContents = new InstanceContent();
// private SaveNode saveNode;
private DataObject dataObject;
private MaterialProperties properties;
private EditableMaterialFile materialFile;
private String materialFileName;
private ProjectAssetManager manager;
private Sphere sphMesh;
@ -89,9 +89,9 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
setActivatedNodes(new Node[]{dataObject.getNodeDelegate()});
((AssetDataObject) dataObject).setSaveCookie(saveCookie);
manager = dataObject.getLookup().lookup(ProjectAssetManager.class);
properties = new MaterialProperties(dataObject.getPrimaryFile(), dataObject.getLookup().lookup(ProjectAssetManager.class));
properties.read();
setMatDefList(manager.getMatDefs(), properties.getMatDefName());
materialFile = new EditableMaterialFile(dataObject.getPrimaryFile(), dataObject.getLookup().lookup(ProjectAssetManager.class));
materialFile.read();
setMatDefList(manager.getMatDefs(), materialFile.getMatDefName());
try {
jTextArea1.setText(dataObject.getPrimaryFile().asText());
} catch (IOException ex) {
@ -331,10 +331,10 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
}// </editor-fold>//GEN-END:initComponents
private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed
if (properties != null) {
if (materialFile != null) {
updateProperties = true;
properties.setMatDefName((String) jComboBox1.getSelectedItem());
String string = properties.getUpdatedContent();
materialFile.setMatDefName((String) jComboBox1.getSelectedItem());
String string = materialFile.getUpdatedContent();
jTextArea1.setText(string);
}
}//GEN-LAST:event_jComboBox1ActionPerformed
@ -344,9 +344,9 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
}//GEN-LAST:event_reloadPreview
private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed
if (properties != null) {
properties.setName(jTextField1.getText());
String string = properties.getUpdatedContent();
if (materialFile != null) {
materialFile.setName(jTextField1.getText());
String string = materialFile.getUpdatedContent();
jTextArea1.setText(string);
}
}//GEN-LAST:event_jTextField1ActionPerformed
@ -508,15 +508,15 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
public void save() throws IOException {
String text = jTextArea1.getText();
properties.setAsText(text);
materialFile.setAsText(text);
dataObject.setModified(false);
showMaterial();
}
}
public void setMatDefList(final String[] strings, String selected) {
MaterialProperties prop = properties;
properties = null;
EditableMaterialFile prop = materialFile;
materialFile = null;
jComboBox1.removeAllItems();
jComboBox1.addItem("");
@ -533,7 +533,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
jComboBox1.addItem("Common/MatDefs/Terrain/Terrain.j3md");
// jComboBox1.addItem("Common/MatDefs/Misc/ShowNormals.j3md");
jComboBox1.setSelectedItem(selected);
properties = prop;
materialFile = prop;
}
private void updateProperties() {
@ -556,7 +556,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
List<Component> valueList = new LinkedList<Component>();
List<Component> textureList = new LinkedList<Component>();
List<Component> otherList = new LinkedList<Component>();
for (Iterator<Entry<String, MaterialProperty>> it = properties.getParameterMap().entrySet().iterator(); it.hasNext();) {
for (Iterator<Entry<String, MaterialProperty>> it = materialFile.getParameterMap().entrySet().iterator(); it.hasNext();) {
Entry<String, MaterialProperty> entry = it.next();
MaterialPropertyWidget widget = WidgetFactory.getWidget(entry.getValue(), manager);
widget.registerChangeListener(this);
@ -596,11 +596,11 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
}
jScrollPane2.repaint();
jScrollPane3.repaint();
setDisplayName(properties.getName() + " - " + properties.getMaterialPath());
MaterialProperties prop = properties;
properties = null;
setDisplayName(materialFile.getName() + " - " + materialFile.getMaterialPath());
EditableMaterialFile prop = materialFile;
materialFile = null;
jTextField1.setText(prop.getName());
properties = prop;
materialFile = prop;
updateStates();
}
@ -612,7 +612,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
}
}
statesPanel.removeAll();
for (Iterator<Entry<String, MaterialProperty>> it = properties.getStateMap().entrySet().iterator(); it.hasNext();) {
for (Iterator<Entry<String, MaterialProperty>> it = materialFile.getStateMap().entrySet().iterator(); it.hasNext();) {
Entry<String, MaterialProperty> entry = it.next();
MaterialPropertyWidget widget = WidgetFactory.getWidget(entry.getValue(), manager);
widget.registerChangeListener(this);
@ -654,7 +654,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
}
public void propertyChanged(MaterialProperty property) {
String string = properties.getUpdatedContent();
String string = materialFile.getUpdatedContent();
jTextArea1.setText(string);
}
}

@ -5,7 +5,6 @@
package com.jme3.gde.materials.multiview.widgets;
import com.jme3.gde.materials.MaterialProperties;
import com.jme3.gde.materials.MaterialProperty;
import javax.swing.JPanel;

Loading…
Cancel
Save