SimpleApplication.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * Copyright (c) 2009-2010 jMonkeyEngine
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. package com.jme3.app;
  33. import com.jme3.font.BitmapFont;
  34. import com.jme3.font.BitmapText;
  35. import com.jme3.input.FlyByCamera;
  36. import com.jme3.input.KeyInput;
  37. import com.jme3.input.controls.ActionListener;
  38. import com.jme3.input.controls.KeyTrigger;
  39. import com.jme3.math.Quaternion;
  40. import com.jme3.math.Vector3f;
  41. import com.jme3.renderer.RenderManager;
  42. import com.jme3.renderer.queue.RenderQueue.Bucket;
  43. import com.jme3.scene.Node;
  44. import com.jme3.scene.Spatial.CullHint;
  45. import com.jme3.system.AppSettings;
  46. import com.jme3.system.JmeContext.Type;
  47. import com.jme3.system.JmeSystem;
  48. import com.jme3.util.BufferUtils;
  49. /**
  50. * <code>SimpleApplication</code> extends the {@link com.jme3.app.Application}
  51. * class to provide default functionality like a first-person camera,
  52. * and an accessible root node that is updated and rendered regularly.
  53. * Additionally, <code>SimpleApplication</code> will display a statistics view
  54. * using the {@link com.jme3.app.StatsView} class. It will display
  55. * the current frames-per-second value on-screen in addition to the statistics.
  56. * Several keys have special functionality in <code>SimpleApplication</code>:<br/>
  57. *
  58. * <table>
  59. * <tr><td>Esc</td><td>- Close the application</td></tr>
  60. * <tr><td>C</td><td>- Display the camera position and rotation in the console.</td></tr>
  61. * <tr><td>M</td><td>- Display memory usage in the console.</td></tr>
  62. * </table>
  63. */
  64. public abstract class SimpleApplication extends Application {
  65. public static final String INPUT_MAPPING_EXIT = "SIMPLEAPP_Exit";
  66. public static final String INPUT_MAPPING_CAMERA_POS = "SIMPLEAPP_CameraPos";
  67. public static final String INPUT_MAPPING_MEMORY = "SIMPLEAPP_Memory";
  68. public static final String INPUT_MAPPING_HIDE_STATS = "SIMPLEAPP_HideStats";
  69. protected Node rootNode = new Node("Root Node");
  70. protected Node guiNode = new Node("Gui Node");
  71. protected float secondCounter = 0.0f;
  72. protected int frameCounter = 0;
  73. protected BitmapText fpsText;
  74. protected BitmapFont guiFont;
  75. protected StatsView statsView;
  76. protected FlyByCamera flyCam;
  77. protected boolean showSettings = true;
  78. private boolean showFps = true;
  79. private AppActionListener actionListener = new AppActionListener();
  80. private class AppActionListener implements ActionListener {
  81. public void onAction(String name, boolean value, float tpf) {
  82. if (!value) {
  83. return;
  84. }
  85. if (name.equals(INPUT_MAPPING_EXIT)) {
  86. stop();
  87. } else if (name.equals(INPUT_MAPPING_CAMERA_POS)) {
  88. if (cam != null) {
  89. Vector3f loc = cam.getLocation();
  90. Quaternion rot = cam.getRotation();
  91. System.out.println("Camera Position: ("
  92. + loc.x + ", " + loc.y + ", " + loc.z + ")");
  93. System.out.println("Camera Rotation: " + rot);
  94. System.out.println("Camera Direction: " + cam.getDirection());
  95. }
  96. } else if (name.equals(INPUT_MAPPING_MEMORY)) {
  97. BufferUtils.printCurrentDirectMemory(null);
  98. }else if (name.equals(INPUT_MAPPING_HIDE_STATS)){
  99. boolean show = showFps;
  100. setDisplayFps(!show);
  101. setDisplayStatView(!show);
  102. }
  103. }
  104. }
  105. public SimpleApplication() {
  106. super();
  107. }
  108. @Override
  109. public void start() {
  110. // set some default settings in-case
  111. // settings dialog is not shown
  112. boolean loadSettings = false;
  113. if (settings == null) {
  114. setSettings(new AppSettings(true));
  115. loadSettings = true;
  116. }
  117. // show settings dialog
  118. if (showSettings) {
  119. if (!JmeSystem.showSettingsDialog(settings, loadSettings)) {
  120. return;
  121. }
  122. }
  123. //re-setting settings they can have been merged from the registry.
  124. setSettings(settings);
  125. super.start();
  126. }
  127. /**
  128. * Retrieves flyCam
  129. * @return flyCam Camera object
  130. *
  131. */
  132. public FlyByCamera getFlyByCamera() {
  133. return flyCam;
  134. }
  135. /**
  136. * Retrieves guiNode
  137. * @return guiNode Node object
  138. *
  139. */
  140. public Node getGuiNode() {
  141. return guiNode;
  142. }
  143. /**
  144. * Retrieves rootNode
  145. * @return rootNode Node object
  146. *
  147. */
  148. public Node getRootNode() {
  149. return rootNode;
  150. }
  151. public boolean isShowSettings() {
  152. return showSettings;
  153. }
  154. /**
  155. * Toggles settings window to display at start-up
  156. * @param showSettings Sets true/false
  157. *
  158. */
  159. public void setShowSettings(boolean showSettings) {
  160. this.showSettings = showSettings;
  161. }
  162. /**
  163. * Attaches FPS statistics to guiNode and displays it on the screen.
  164. *
  165. */
  166. public void loadFPSText() {
  167. guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  168. fpsText = new BitmapText(guiFont, false);
  169. fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
  170. fpsText.setText("Frames per second");
  171. guiNode.attachChild(fpsText);
  172. }
  173. /**
  174. * Attaches Statistics View to guiNode and displays it on the screen
  175. * above FPS statistics line.
  176. *
  177. */
  178. public void loadStatsView() {
  179. statsView = new StatsView("Statistics View", assetManager, renderer.getStatistics());
  180. // move it up so it appears above fps text
  181. statsView.setLocalTranslation(0, fpsText.getLineHeight(), 0);
  182. guiNode.attachChild(statsView);
  183. }
  184. @Override
  185. public void initialize() {
  186. super.initialize();
  187. guiNode.setQueueBucket(Bucket.Gui);
  188. guiNode.setCullHint(CullHint.Never);
  189. loadFPSText();
  190. loadStatsView();
  191. viewPort.attachScene(rootNode);
  192. guiViewPort.attachScene(guiNode);
  193. if (inputManager != null) {
  194. flyCam = new FlyByCamera(cam);
  195. flyCam.setMoveSpeed(1f);
  196. flyCam.registerWithInput(inputManager);
  197. if (context.getType() == Type.Display) {
  198. inputManager.addMapping(INPUT_MAPPING_EXIT, new KeyTrigger(KeyInput.KEY_ESCAPE));
  199. }
  200. inputManager.addMapping(INPUT_MAPPING_CAMERA_POS, new KeyTrigger(KeyInput.KEY_C));
  201. inputManager.addMapping(INPUT_MAPPING_MEMORY, new KeyTrigger(KeyInput.KEY_M));
  202. inputManager.addMapping(INPUT_MAPPING_HIDE_STATS, new KeyTrigger(KeyInput.KEY_F5));
  203. inputManager.addListener(actionListener, INPUT_MAPPING_EXIT,
  204. INPUT_MAPPING_CAMERA_POS, INPUT_MAPPING_MEMORY, INPUT_MAPPING_HIDE_STATS);
  205. }
  206. // call user code
  207. simpleInitApp();
  208. }
  209. @Override
  210. public void update() {
  211. super.update(); // makes sure to execute AppTasks
  212. if (speed == 0 || paused) {
  213. return;
  214. }
  215. float tpf = timer.getTimePerFrame() * speed;
  216. if (showFps) {
  217. secondCounter += timer.getTimePerFrame();
  218. frameCounter ++;
  219. if (secondCounter >= 1.0f) {
  220. int fps = (int) (frameCounter / secondCounter);
  221. fpsText.setText("Frames per second: " + fps);
  222. secondCounter = 0.0f;
  223. frameCounter = 0;
  224. }
  225. }
  226. // update states
  227. stateManager.update(tpf);
  228. // simple update and root node
  229. simpleUpdate(tpf);
  230. rootNode.updateLogicalState(tpf);
  231. guiNode.updateLogicalState(tpf);
  232. rootNode.updateGeometricState();
  233. guiNode.updateGeometricState();
  234. // render states
  235. stateManager.render(renderManager);
  236. renderManager.render(tpf, context.isRenderable());
  237. simpleRender(renderManager);
  238. stateManager.postRender();
  239. }
  240. public void setDisplayFps(boolean show) {
  241. showFps = show;
  242. fpsText.setCullHint(show ? CullHint.Never : CullHint.Always);
  243. }
  244. public void setDisplayStatView(boolean show) {
  245. statsView.setEnabled(show);
  246. statsView.setCullHint(show ? CullHint.Never : CullHint.Always);
  247. }
  248. public abstract void simpleInitApp();
  249. public void simpleUpdate(float tpf) {
  250. }
  251. public void simpleRender(RenderManager rm) {
  252. }
  253. }