Compare commits

...

35 Commits
master ... 3.0

Author SHA1 Message Date
Normen Hansen 811e715c38 - add iOS input handling base classes 11 years ago
sgold@sonic.net 10490c2f39 update plugins version to 3.0.8 11 years ago
sgold@sonic.net a74fc22797 update version to 3.0.8 in core 11 years ago
sgold@sonic.net 0c4bfed950 fix issue where rays pass through Quads in certain cases: corresponds to SVN rev 10785 in trunk 11 years ago
sgold@sonic.net fb681741de fix issue where AnimChannel.update() fails to invoke onAnimCycleDone(): corresponds to ad99467cf2 in master 11 years ago
sgold@sonic.net dc4d959617 fix NPE in FilterPostProcessor: corresponds to SVN revision 10920 in trunk 11 years ago
nor..67 a77c090be2 - 3.0.7 fix for merge issue 11 years ago
nor..67 cacd179107 - re-fix leftover merge conflict 11 years ago
nor..67 9edf5dc21e - fix leftover merge conflict 11 years ago
nor..67 8ff93b862b update stable to 3.0.6, see http://hub.jmonkeyengine.org/forum/topic/candidate-changes-for-3-0-6/ 11 years ago
nor..67 fb02f3d95c - add svn merge infos 11 years ago
nor..67 48c7183385 - re-add some depth func stuff from ios renderer (only stable branch) 11 years ago
nor..67 f881fa7851 - re-add some depth func stuff from ios renderer (only stable branch) 11 years ago
nor..67 c8e6878b64 - re-add some depth func stuff from ios renderer (only stable branch) 11 years ago
nor..67 02841d4295 - remove depth func stuff from ios renderer (only stable branch) 11 years ago
nor..67 cacef7564a - add merge info 11 years ago
nor..67 0e75269405 - merge jdk version info 11 years ago
nor..67 22c77b954c Update 3.0.5 11 years ago
iwg..ic 4399db373b Bump SDK Plugins version 3.0.4 to push out an update 11 years ago
iwg..ic c2db7f0254 Bump JmeVersion to 3.0.4 11 years ago
iwg..ic 2209210617 Port patch for NativeObjectManager in Trunk r10889 to the 3.0 Final branch. https://code.google.com/p/jmonkeyengine/source/detail?r=10889 11 years ago
iwg..ic 64b9ae958b Bump plugins version number to 3.0.3 11 years ago
iwg..ic e2b7ebaf76 Bump engine version number to 3.0.3 11 years ago
iwg..ic 33db5460c3 Android: Update Android Config Chooser to the same level as r10798 from trunk. Fixes issues due to finding the EGL config too early based on a default display instead of finding the config when asked for it by the surface. 11 years ago
PSp..om f4b4fc9c1e Upping version. 12 years ago
PSp..om 781fb7b4e6 Fixing JME system version and upping it at the 12 years ago
PSp..om 22e4745fea From trunk: 12 years ago
rem..om 35cb546c0d Changed plugin version in 3.0final branch to 3.0.1 for sdk 12 years ago
rem..om f8c466f329 Merged revision 10799 from trunk 12 years ago
nor..67 16d34f7bbb Merge build and genfile changes 12 years ago
nor..67 cb980091ad Merge build changes 12 years ago
nor..67 d947820d9b Merge SDK config changes 12 years ago
nor..67 2271c690a3 Merge SDK config changes 12 years ago
nor..67 71217a6da2 Merge SDK config changes 12 years ago
PSp..om 247f2a633d Branching the code for final 3.0 release so we can continue 12 years ago
  1. 7
      build.xml
  2. 102
      engine/src/android/com/jme3/renderer/android/RendererUtil.java
  3. 172
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
  4. 116
      engine/src/android/com/jme3/system/android/OGLESContext.java
  5. 3
      engine/src/bullet-common/com/jme3/bullet/control/KinematicRagdollControl.java
  6. 2
      engine/src/bullet-common/com/jme3/bullet/util/CollisionShapeFactory.java
  7. 9
      engine/src/core-data/Common/MatDefs/Light/Lighting.frag
  8. 2
      engine/src/core-data/Common/MatDefs/Light/Lighting.vert
  9. 4
      engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag
  10. 3
      engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md
  11. 5
      engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag
  12. 8
      engine/src/core-data/Common/ShaderLib/MultiSample.glsllib
  13. 643
      engine/src/core-effects/com/jme3/post/filters/BloomFilter.java
  14. 5
      engine/src/core-effects/com/jme3/post/filters/LightScatteringFilter.java
  15. 47
      engine/src/core-effects/com/jme3/water/SimpleWaterProcessor.java
  16. 39
      engine/src/core-effects/com/jme3/water/WaterFilter.java
  17. 53
      engine/src/core-effects/com/jme3/water/WaterUtils.java
  18. 12
      engine/src/core-plugins/com/jme3/export/binary/BinaryExporter.java
  19. 10
      engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java
  20. 9
      engine/src/core-plugins/com/jme3/font/plugins/BitmapFontLoader.java
  21. 4
      engine/src/core-plugins/com/jme3/shader/plugins/GLSLLoader.java
  22. 10
      engine/src/core/com/jme3/animation/AnimChannel.java
  23. 4
      engine/src/core/com/jme3/app/FlyCamAppState.java
  24. 2
      engine/src/core/com/jme3/app/StatsAppState.java
  25. 21
      engine/src/core/com/jme3/audio/AudioNode.java
  26. 274
      engine/src/core/com/jme3/bounding/BoundingBox.java
  27. 91
      engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java
  28. 6
      engine/src/core/com/jme3/input/FlyByCamera.java
  29. 1
      engine/src/core/com/jme3/input/InputManager.java
  30. 2
      engine/src/core/com/jme3/input/KeyNames.java
  31. 4
      engine/src/core/com/jme3/light/DirectionalLight.java
  32. 3
      engine/src/core/com/jme3/light/SpotLight.java
  33. 34
      engine/src/core/com/jme3/post/FilterPostProcessor.java
  34. 22
      engine/src/core/com/jme3/renderer/Camera.java
  35. 7
      engine/src/core/com/jme3/renderer/RenderContext.java
  36. 20
      engine/src/core/com/jme3/scene/BatchNode.java
  37. 8
      engine/src/core/com/jme3/scene/Mesh.java
  38. 2
      engine/src/core/com/jme3/scene/Node.java
  39. 3027
      engine/src/core/com/jme3/scene/Spatial.java
  40. 4
      engine/src/core/com/jme3/scene/shape/Dome.java
  41. 12
      engine/src/core/com/jme3/shadow/AbstractShadowFilter.java
  42. 111
      engine/src/core/com/jme3/shadow/AbstractShadowRenderer.java
  43. 9
      engine/src/core/com/jme3/shadow/EdgeFilteringMode.java
  44. 2
      engine/src/core/com/jme3/system/JmeVersion.java
  45. 1
      engine/src/core/com/jme3/util/NativeObjectManager.java
  46. 543
      engine/src/core/com/jme3/util/SkyFactory.java
  47. 13
      engine/src/desktop/com/jme3/cursors/plugins/CursorLoader.java
  48. 12
      engine/src/desktop/com/jme3/system/Natives.java
  49. 1054
      engine/src/ios/com/jme3/audio/android/AL.java
  50. 67
      engine/src/ios/com/jme3/audio/android/AndroidAudioData.java
  51. 24
      engine/src/ios/com/jme3/audio/android/AndroidAudioRenderer.java
  52. 1423
      engine/src/ios/com/jme3/audio/android/AndroidOpenALSoftAudioRenderer.java
  53. 20
      engine/src/ios/com/jme3/audio/plugins/AndroidAudioLoader.java
  54. 203
      engine/src/ios/com/jme3/input/ios/IosInputHandler.java
  55. 191
      engine/src/ios/com/jme3/input/ios/IosTouchHandler.java
  56. 121
      engine/src/ios/com/jme3/input/ios/TouchEventPool.java
  57. 2572
      engine/src/ios/com/jme3/renderer/ios/IGLESShaderRenderer.java
  58. 273
      engine/src/ios/com/jme3/renderer/ios/JmeIosGLES.java
  59. 591
      engine/src/ios/com/jme3/renderer/ios/TextureUtil.java
  60. 200
      engine/src/ios/com/jme3/system/ios/IGLESContext.java
  61. 5
      engine/src/ios/com/jme3/system/ios/IosAssetManager.java
  62. 7
      engine/src/ios/com/jme3/system/ios/IosHarness.java
  63. 5
      engine/src/ios/com/jme3/system/ios/JmeIosSystem.java
  64. 76
      engine/src/ios/com/jme3/util/RingBuffer.java
  65. 17
      engine/src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java
  66. 39
      engine/src/niftygui/com/jme3/niftygui/InputSystemJme.java
  67. 14
      engine/src/terrain/com/jme3/terrain/heightmap/AbstractHeightMap.java
  68. 2
      engine/src/test/jme3test/audio/TestMusicStreaming.java
  69. 4
      sdk/jdks/build-package.sh
  70. 10
      sdk/jdks/versions
  71. 8
      sdk/jme3-android/nbproject/genfiles.properties
  72. 28
      sdk/jme3-android/nbproject/project.xml
  73. 8
      sdk/jme3-angelfont/nbproject/genfiles.properties
  74. 12
      sdk/jme3-angelfont/nbproject/project.xml
  75. 4
      sdk/jme3-assetpack-support/nbproject/genfiles.properties
  76. 34
      sdk/jme3-assetpack-support/nbproject/project.xml
  77. 8
      sdk/jme3-blender/nbproject/genfiles.properties
  78. 22
      sdk/jme3-blender/nbproject/project.xml
  79. 5
      sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java
  80. 97
      sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/Blender3dsDataObject.java
  81. 93
      sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/BlenderFbxDataObject.java
  82. 1
      sdk/jme3-blender/src/com/jme3/gde/blender/scripts/Scripts.java
  83. 83
      sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_fbx.py
  84. 8
      sdk/jme3-cinematics/nbproject/genfiles.properties
  85. 18
      sdk/jme3-cinematics/nbproject/project.xml
  86. 8
      sdk/jme3-code-check/nbproject/genfiles.properties
  87. 32
      sdk/jme3-code-check/nbproject/project.xml
  88. 8
      sdk/jme3-codepalette/nbproject/genfiles.properties
  89. 14
      sdk/jme3-codepalette/nbproject/project.xml
  90. 8
      sdk/jme3-core-updatecenters/nbproject/genfiles.properties
  91. 6
      sdk/jme3-core-updatecenters/nbproject/project.xml
  92. 66
      sdk/jme3-core/nbproject/project.xml
  93. 19
      sdk/jme3-core/src/com/jme3/gde/core/filters/AbstractFilterNode.java
  94. 10
      sdk/jme3-desktop-executables/nbproject/project.xml
  95. 4
      sdk/jme3-documentation/nbproject/genfiles.properties
  96. 2
      sdk/jme3-documentation/nbproject/project.xml
  97. 2
      sdk/jme3-documentation/src/com/jme3/gde/docs/jme3/advanced/3d_models.html
  98. 34
      sdk/jme3-documentation/src/com/jme3/gde/docs/jme3/advanced/application_states.html
  99. 31
      sdk/jme3-documentation/src/com/jme3/gde/docs/jme3/advanced/audio.html
  100. 8
      sdk/jme3-documentation/src/com/jme3/gde/docs/jme3/advanced/capture_audio_video_to_a_file.html
  101. Some files were not shown because too many files have changed in this diff Show More

@ -34,8 +34,10 @@
<ant dir="sdk" target="run"/>
</target>
<target name="zip" description="Builds the complete SDK and packs it as a ZIP file" depends="build">
<propertyfile file="sdk/nbproject/project.properties"/>
<target name="zip" description="Builds the complete SDK and packs it as a ZIP file">
<ant dir="engine" target="update-sdk"/>
<ant dir="sdk" target="build-zip"/>
<property file="sdk/nbproject/project.properties"/>
<move file="sdk/dist/${app.name}.zip" tofile="./jMonkeyEngine-SDK-${app.version}-NoBundles.zip"/>
</target>
@ -86,6 +88,7 @@
<target name="hudson-stable" depends="-hudson-revert-changes, -check-platform, -update-sdk-platform-config, -hudson-build-engine">
<!--ant dir="engine" target="dist"/-->
<ant dir="engine" target="create-zip-distribution"/>
<ant dir="sdk" target="hudson-stable"/>
</target>

@ -3,23 +3,27 @@ package com.jme3.renderer.android;
import android.opengl.GLES20;
import android.opengl.GLU;
import com.jme3.renderer.RendererException;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
/**
* Utility class used by the {@link OGLESShaderRenderer renderer} and sister classes.
*
* Utility class used by the {@link OGLESShaderRenderer renderer} and sister
* classes.
*
* @author Kirill Vainer
*/
public class RendererUtil {
/**
* When set to true, every OpenGL call will check for errors and throw
* an exception if there is one, if false, no error checking is performed.
* When set to true, every OpenGL call will check for errors and throw an
* exception if there is one, if false, no error checking is performed.
*/
public static boolean ENABLE_ERROR_CHECKING = true;
/**
* Checks for an OpenGL error and throws a {@link RendererException}
* if there is one. Ignores the value of {@link RendererUtil#ENABLE_ERROR_CHECKING}.
* Checks for an OpenGL error and throws a {@link RendererException} if
* there is one. Ignores the value of
* {@link RendererUtil#ENABLE_ERROR_CHECKING}.
*/
public static void checkGLErrorForced() {
int error = GLES20.glGetError();
@ -32,14 +36,86 @@ public class RendererUtil {
}
}
}
/**
* Checks for an EGL error and throws a {@link RendererException} if there
* is one. Ignores the value of {@link RendererUtil#ENABLE_ERROR_CHECKING}.
*/
public static void checkEGLError(EGL10 egl) {
int error = egl.eglGetError();
if (error != EGL10.EGL_SUCCESS) {
String errorMessage;
switch (error) {
case EGL10.EGL_SUCCESS:
return;
case EGL10.EGL_NOT_INITIALIZED:
errorMessage = "EGL is not initialized, or could not be "
+ "initialized, for the specified EGL display connection. ";
break;
case EGL10.EGL_BAD_ACCESS:
errorMessage = "EGL cannot access a requested resource "
+ "(for example a context is bound in another thread). ";
break;
case EGL10.EGL_BAD_ALLOC:
errorMessage = "EGL failed to allocate resources for the requested operation.";
break;
case EGL10.EGL_BAD_ATTRIBUTE:
errorMessage = "An unrecognized attribute or attribute "
+ "value was passed in the attribute list. ";
break;
case EGL10.EGL_BAD_CONTEXT:
errorMessage = "An EGLContext argument does not name a valid EGL rendering context. ";
break;
case EGL10.EGL_BAD_CONFIG:
errorMessage = "An EGLConfig argument does not name a valid EGL frame buffer configuration. ";
break;
case EGL10.EGL_BAD_CURRENT_SURFACE:
errorMessage = "The current surface of the calling thread "
+ "is a window, pixel buffer or pixmap that is no longer valid. ";
break;
case EGL10.EGL_BAD_DISPLAY:
errorMessage = "An EGLDisplay argument does not name a valid EGL display connection. ";
break;
case EGL10.EGL_BAD_SURFACE:
errorMessage = "An EGLSurface argument does not name a "
+ "valid surface (window, pixel buffer or pixmap) configured for GL rendering. ";
break;
case EGL10.EGL_BAD_MATCH:
errorMessage = "Arguments are inconsistent (for example, a "
+ "valid context requires buffers not supplied by a valid surface). ";
break;
case EGL10.EGL_BAD_PARAMETER:
errorMessage = "One or more argument values are invalid.";
break;
case EGL10.EGL_BAD_NATIVE_PIXMAP:
errorMessage = "A NativePixmapType argument does not refer to a valid native pixmap. ";
break;
case EGL10.EGL_BAD_NATIVE_WINDOW:
errorMessage = "A NativeWindowType argument does not refer to a valid native window. ";
break;
case EGL11.EGL_CONTEXT_LOST:
errorMessage = "A power management event has occurred. "
+ "The application must destroy all contexts and reinitialise "
+ "OpenGL ES state and objects to continue rendering. ";
break;
default:
errorMessage = "Unknown";
}
throw new RendererException("EGL error 0x" + Integer.toHexString(error) + ": " + errorMessage);
}
}
/**
* Checks for an OpenGL error and throws a {@link RendererException}
* if there is one. Does nothing if {@link RendererUtil#ENABLE_ERROR_CHECKING}
* is set to <code>false</code>.
* Checks for an OpenGL error and throws a {@link RendererException} if
* there is one. Does nothing if {@link RendererUtil#ENABLE_ERROR_CHECKING}
* is set to
* <code>false</code>.
*/
public static void checkGLError() {
if (!ENABLE_ERROR_CHECKING) return;
if (!ENABLE_ERROR_CHECKING) {
return;
}
int error = GLES20.glGetError();
if (error != 0) {
String message = GLU.gluErrorString(error);

@ -2,9 +2,8 @@ package com.jme3.system.android;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView.EGLConfigChooser;
import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.AppSettings;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGL10;
@ -20,9 +19,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
public final static String SETTINGS_CONFIG_TYPE = "configType";
protected int clientOpenGLESVersion = 0;
protected EGLConfig bestConfig = null;
protected EGLConfig fastestConfig = null;
protected EGLConfig choosenConfig = null;
protected AppSettings settings;
protected int pixelFormat;
@ -91,14 +87,30 @@ public class AndroidConfigChooser implements EGLConfigChooser {
this.settings = settings;
}
private static int eglGetConfigAttribSafe(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute) {
int[] value = new int[1];
if (!egl.eglGetConfigAttrib(display, config, attribute, value)) {
RendererUtil.checkEGLError(egl);
throw new AssertionError();
}
return value[0];
}
/**
* Gets called by the GLSurfaceView class to return the best config
*/
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
logger.fine("GLSurfaceView asks for egl config, returning: ");
logEGLConfig(choosenConfig, display, egl, Level.FINE);
return choosenConfig;
logger.fine("GLSurfaceView asking for egl config");
boolean configFound = findConfig(egl, display);
if (configFound) {
logger.fine("GLSurfaceView asks for egl config, returning: ");
logEGLConfig(choosenConfig, display, egl, Level.FINE);
return choosenConfig;
} else {
logger.fine("GLSurfaceView asks for egl config, No config found");
return null;
}
}
/**
@ -108,7 +120,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @return true if successfull, false if no config was found
*/
public boolean findConfig(EGL10 egl, EGLDisplay display) {
private boolean findConfig(EGL10 egl, EGLDisplay display) {
ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples());
@ -116,48 +128,46 @@ public class AndroidConfigChooser implements EGLConfigChooser {
logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name());
if (choosenConfig != null) {
// Remember the display for which we have the EGLConfig for
logger.info("JME3 using choosen config: ");
logEGLConfig(choosenConfig, display, egl, Level.INFO);
pixelFormat = getPixelFormat(choosenConfig, display, egl);
clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
return true;
} else {
logger.severe("ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this.");
clientOpenGLESVersion = 1;
pixelFormat = PixelFormat.UNKNOWN;
return false;
}
}
private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) {
int[] value = new int[1];
//Android Pixel format is not very well documented.
//From what i gathered, the format is chosen automatically except for the alpha channel
//if the alpha channel has 8 bit or more, e set the pixel format to Transluscent, as it allow transparent view background
//if it's 0 bit, the format is OPAQUE otherwise it's TRANSPARENT
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
if (value[0] >= 8) {
int result = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE);
if (result >= 8) {
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
return PixelFormat.TRANSLUCENT;
}
if (value[0] >= 1) {
if (result >= 1) {
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
return PixelFormat.TRANSPARENT;
}
logger.log(Level.FINE, "Pixel Format: OPAQUE");
return PixelFormat.OPAQUE;
}
private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) {
int[] value = new int[1];
int result = 1;
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
int val = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE);
// Check if conf is OpenGL ES 2.0
if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) {
result = 2;
if ((val & EGL_OPENGL_ES2_BIT) != 0) {
return 2;
} else {
return 1;
}
return result;
}
/**
@ -167,50 +177,37 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @param egl
*/
public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
int[] value = new int[1];
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
logger.log(level, String.format("EGL_RED_SIZE = %d", value[0]));
private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
logger.log(level, String.format("EGL_GREEN_SIZE = %d", value[0]));
logger.log(level, "EGL_RED_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RED_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
logger.log(level, String.format("EGL_BLUE_SIZE = %d", value[0]));
logger.log(level, "EGL_GREEN_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_GREEN_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
logger.log(level, String.format("EGL_ALPHA_SIZE = %d", value[0]));
logger.log(level, "EGL_BLUE_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_BLUE_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
logger.log(level, String.format("EGL_DEPTH_SIZE = %d", value[0]));
logger.log(level, "EGL_ALPHA_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
logger.log(level, String.format("EGL_STENCIL_SIZE = %d", value[0]));
logger.log(level, "EGL_DEPTH_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_DEPTH_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
logger.log(level, String.format("EGL_RENDERABLE_TYPE = %d", value[0]));
logger.log(level, "EGL_STENCIL_SIZE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_STENCIL_SIZE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
logger.log(level, String.format("EGL_SURFACE_TYPE = %d", value[0]));
logger.log(level, "EGL_RENDERABLE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLE_BUFFERS, value);
logger.log(level, String.format("EGL_SAMPLE_BUFFERS = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLES, value);
logger.log(level, String.format("EGL_SAMPLES = %d", value[0]));
}
logger.log(level, "EGL_SURFACE_TYPE = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SURFACE_TYPE));
public int getClientOpenGLESVersion() {
return clientOpenGLESVersion;
}
public void setClientOpenGLESVersion(int clientOpenGLESVersion) {
this.clientOpenGLESVersion = clientOpenGLESVersion;
}
logger.log(level, "EGL_SAMPLE_BUFFERS = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLE_BUFFERS));
public int getPixelFormat() {
return pixelFormat;
logger.log(level, "EGL_SAMPLES = {0}",
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
}
private abstract class BaseConfigChooser implements EGLConfigChooser {
@ -226,11 +223,17 @@ public class AndroidConfigChooser implements EGLConfigChooser {
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE};
egl.eglChooseConfig(display, configSpec, null, 0, num_config);
if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) {
RendererUtil.checkEGLError(egl);
throw new AssertionError();
}
int numConfigs = num_config[0];
EGLConfig[] configs = new EGLConfig[numConfigs];
egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config);
if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config)) {
RendererUtil.checkEGLError(egl);
throw new AssertionError();
}
logger.fine("--------------Display Configurations---------------");
for (EGLConfig eGLConfig : configs) {
@ -252,12 +255,10 @@ public class AndroidConfigChooser implements EGLConfigChooser {
*/
private class ComponentSizeChooser extends BaseConfigChooser {
private int[] mValue;
private ConfigType configType;
protected int mSamples;
public ComponentSizeChooser(ConfigType configType, int samples) {
mValue = new int[1];
mSamples = samples;
this.configType = configType;
}
@ -272,22 +273,22 @@ public class AndroidConfigChooser implements EGLConfigChooser {
// first pass through config list. Try to find an exact match.
for (EGLConfig config : configs) {
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
int isMs = findConfigAttrib(egl, display, config,
EGL10.EGL_SAMPLE_BUFFERS, 0);
int nbMs = findConfigAttrib(egl, display, config,
EGL10.EGL_SAMPLES, 0);
int r = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_RED_SIZE);
int g = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_GREEN_SIZE);
int b = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_BLUE_SIZE);
int a = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_ALPHA_SIZE);
int d = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_DEPTH_SIZE);
int s = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_STENCIL_SIZE);
int isMs = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_SAMPLE_BUFFERS);
int nbMs = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_SAMPLES);
if (inRange(r, configType.mr, configType.r)
&& inRange(g, configType.mg, configType.g)
@ -344,13 +345,13 @@ public class AndroidConfigChooser implements EGLConfigChooser {
return keptConfig;
}
}
logger.log(Level.WARNING, "Failed to find a suitable display configuration for FASTEST, hoping for the best...");
// failsafe. pick the 1st config with a 16 bit depth buffer.
for (EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int d = eglGetConfigAttribSafe(egl, display, config,
EGL10.EGL_DEPTH_SIZE);
if (d >= 16) {
return config;
}
@ -363,15 +364,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private boolean inRange(int val, int min, int max) {
return min <= val && val <= max;
}
private int findConfigAttrib(EGL10 egl, EGLDisplay display,
EGLConfig config, int attribute, int defaultValue) {
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
return mValue[0];
}
return defaultValue;
}
}
//DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS.
// private static class Config {

@ -32,11 +32,15 @@
package com.jme3.system.android;
import android.app.Activity;
import com.jme3.renderer.android.AndroidGLSurfaceView;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ConfigurationInfo;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.ViewGroup.LayoutParams;
@ -48,16 +52,16 @@ import com.jme3.input.android.AndroidSensorJoyInput;
import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.AndroidGLSurfaceView;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.android.OGLESShaderRenderer;
import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.*;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
@ -91,7 +95,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
public Type getType() {
return Type.Display;
}
/**
* <code>createView</code> creates the GLSurfaceView that the renderer will
* draw to. <p> The result GLSurfaceView will receive input events and
@ -104,27 +108,27 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
* ConfigType.BEST
* @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view
* @deprecated AndroidGLSurfaceView createView()
* @deprecated AndroidGLSurfaceView createView()
* and put the configType in the appSettigs with the key AndroidConfigChoose.SETTINGS_CONFIG_TYPE
*/
@Deprecated
public AndroidGLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, configType);
return this.createView();
return this.createView();
}
/**
* <code>createView</code> creates the GLSurfaceView that the renderer will
* draw to. <p> The result GLSurfaceView will receive input events and
* forward them to the Application. Any rendering will be done into the
* GLSurfaceView. Only one GLSurfaceView can be created at this time. The
* given configType specifies how to determine the display configuration.
* given configType specifies how to determine the display configuration.
*
*
*
* @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view
*/
public AndroidGLSurfaceView createView() {
AndroidGLSurfaceView view;
AndroidGLSurfaceView view;
ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE);
// Start to set up the view
@ -135,60 +139,60 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
androidInput.setView(view);
androidInput.loadSettings(settings);
if (configType == ConfigType.LEGACY) {
// Hardcoded egl setup
clientOpenGLESVersion = 2;
view.setEGLContextClientVersion(2);
// RGB565, Depth16
view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
logger.fine("ConfigType.LEGACY using RGB565");
int rawOpenGLESVersion = getOpenGLESVersion();
logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}",
new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16});
if (rawOpenGLESVersion < 0x20000) {
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
} else {
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
if (egl.eglInitialize(display, version) == true) {
logger.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]});
}
try {
// Create a config chooser
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
// Init chooser
if (!configChooser.findConfig(egl, display)) {
listener.handleError("Unable to find suitable EGL config", null);
return null;
}
clientOpenGLESVersion = configChooser.getClientOpenGLESVersion();
if (clientOpenGLESVersion < 2) {
listener.handleError("OpenGL ES 2.0 is not supported on this device", null);
return null;
}
// Requesting client version from GLSurfaceView which is extended by
// AndroidInput.
view.setEGLContextClientVersion(clientOpenGLESVersion);
view.setEGLConfigChooser(configChooser);
view.getHolder().setFormat(configChooser.getPixelFormat());
} finally {
if (display != null) {
egl.eglTerminate(display);
}
}
clientOpenGLESVersion = 2;
view.setEGLContextClientVersion(clientOpenGLESVersion);
}
view.setFocusableInTouchMode(true);
view.setFocusable(true);
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
if (configType == ConfigType.BEST_TRANSLUCENT) {
//This is important to allow the GL surface to have a translucent background
// setFormat must be set before AndroidConfigChooser is called by the surfaceview.
// if setFormat is called after ConfigChooser is called, then execution
// stops at the setFormat call without a crash.
// We look at the user setting for alpha bits and set the surfaceview
// PixelFormat to either Opaque, Transparent, or Translucent.
// ConfigChooser will do it's best to honor the alpha requested by the user
// For best rendering performance, use Opaque (alpha bits = 0).
int alphaBits = configType.a;
logger.log(Level.FINE, "alphaBits: {0}", alphaBits);
if (alphaBits >= 8) {
logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
view.setZOrderOnTop(true);
} else if (alphaBits >= 1) {
logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
view.getHolder().setFormat(PixelFormat.TRANSPARENT);
} else {
logger.log(Level.FINE, "Pixel Format: OPAQUE");
view.getHolder().setFormat(PixelFormat.OPAQUE);
}
AndroidConfigChooser configChooser = new AndroidConfigChooser(settings);
view.setEGLConfigChooser(configChooser);
view.setRenderer(this);
return view;
}
/**
* Get the OpenGL ES version
* @return version returns the int value of the GLES version
*/
public int getOpenGLESVersion() {
ActivityManager am =
(ActivityManager) JmeAndroidSystem.getActivity().getApplication().getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
logger.log(Level.FINE, "OpenGL Version {0}:", info.getGlEsVersion());
return info.reqGlEsVersion;
// return (info.reqGlEsVersion >= 0x20000);
}
// renderer:initialize
@Override
@ -218,10 +222,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
}
});
if (clientOpenGLESVersion < 2) {
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
}
timer = new AndroidTimer();
renderer = new OGLESShaderRenderer();
@ -405,10 +405,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
}
}
public int getClientOpenGLESVersion() {
return clientOpenGLESVersion;
}
public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}",
new Object[]{title, initialValue});

@ -355,6 +355,9 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
//I remove the skeletonControl and readd it to the spatial to make sure it's after the ragdollControl in the stack
//Find a proper way to order the controls.
SkeletonControl sc = model.getControl(SkeletonControl.class);
if(sc == null){
throw new IllegalArgumentException("The root node of the model should have a SkeletonControl. Make sure the control is there and that it's not on a sub node.");
}
model.removeControl(sc);
model.addControl(sc);

@ -210,7 +210,7 @@ public class CollisionShapeFactory {
private static MeshCollisionShape createSingleMeshShape(Geometry geom, Spatial parent) {
Mesh mesh = geom.getMesh();
Transform trans = getTransform(geom, parent);
if (mesh != null) {
if (mesh != null && mesh.getMode() == Mesh.Mode.Triangles) {
MeshCollisionShape mColl = new MeshCollisionShape(mesh);
mColl.setScale(trans.getScale());
return mColl;

@ -211,11 +211,14 @@ void main(){
// ***********************
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);
vec3 normal = normalize((normalHeight.xyz * vec3(2.0) - vec3(1.0)));
//Note the -2.0 and -1.0. We invert the green channel of the normal map,
//as it's complient with normal maps generated with blender.
//see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
//for more explanation.
vec3 normal = normalize((normalHeight.xyz * vec3(2.0,-2.0,2.0) - vec3(1.0,-1.0,1.0)));
#ifdef LATC
normal.z = sqrt(1.0 - (normal.x * normal.x) - (normal.y * normal.y));
#endif
//normal.y = -normal.y;
#endif
#elif !defined(VERTEX_LIGHTING)
vec3 normal = vNormal;
#if !defined(LOW_QUALITY) && !defined(V_TANGENT)

@ -171,7 +171,7 @@ void main(){
vec3 wvTangent = normalize(g_NormalMatrix * modelSpaceTan);
vec3 wvBinormal = cross(wvNormal, wvTangent);
mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
//vPosition = wvPosition * tbnMat;
//vViewDir = viewDir * tbnMat;

@ -35,6 +35,10 @@ vec3 getPosition(in float depth, in vec2 uv){
}
void main(){
#if !defined( RENDER_SHADOWS )
gl_FragColor = texture2D(m_Texture,texCoord);
return;
#endif
float depth = texture2D(m_DepthTexture,texCoord).r;
vec4 color = texture2D(m_Texture,texCoord);

@ -57,6 +57,9 @@ MaterialDef Post Shadow {
FADE : FadeInfo
PSSM : Splits
POINTLIGHT : LightViewProjectionMatrix5
//if no shadow map don't render shadows
RENDER_SHADOWS : ShadowMap0
}
}

@ -87,6 +87,11 @@ vec4 main_multiSample(in int numSample){
void main(){
#if !defined( RENDER_SHADOWS )
outFragColor = fetchTextureSample(m_Texture,texCoord,0);
return;
#endif
#ifdef RESOLVE_MS
vec4 color = vec4(0.0);
for (int i = 0; i < m_NumSamples; i++){

@ -46,17 +46,17 @@ vec4 getDepth(in sampler2DMS tex,in vec2 texC){
#endif
vec4 fetchTextureSample(in sampler2D tex,in vec2 texC,in int sample){
return texture2D(tex,texC);
return texture(tex,texC);
}
vec4 getColor(in sampler2D tex, in vec2 texC){
return texture2D(tex,texC);
return texture(tex,texC);
}
vec4 getColorSingle(in sampler2D tex, in vec2 texC){
return texture2D(tex, texC);
return texture(tex, texC);
}
vec4 getDepth(in sampler2D tex,in vec2 texC){
return texture2D(tex,texC);
return texture(tex,texC);
}

@ -1,314 +1,329 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.post.filters;
import com.jme3.asset.AssetManager;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.post.Filter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.texture.Image.Format;
import java.io.IOException;
import java.util.ArrayList;
/**
* BloomFilter is used to make objects in the scene have a glow effect.<br>
* There are 2 mode : Scene and Objects.<br>
* Scene mode extracts the bright parts of the scene to make them glow<br>
* Object mode make objects glow according to their material's glowMap or their GlowColor<br>
* @see <a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:bloom_and_glow">advanced:bloom_and_glow</a> for more details
*
* @author Rémy Bouquet aka Nehon
*/
public class BloomFilter extends Filter {
/**
* GlowMode specifies if the glow will be applied to the whole scene,or to objects that have aglow color or a glow map
*/
public enum GlowMode {
/**
* Apply bloom filter to bright areas in the scene.
*/
Scene,
/**
* Apply bloom only to objects that have a glow map or a glow color.
*/
Objects,
/**
* Apply bloom to both bright parts of the scene and objects with glow map.
*/
SceneAndObjects;
}
private GlowMode glowMode = GlowMode.Scene;
//Bloom parameters
private float blurScale = 1.5f;
private float exposurePower = 5.0f;
private float exposureCutOff = 0.0f;
private float bloomIntensity = 2.0f;
private float downSamplingFactor = 1;
private Pass preGlowPass;
private Pass extractPass;
private Pass horizontalBlur = new Pass();
private Pass verticalalBlur = new Pass();
private Material extractMat;
private Material vBlurMat;
private Material hBlurMat;
private int screenWidth;
private int screenHeight;
private RenderManager renderManager;
private ViewPort viewPort;
/**
* Creates a Bloom filter
*/
public BloomFilter() {
super("BloomFilter");
}
/**
* Creates the bloom filter with the specific glow mode
* @param glowMode
*/
public BloomFilter(GlowMode glowMode) {
this();
this.glowMode = glowMode;
}
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
this.renderManager = renderManager;
this.viewPort = vp;
screenWidth = (int) Math.max(1, (w / downSamplingFactor));
screenHeight = (int) Math.max(1, (h / downSamplingFactor));
// System.out.println(screenWidth + " " + screenHeight);
if (glowMode != GlowMode.Scene) {
preGlowPass = new Pass();
preGlowPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
}
postRenderPasses = new ArrayList<Pass>();
//configuring extractPass
extractMat = new Material(manager, "Common/MatDefs/Post/BloomExtract.j3md");
extractPass = new Pass() {
@Override
public boolean requiresSceneAsTexture() {
return true;
}
@Override
public void beforeRender() {
extractMat.setFloat("ExposurePow", exposurePower);
extractMat.setFloat("ExposureCutoff", exposureCutOff);
if (glowMode != GlowMode.Scene) {
extractMat.setTexture("GlowMap", preGlowPass.getRenderedTexture());
}
extractMat.setBoolean("Extract", glowMode != GlowMode.Objects);
}
};
extractPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, extractMat);
postRenderPasses.add(extractPass);
//configuring horizontal blur pass
hBlurMat = new Material(manager, "Common/MatDefs/Blur/HGaussianBlur.j3md");
horizontalBlur = new Pass() {
@Override
public void beforeRender() {
hBlurMat.setTexture("Texture", extractPass.getRenderedTexture());
hBlurMat.setFloat("Size", screenWidth);
hBlurMat.setFloat("Scale", blurScale);
}
};
horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
postRenderPasses.add(horizontalBlur);
//configuring vertical blur pass
vBlurMat = new Material(manager, "Common/MatDefs/Blur/VGaussianBlur.j3md");
verticalalBlur = new Pass() {
@Override
public void beforeRender() {
vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
vBlurMat.setFloat("Size", screenHeight);
vBlurMat.setFloat("Scale", blurScale);
}
};
verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
postRenderPasses.add(verticalalBlur);
//final material
material = new Material(manager, "Common/MatDefs/Post/BloomFinal.j3md");
material.setTexture("BloomTex", verticalalBlur.getRenderedTexture());
}
@Override
protected Material getMaterial() {
material.setFloat("BloomIntensity", bloomIntensity);
return material;
}
@Override
protected void postQueue(RenderQueue queue) {
if (glowMode != GlowMode.Scene) {
renderManager.getRenderer().setBackgroundColor(ColorRGBA.BlackNoAlpha);
renderManager.getRenderer().setFrameBuffer(preGlowPass.getRenderFrameBuffer());
renderManager.getRenderer().clearBuffers(true, true, true);
renderManager.setForcedTechnique("Glow");
renderManager.renderViewPortQueues(viewPort, false);
renderManager.setForcedTechnique(null);
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
}
}
/**
* returns the bloom intensity
* @return
*/
public float getBloomIntensity() {
return bloomIntensity;
}
/**
* intensity of the bloom effect default is 2.0
* @param bloomIntensity
*/
public void setBloomIntensity(float bloomIntensity) {
this.bloomIntensity = bloomIntensity;
}
/**
* returns the blur scale
* @return
*/
public float getBlurScale() {
return blurScale;
}
/**
* sets The spread of the bloom default is 1.5f
* @param blurScale
*/
public void setBlurScale(float blurScale) {
this.blurScale = blurScale;
}
/**
* returns the exposure cutoff<br>
* for more details see {@link #setExposureCutOff(float exposureCutOff)}
* @return
*/
public float getExposureCutOff() {
return exposureCutOff;
}
/**
* Define the color threshold on which the bloom will be applied (0.0 to 1.0)
* @param exposureCutOff
*/
public void setExposureCutOff(float exposureCutOff) {
this.exposureCutOff = exposureCutOff;
}
/**
* returns the exposure power<br>
* form more details see {@link #setExposurePower(float exposurePower)}
* @return
*/
public float getExposurePower() {
return exposurePower;
}
/**
* defines how many time the bloom extracted color will be multiplied by itself. default id 5.0<br>
* a high value will reduce rough edges in the bloom and somhow the range of the bloom area *
* @param exposurePower
*/
public void setExposurePower(float exposurePower) {
this.exposurePower = exposurePower;
}
/**
* returns the downSampling factor<br>
* form more details see {@link #setDownSamplingFactor(float downSamplingFactor)}
* @return
*/
public float getDownSamplingFactor() {
return downSamplingFactor;
}
/**
* Sets the downSampling factor : the size of the computed texture will be divided by this factor. default is 1 for no downsampling
* A 2 value is a good way of widening the blur
* @param downSamplingFactor
*/
public void setDownSamplingFactor(float downSamplingFactor) {
this.downSamplingFactor = downSamplingFactor;
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(glowMode, "glowMode", GlowMode.Scene);
oc.write(blurScale, "blurScale", 1.5f);
oc.write(exposurePower, "exposurePower", 5.0f);
oc.write(exposureCutOff, "exposureCutOff", 0.0f);
oc.write(bloomIntensity, "bloomIntensity", 2.0f);
oc.write(downSamplingFactor, "downSamplingFactor", 1);
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
glowMode = ic.readEnum("glowMode", GlowMode.class, GlowMode.Scene);
blurScale = ic.readFloat("blurScale", 1.5f);
exposurePower = ic.readFloat("exposurePower", 5.0f);
exposureCutOff = ic.readFloat("exposureCutOff", 0.0f);
bloomIntensity = ic.readFloat("bloomIntensity", 2.0f);
downSamplingFactor = ic.readFloat("downSamplingFactor", 1);
}
}
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.post.filters;
import com.jme3.asset.AssetManager;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.post.Filter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.texture.Image.Format;
import java.io.IOException;
import java.util.ArrayList;
/**
* BloomFilter is used to make objects in the scene have a glow effect.<br>
* There are 2 mode : Scene and Objects.<br>
* Scene mode extracts the bright parts of the scene to make them glow<br>
* Object mode make objects glow according to their material's glowMap or their GlowColor<br>
* @see <a href="http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:bloom_and_glow">advanced:bloom_and_glow</a> for more details
*
* @author Rémy Bouquet aka Nehon
*/
public class BloomFilter extends Filter {
/**
* GlowMode specifies if the glow will be applied to the whole scene,or to objects that have aglow color or a glow map
*/
public enum GlowMode {
/**
* Apply bloom filter to bright areas in the scene.
*/
Scene,
/**
* Apply bloom only to objects that have a glow map or a glow color.
*/
Objects,
/**
* Apply bloom to both bright parts of the scene and objects with glow map.
*/
SceneAndObjects;
}
private GlowMode glowMode = GlowMode.Scene;
//Bloom parameters
private float blurScale = 1.5f;
private float exposurePower = 5.0f;
private float exposureCutOff = 0.0f;
private float bloomIntensity = 2.0f;
private float downSamplingFactor = 1;
private Pass preGlowPass;
private Pass extractPass;
private Pass horizontalBlur = new Pass();
private Pass verticalalBlur = new Pass();
private Material extractMat;
private Material vBlurMat;
private Material hBlurMat;
private int screenWidth;
private int screenHeight;
private RenderManager renderManager;
private ViewPort viewPort;
private AssetManager assetManager;
private int initalWidth;
private int initalHeight;
/**
* Creates a Bloom filter
*/
public BloomFilter() {
super("BloomFilter");
}
/**
* Creates the bloom filter with the specific glow mode
* @param glowMode
*/
public BloomFilter(GlowMode glowMode) {
this();
this.glowMode = glowMode;
}
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
this.renderManager = renderManager;
this.viewPort = vp;
this.assetManager = manager;
this.initalWidth = w;
this.initalHeight = h;
screenWidth = (int) Math.max(1, (w / downSamplingFactor));
screenHeight = (int) Math.max(1, (h / downSamplingFactor));
// System.out.println(screenWidth + " " + screenHeight);
if (glowMode != GlowMode.Scene) {
preGlowPass = new Pass();
preGlowPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
}
postRenderPasses = new ArrayList<Pass>();
//configuring extractPass
extractMat = new Material(manager, "Common/MatDefs/Post/BloomExtract.j3md");
extractPass = new Pass() {
@Override
public boolean requiresSceneAsTexture() {
return true;
}
@Override
public void beforeRender() {
extractMat.setFloat("ExposurePow", exposurePower);
extractMat.setFloat("ExposureCutoff", exposureCutOff);
if (glowMode != GlowMode.Scene) {
extractMat.setTexture("GlowMap", preGlowPass.getRenderedTexture());
}
extractMat.setBoolean("Extract", glowMode != GlowMode.Objects);
}
};
extractPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, extractMat);
postRenderPasses.add(extractPass);
//configuring horizontal blur pass
hBlurMat = new Material(manager, "Common/MatDefs/Blur/HGaussianBlur.j3md");
horizontalBlur = new Pass() {
@Override
public void beforeRender() {
hBlurMat.setTexture("Texture", extractPass.getRenderedTexture());
hBlurMat.setFloat("Size", screenWidth);
hBlurMat.setFloat("Scale", blurScale);
}
};
horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
postRenderPasses.add(horizontalBlur);
//configuring vertical blur pass
vBlurMat = new Material(manager, "Common/MatDefs/Blur/VGaussianBlur.j3md");
verticalalBlur = new Pass() {
@Override
public void beforeRender() {
vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
vBlurMat.setFloat("Size", screenHeight);
vBlurMat.setFloat("Scale", blurScale);
}
};
verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
postRenderPasses.add(verticalalBlur);
//final material
material = new Material(manager, "Common/MatDefs/Post/BloomFinal.j3md");
material.setTexture("BloomTex", verticalalBlur.getRenderedTexture());
}
protected void reInitFilter() {
initFilter(assetManager, renderManager, viewPort, initalWidth, initalHeight);
}
@Override
protected Material getMaterial() {
material.setFloat("BloomIntensity", bloomIntensity);
return material;
}
@Override
protected void postQueue(RenderQueue queue) {
if (glowMode != GlowMode.Scene) {
renderManager.getRenderer().setBackgroundColor(ColorRGBA.BlackNoAlpha);
renderManager.getRenderer().setFrameBuffer(preGlowPass.getRenderFrameBuffer());
renderManager.getRenderer().clearBuffers(true, true, true);
renderManager.setForcedTechnique("Glow");
renderManager.renderViewPortQueues(viewPort, false);
renderManager.setForcedTechnique(null);
renderManager.getRenderer().setFrameBuffer(viewPort.getOutputFrameBuffer());
}
}
/**
* returns the bloom intensity
* @return
*/
public float getBloomIntensity() {
return bloomIntensity;
}
/**
* intensity of the bloom effect default is 2.0
* @param bloomIntensity
*/
public void setBloomIntensity(float bloomIntensity) {
this.bloomIntensity = bloomIntensity;
}
/**
* returns the blur scale
* @return
*/
public float getBlurScale() {
return blurScale;
}
/**
* sets The spread of the bloom default is 1.5f
* @param blurScale
*/
public void setBlurScale(float blurScale) {
this.blurScale = blurScale;
}
/**
* returns the exposure cutoff<br>
* for more details see {@link #setExposureCutOff(float exposureCutOff)}
* @return
*/
public float getExposureCutOff() {
return exposureCutOff;
}
/**
* Define the color threshold on which the bloom will be applied (0.0 to 1.0)
* @param exposureCutOff
*/
public void setExposureCutOff(float exposureCutOff) {
this.exposureCutOff = exposureCutOff;
}
/**
* returns the exposure power<br>
* form more details see {@link #setExposurePower(float exposurePower)}
* @return
*/
public float getExposurePower() {
return exposurePower;
}
/**
* defines how many time the bloom extracted color will be multiplied by itself. default id 5.0<br>
* a high value will reduce rough edges in the bloom and somhow the range of the bloom area *
* @param exposurePower
*/
public void setExposurePower(float exposurePower) {
this.exposurePower = exposurePower;
}
/**
* returns the downSampling factor<br>
* form more details see {@link #setDownSamplingFactor(float downSamplingFactor)}
* @return
*/
public float getDownSamplingFactor() {
return downSamplingFactor;
}
/**
* Sets the downSampling factor : the size of the computed texture will be divided by this factor. default is 1 for no downsampling
* A 2 value is a good way of widening the blur
* @param downSamplingFactor
*/
public void setDownSamplingFactor(float downSamplingFactor) {
this.downSamplingFactor = downSamplingFactor;
if (assetManager != null) // dirty isInitialised check
reInitFilter();
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(glowMode, "glowMode", GlowMode.Scene);
oc.write(blurScale, "blurScale", 1.5f);
oc.write(exposurePower, "exposurePower", 5.0f);
oc.write(exposureCutOff, "exposureCutOff", 0.0f);
oc.write(bloomIntensity, "bloomIntensity", 2.0f);
oc.write(downSamplingFactor, "downSamplingFactor", 1);
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
glowMode = ic.readEnum("glowMode", GlowMode.class, GlowMode.Scene);
blurScale = ic.readFloat("blurScale", 1.5f);
exposurePower = ic.readFloat("exposurePower", 5.0f);
exposureCutOff = ic.readFloat("exposureCutOff", 0.0f);
bloomIntensity = ic.readFloat("bloomIntensity", 2.0f);
downSamplingFactor = ic.readFloat("downSamplingFactor", 1);
}
}

@ -37,6 +37,7 @@ import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.post.Filter;
import com.jme3.renderer.Camera;
@ -102,7 +103,9 @@ public class LightScatteringFilter extends Filter {
getClipCoordinates(lightPosition, screenLightPos, viewPort.getCamera());
viewPort.getCamera().getViewMatrix().mult(lightPosition, viewLightPos);
if (adaptative) {
innerLightDensity = Math.max(lightDensity - Math.max(screenLightPos.x, screenLightPos.y), 0.0f);
float densityX = 1f - FastMath.clamp(FastMath.abs(screenLightPos.x - 0.5f), 0, 1);
float densityY = 1f - FastMath.clamp(FastMath.abs(screenLightPos.y - 0.5f), 0, 1);
innerLightDensity = lightDensity * densityX * densityY;
} else {
innerLightDensity = lightDensity;
}

@ -48,6 +48,7 @@ import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.texture.Texture2D;
import com.jme3.ui.Picture;
import com.jme3.util.TempVars;
/**
*
@ -119,15 +120,12 @@ public class SimpleWaterProcessor implements SceneProcessor {
private Plane reflectionClipPlane;
private Plane refractionClipPlane;
private float refractionClippingOffset = 0.3f;
private float reflectionClippingOffset = -5f;
private Vector3f vect1 = new Vector3f();
private Vector3f vect2 = new Vector3f();
private Vector3f vect3 = new Vector3f();
private float reflectionClippingOffset = -5f;
private float distortionScale = 0.2f;
private float distortionMix = 0.5f;
private float texScale = 1f;
/**
* Creates a SimpleWaterProcessor
* @param manager the asset manager
@ -190,10 +188,6 @@ public class SimpleWaterProcessor implements SceneProcessor {
public void postQueue(RenderQueue rq) {
Camera sceneCam = rm.getCurrentCamera();
//update ray
ray.setOrigin(sceneCam.getLocation());
ray.setDirection(sceneCam.getDirection());
//update refraction cam
refractionCam.setLocation(sceneCam.getLocation());
refractionCam.setRotation(sceneCam.getRotation());
@ -203,40 +197,11 @@ public class SimpleWaterProcessor implements SceneProcessor {
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
refractionCam.setParallelProjection(false);
refractionCam.setParallelProjection(sceneCam.isParallelProjection());
//update reflection cam
boolean inv = false;
if (!ray.intersectsWherePlane(plane, targetLocation)) {
ray.setDirection(ray.getDirection().negateLocal());
ray.intersectsWherePlane(plane, targetLocation);
inv = true;
}
Vector3f loc = plane.reflect(sceneCam.getLocation(), new Vector3f());
reflectionCam.setLocation(loc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(false);
// tempVec and calcVect are just temporary vector3f objects
vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
float planeDistance = plane.pseudoDistance(vect1);
vect2.set(plane.getNormal()).multLocal(planeDistance * 2.0f);
vect3.set(vect1.subtractLocal(vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
// now set the up vector
reflectionCam.lookAt(targetLocation, vect3);
if (inv) {
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
}
//we are rendering a sub part of the scene so the camera planeState may never be reseted to 0.
// reflectionCam.setPlaneState(0);
// refractionCam.setPlaneState(0);
WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam);
//Rendering reflection and refraction
rm.renderViewPort(reflectionView, savedTpf);
rm.renderViewPort(refractionView, savedTpf);

@ -155,40 +155,11 @@ public class WaterFilter extends Filter {
material.setFloat("WaterHeight", waterHeight);
//update reflection cam
ray.setOrigin(sceneCam.getLocation());
ray.setDirection(sceneCam.getDirection());
//update reflection cam
plane = new Plane(Vector3f.UNIT_Y, new Vector3f(0, waterHeight, 0).dot(Vector3f.UNIT_Y));
reflectionProcessor.setReflectionClipPlane(plane);
boolean inv = false;
if (!ray.intersectsWherePlane(plane, targetLocation)) {
ray.setDirection(ray.getDirection().negateLocal());
ray.intersectsWherePlane(plane, targetLocation);
inv = true;
}
Vector3f loc = plane.reflect(sceneCam.getLocation(), new Vector3f());
reflectionCam.setLocation(loc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(false);
TempVars vars = TempVars.get();
vars.vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
float planeDistance = plane.pseudoDistance(vars.vect1);
vars.vect2.set(plane.getNormal()).multLocal(planeDistance * 2.0f);
vars.vect3.set(vars.vect1.subtractLocal(vars.vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
reflectionCam.lookAt(targetLocation, vars.vect3);
vars.release();
if (inv) {
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
}
reflectionProcessor.setReflectionClipPlane(plane);
WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam);
//if we're under water no need to compute reflection
if (sceneCam.getLocation().y >= waterHeight) {
@ -1026,7 +997,7 @@ public class WaterFilter extends Filter {
public void setReflectionDisplace(float reflectionDisplace) {
this.reflectionDisplace = reflectionDisplace;
if (material != null) {
material.setFloat("m_ReflectionDisplace", reflectionDisplace);
material.setFloat("ReflectionDisplace", reflectionDisplace);
}
}

@ -0,0 +1,53 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.water;
import com.jme3.math.Plane;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.util.TempVars;
/**
*
* @author Nehon
*/
public class WaterUtils {
public static void updateReflectionCam(Camera reflectionCam, Plane plane, Camera sceneCam){
TempVars vars = TempVars.get();
//Temp vects for reflection cam orientation calculation
Vector3f sceneTarget = vars.vect1;
Vector3f reflectDirection = vars.vect2;
Vector3f reflectUp = vars.vect3;
Vector3f reflectLeft = vars.vect4;
Vector3f camLoc = vars.vect5;
camLoc = plane.reflect(sceneCam.getLocation(), camLoc);
reflectionCam.setLocation(camLoc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(sceneCam.isParallelProjection());
sceneTarget.set(sceneCam.getLocation()).addLocal(sceneCam.getDirection());
reflectDirection = plane.reflect(sceneTarget, reflectDirection);
reflectDirection.subtractLocal(camLoc);
sceneTarget.set(sceneCam.getLocation()).subtractLocal(sceneCam.getUp());
reflectUp = plane.reflect(sceneTarget, reflectUp);
reflectUp.subtractLocal(camLoc);
sceneTarget.set(sceneCam.getLocation()).addLocal(sceneCam.getLeft());
reflectLeft = plane.reflect(sceneTarget, reflectLeft);
reflectLeft.subtractLocal(camLoc);
reflectionCam.setAxes(reflectLeft, reflectUp, reflectDirection);
vars.release();
}
}

@ -327,14 +327,18 @@ public class BinaryExporter implements JmeExporter {
public boolean save(Savable object, File f) throws IOException {
File parentDirectory = f.getParentFile();
if(parentDirectory != null && !parentDirectory.exists()) {
if (parentDirectory != null && !parentDirectory.exists()) {
parentDirectory.mkdirs();
}
FileOutputStream fos = new FileOutputStream(f);
boolean rVal = save(object, fos);
fos.close();
return rVal;
try {
return save(object, fos);
} finally {
if (fos != null) {
fos.close();
}
}
}
public BinaryOutputCapsule getCapsule(Savable object) {

@ -267,9 +267,13 @@ public final class BinaryImporter implements JmeImporter {
public Savable load(File f, ReadListener listener) throws IOException {
FileInputStream fis = new FileInputStream(f);
Savable rVal = load(fis, listener);
fis.close();
return rVal;
try {
return load(fis, listener);
} finally {
if (fis != null) {
fis.close();
}
}
}
public Savable load(byte[] data) throws IOException {

@ -43,23 +43,22 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
public class BitmapFontLoader implements AssetLoader {
private BitmapFont load(AssetManager assetManager, String folder, InputStream in) throws IOException{
MaterialDef spriteMat =
(MaterialDef) assetManager.loadAsset(new AssetKey("Common/MatDefs/Misc/Unshaded.j3md"));
BitmapCharacterSet charSet = new BitmapCharacterSet();
Material[] matPages = null;
BitmapFont font = new BitmapFont();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String regex = "[\\s=]+";
String regex = "[\\s=]+";
font.setCharSet(charSet);
while (reader.ready()){
String line = reader.readLine();
String line;
while ((line = reader.readLine())!=null){
String[] tokens = line.split(regex);
if (tokens[0].equals("info")){
// Get rendered size

@ -82,8 +82,8 @@ public class GLSLLoader implements AssetLoader {
StringBuilder sb = new StringBuilder();
BufferedReader bufReader = new BufferedReader(reader);
try {
while (bufReader.ready()) {
String ln = bufReader.readLine();
String ln;
while ((ln = bufReader.readLine()) != null) {
if (ln.trim().startsWith("#import ")) {
ln = ln.trim().substring(8).trim();
if (ln.startsWith("\"") && ln.endsWith("\"") && ln.length() > 3) {

@ -59,6 +59,7 @@ public final class AnimChannel {
private float time;
private float speed;
private float timeBlendFrom;
private float blendTime;
private float speedBlendFrom;
private boolean notified=false;
@ -192,6 +193,11 @@ public final class AnimChannel {
*/
public void setSpeed(float speed) {
this.speed = speed;
if(blendTime>0){
this.speedBlendFrom = speed;
blendTime = Math.min(blendTime, animation.getLength() / speed);
blendRate = 1/ blendTime;
}
}
/**
@ -248,7 +254,9 @@ public final class AnimChannel {
control.notifyAnimChange(this, name);
if (animation != null && blendTime > 0f){
this.blendTime = blendTime;
// activate blending
blendTime = Math.min(blendTime, anim.getLength() / speed);
blendFrom = animation;
timeBlendFrom = time;
speedBlendFrom = speed;
@ -394,7 +402,6 @@ public final class AnimChannel {
animation.setTime(time, blendAmount, control, this, vars);
time += tpf * speed;
if (animation.getLength() > 0){
if (!notified && (time >= animation.getLength() || time < 0)) {
if (loopMode == LoopMode.DontLoop) {
@ -406,7 +413,6 @@ public final class AnimChannel {
control.notifyAnimCycleDone(this, animation.getName());
}
}
time = clampWrapTime(time, animation.getLength(), loopMode);
if (time < 0){
// Negative time indicates that speed should be inverted

@ -87,7 +87,9 @@ public class FlyCamAppState extends AbstractAppState {
public void cleanup() {
super.cleanup();
flyCam.unregisterInput();
if (app.getInputManager() != null) {
flyCam.unregisterInput();
}
}

@ -81,7 +81,7 @@ public class StatsAppState extends AbstractAppState {
* is because several applications expect to directly access
* fpsText... unfortunately.
*/
void setFont( BitmapFont guiFont ) {
public void setFont( BitmapFont guiFont ) {
this.guiFont = guiFont;
this.fpsText = new BitmapText(guiFont, false);
}

@ -45,15 +45,18 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* An <code>AudioNode</code> is used in jME3 for playing audio files.
* <br/>
* First, an {@link AudioNode} is loaded from file, and then assigned
* to an audio node for playback. Once the audio node is attached to the
* scene, its location will influence the position it is playing from relative
* to the {@link Listener}.
* <br/>
* An audio node can also play in "headspace", meaning its location
* or velocity does not influence how it is played.
* An <code>AudioNode</code> is a scene Node which can play audio assets.
*
* An AudioNode is either positional or ambient, with positional being the
* default. Once a positional node is attached to the scene, its location and
* velocity relative to the {@link Listener} affect how it sounds when played.
* Positional nodes can only play monoaural (single-channel) assets, not stereo
* ones.
*
* An ambient AudioNode plays in "headspace", meaning that the node's location
* and velocity do not affect how it sounds when played. Ambient audio nodes can
* play stereo assets.
*
* The "positional" property of an AudioNode can be set via
* {@link AudioNode#setPositional(boolean) }.
*

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2013 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -47,31 +47,40 @@ import java.nio.FloatBuffer;
//import com.jme.scene.TriMesh;
/**
* <code>BoundingBox</code> defines an axis-aligned cube that defines a
* container for a group of vertices of a particular piece of geometry. This box
* defines a center and extents from that center along the x, y and z axis. <br>
* <code>BoundingBox</code> describes a bounding volume as an axis-aligned box.
* <br>
* A typical usage is to allow the class define the center and radius by calling
* either <code>containAABB</code> or <code>averagePoints</code>. A call to
* <code>computeFramePoint</code> in turn calls <code>containAABB</code>.
*
* Instances may be initialized by invoking the <code>containAABB</code> method.
*
* @author Joshua Slack
* @version $Id: BoundingBox.java,v 1.50 2007/09/22 16:46:35 irrisor Exp $
*/
public class BoundingBox extends BoundingVolume {
float xExtent, yExtent, zExtent;
/**
* Default constructor instantiates a new <code>BoundingBox</code>
* object.
* the X-extent of the box (>=0, may be +Infinity)
*/
float xExtent;
/**
* the Y-extent of the box (>=0, may be +Infinity)
*/
float yExtent;
/**
* the Z-extent of the box (>=0, may be +Infinity)
*/
float zExtent;
/**
* Instantiate a <code>BoundingBox</code> without initializing it.
*/
public BoundingBox() {
}
/**
* Contstructor instantiates a new <code>BoundingBox</code> object with
* given specs.
* Instantiate a <code>BoundingBox</code> with given center and extents.
*
* @param c the coordinates of the center of the box (not null, not altered)
* @param x the X-extent of the box (>=0, may be +Infinity)
* @param y the Y-extent of the box (>=0, may be +Infinity)
* @param z the Z-extent of the box (>=0, may be +Infinity)
*/
public BoundingBox(Vector3f c, float x, float y, float z) {
this.center.set(c);
@ -80,6 +89,11 @@ public class BoundingBox extends BoundingVolume {
this.zExtent = z;
}
/**
* Instantiate a <code>BoundingBox</code> equivalent to an existing box.
*
* @param source the existing box (not null, not altered)
*/
public BoundingBox(BoundingBox source) {
this.center.set(source.center);
this.xExtent = source.xExtent;
@ -368,52 +382,28 @@ public class BoundingBox extends BoundingVolume {
}
/**
* <code>merge</code> combines this bounding box with a second bounding box.
* This new box contains both bounding box and is returned.
*
* @param volume
* the bounding box to combine with this bounding box.
* @return the new bounding box
* <code>merge</code> combines this bounding box locally with a second
* bounding volume. The result contains both the original box and the second
* volume.
*
* @param volume the bounding volume to combine with this box (or null) (not
* altered)
* @return this box (with its components modified) or null if the second
* volume is of some type other than AABB or Sphere
*/
public BoundingVolume merge(BoundingVolume volume) {
if (volume == null) {
return this;
}
switch (volume.getType()) {
case AABB: {
BoundingBox vBox = (BoundingBox) volume;
return merge(vBox.center, vBox.xExtent, vBox.yExtent,
vBox.zExtent, new BoundingBox(new Vector3f(0, 0, 0), 0,
0, 0));
}
case Sphere: {
BoundingSphere vSphere = (BoundingSphere) volume;
return merge(vSphere.center, vSphere.radius, vSphere.radius,
vSphere.radius, new BoundingBox(new Vector3f(0, 0, 0),
0, 0, 0));
}
// case OBB: {
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
// BoundingBox rVal = (BoundingBox) this.clone(null);
// return rVal.mergeOBB(box);
// }
default:
return null;
}
return mergeLocal(volume);
}
/**
* <code>mergeLocal</code> combines this sphere with a second bounding
* sphere locally. Altering this sphere to contain both the original and the
* additional sphere volumes;
*
* @param volume
* the sphere to combine with this sphere.
* @return this
* <code>mergeLocal</code> combines this bounding box locally with a second
* bounding volume. The result contains both the original box and the second
* volume.
*
* @param volume the bounding volume to combine with this box (or null) (not
* altered)
* @return this box (with its components modified) or null if the second
* volume is of some type other than AABB or Sphere
*/
public BoundingVolume mergeLocal(BoundingVolume volume) {
if (volume == null) {
@ -421,17 +411,15 @@ public class BoundingBox extends BoundingVolume {
}
switch (volume.getType()) {
case AABB: {
case AABB:
BoundingBox vBox = (BoundingBox) volume;
return merge(vBox.center, vBox.xExtent, vBox.yExtent,
vBox.zExtent, this);
}
return mergeLocal(vBox.center, vBox.xExtent, vBox.yExtent,
vBox.zExtent);
case Sphere: {
case Sphere:
BoundingSphere vSphere = (BoundingSphere) volume;
return merge(vSphere.center, vSphere.radius, vSphere.radius,
vSphere.radius, this);
}
return mergeLocal(vSphere.center, vSphere.radius,
vSphere.radius, vSphere.radius);
// case OBB: {
// return mergeOBB((OrientedBoundingBox) volume);
@ -486,61 +474,68 @@ public class BoundingBox extends BoundingVolume {
// return this;
// }
/**
* <code>merge</code> combines this bounding box with another box which is
* defined by the center, x, y, z extents.
*
* @param boxCenter
* the center of the box to merge with
* @param boxX
* the x extent of the box to merge with.
* @param boxY
* the y extent of the box to merge with.
* @param boxZ
* the z extent of the box to merge with.
* @param rVal
* the resulting merged box.
* <code>mergeLocal</code> combines this bounding box locally with a second
* bounding box described by its center and extents.
*
* @param c the center of the second box (not null, not altered)
* @param x the X-extent of the second box
* @param y the Y-extent of the second box
* @param z the Z-extent of the second box
* @return the resulting merged box.
*/
private BoundingBox merge(Vector3f boxCenter, float boxX, float boxY,
float boxZ, BoundingBox rVal) {
TempVars vars = TempVars.get();
vars.vect1.x = center.x - xExtent;
if (vars.vect1.x > boxCenter.x - boxX) {
vars.vect1.x = boxCenter.x - boxX;
}
vars.vect1.y = center.y - yExtent;
if (vars.vect1.y > boxCenter.y - boxY) {
vars.vect1.y = boxCenter.y - boxY;
}
vars.vect1.z = center.z - zExtent;
if (vars.vect1.z > boxCenter.z - boxZ) {
vars.vect1.z = boxCenter.z - boxZ;
private BoundingBox mergeLocal(Vector3f c, float x, float y, float z) {
if (xExtent == Float.POSITIVE_INFINITY
|| x == Float.POSITIVE_INFINITY) {
center.x = 0;
xExtent = Float.POSITIVE_INFINITY;
} else {
float low = center.x - xExtent;
if (low > c.x - x) {
low = c.x - x;
}
float high = center.x + xExtent;
if (high < c.x + x) {
high = c.x + x;
}
center.x = (low + high) / 2;
xExtent = high - center.x;
}
vars.vect2.x = center.x + xExtent;
if (vars.vect2.x < boxCenter.x + boxX) {
vars.vect2.x = boxCenter.x + boxX;
}
vars.vect2.y = center.y + yExtent;
if (vars.vect2.y < boxCenter.y + boxY) {
vars.vect2.y = boxCenter.y + boxY;
}
vars.vect2.z = center.z + zExtent;
if (vars.vect2.z < boxCenter.z + boxZ) {
vars.vect2.z = boxCenter.z + boxZ;
if (yExtent == Float.POSITIVE_INFINITY
|| y == Float.POSITIVE_INFINITY) {
center.y = 0;
yExtent = Float.POSITIVE_INFINITY;
} else {
float low = center.y - yExtent;
if (low > c.y - y) {
low = c.y - y;
}
float high = center.y + yExtent;
if (high < c.y + y) {
high = c.y + y;
}
center.y = (low + high) / 2;
yExtent = high - center.y;
}
center.set(vars.vect2).addLocal(vars.vect1).multLocal(0.5f);
xExtent = vars.vect2.x - center.x;
yExtent = vars.vect2.y - center.y;
zExtent = vars.vect2.z - center.z;
vars.release();
if (zExtent == Float.POSITIVE_INFINITY
|| z == Float.POSITIVE_INFINITY) {
center.z = 0;
zExtent = Float.POSITIVE_INFINITY;
} else {
float low = center.z - zExtent;
if (low > c.z - z) {
low = c.z - z;
}
float high = center.z + zExtent;
if (high < c.z + z) {
high = c.z + z;
}
center.z = (low + high) / 2;
zExtent = high - center.z;
}
return rVal;
return this;
}
/**
@ -570,8 +565,9 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>toString</code> returns the string representation of this object.
* The form is: "Radius: RRR.SSSS Center: <Vector>".
*
* The form is: "[Center: <Vector> xExtent: X.XX yExtent: Y.YY zExtent:
* Z.ZZ]".
*
* @return the string representation of this.
*/
@Override
@ -869,19 +865,55 @@ public class BoundingBox extends BoundingVolume {
// plane. Otherwise 'false' is returned in which case the line segment
// is entirely clipped.
if (denom > 0.0f) {
if (numer > denom * t[1]) {
// This is the old if statement...
// if (numer > denom * t[1]) {
//
// The problem is that what is actually stored is
// numer/denom. In non-floating point, this math should
// work out the same but in floating point there can
// be subtle math errors. The multiply will exaggerate
// errors that may have been introduced when the value
// was originally divided.
//
// This is especially true when the bounding box has zero
// extents in some plane because the error rate is critical.
// comparing a to b * c is not the same as comparing a/b to c
// in this case. In fact, I tried converting this method to
// double and the and the error was in the last decimal place.
//
// So, instead, we now compare the divided version to the divided
// version. We lose some slight performance here as divide
// will be more expensive than the divide. Some microbenchmarks
// show divide to be 3x slower than multiple on Java 1.6.
// BUT... we also saved a multiply in the non-clipped case because
// we can reuse the divided version in both if checks.
// I think it's better to be right in this case.
//
// Bug that I'm fixing: rays going right through quads at certain
// angles and distances because they fail the bounding box test.
// Many Bothans died bring you this fix.
// -pspeed
float newT = numer / denom;
if (newT > t[1]) {
return false;
}
if (numer > denom * t[0]) {
t[0] = numer / denom;
if (newT > t[0]) {
t[0] = newT;
}
return true;
} else if (denom < 0.0f) {
if (numer > denom * t[0]) {
// Old if statement... see above
// if (numer > denom * t[0]) {
//
// Note though that denom is always negative in this block.
// When we move it over to the other side we have to flip
// the comparison. Algebra for the win.
float newT = numer / denom;
if (newT < t[0]) {
return false;
}
if (numer > denom * t[1]) {
t[1] = numer / denom;
if (newT < t[1]) {
t[1] = newT;
}
return true;
} else {
@ -985,4 +1017,4 @@ public class BoundingBox extends BoundingVolume {
public float getVolume() {
return (8 * xExtent * yExtent * zExtent);
}
}
}

@ -44,34 +44,35 @@ import java.util.ArrayList;
import java.util.List;
/**
* This calls contains basic behavior of a cinematic event
* every cinematic event must extend this class
* This call contains the basic behaviour of a cinematic event.
* Every cinematic event must extend this class.
*
* A cinematic event must be given an inital duration in seconds (duration of the event at speed = 1) (default is 10)
* A cinematic event must be given an inital duration in seconds
* (duration of the event at speed = 1). Default is 10 sec.
* @author Nehon
*/
public abstract class AbstractCinematicEvent implements CinematicEvent {
protected PlayState playState = PlayState.Stopped;
protected float speed = 1;
protected float initialDuration = 10;
protected LoopMode loopMode = LoopMode.DontLoop;
protected float initialDuration = 10;
protected float speed = 1;
protected float time = 0;
protected boolean resuming = false;
/**
* the list of listeners
* The list of listeners.
*/
protected List<CinematicEventListener> listeners;
/**
* contruct a cinematic event
* Contruct a cinematic event (empty constructor).
*/
public AbstractCinematicEvent() {
}
/**
* contruct a cinematic event wwith the given initial duration
* Contruct a cinematic event with the given initial duration.
* @param initialDuration
*/
public AbstractCinematicEvent(float initialDuration) {
@ -79,7 +80,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* contruct a cinematic event with the given loopMode
* Contruct a cinematic event with the given loopMode.
* @param loopMode
*/
public AbstractCinematicEvent(LoopMode loopMode) {
@ -87,9 +88,9 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* contruct a cinematic event with the given loopMode and the given initialDuration
* @param initialDuration the duration of the event at speed = 1
* @param loopMode the loop mode of the event
* Contruct a cinematic event with the given loopMode and the given initialDuration.
* @param initialDuration the duration of the event at speed = 1.
* @param loopMode the loop mode of the event.
*/
public AbstractCinematicEvent(float initialDuration, LoopMode loopMode) {
this.initialDuration = initialDuration;
@ -97,17 +98,17 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* this method can be implemented if the event needs different handling when
* stopped naturally (when the event reach its end)
* or when it was forced stopped during playback
* otherwise it just call regular stop()
* Implement this method if the event needs different handling when
* stopped naturally (when the event reach its end),
* or when it was force-stopped during playback.
* By default, this method just calls regular stop().
*/
public void forceStop(){
stop();
}
/**
* Play this event
* Play this event.
*/
public void play() {
onPlay();
@ -121,13 +122,13 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Place here the code you want to execute when the event is started
* Implement this method with code that you want to execute when the event is started.
*/
protected abstract void onPlay();
/**
* should be used internally only
* @param tpf time per frame
* Used internally only.
* @param tpf time per frame.
*/
public void internalUpdate(float tpf) {
if (playState == PlayState.Playing) {
@ -135,7 +136,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
onUpdate(tpf);
if (time >= initialDuration && loopMode == LoopMode.DontLoop) {
stop();
}else if(time >= initialDuration && loopMode == LoopMode.Loop){
} else if(time >= initialDuration && loopMode == LoopMode.Loop){
setTime(0);
}
}
@ -143,13 +144,15 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Place here the code you want to execute on update (only called when the event is playing)
* Implement this method with the code that you want to execute on update
* (only called when the event is playing).
* @param tpf time per frame
*/
protected abstract void onUpdate(float tpf);
/**
* stops the animation, next time play() is called the animation will start from the begining.
* Stops the animation.
* Next time when play() is called, the animation starts from the beginning.
*/
public void stop() {
onStop();
@ -164,12 +167,13 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Place here the code you want to execute when the event is stoped.
* Implement this method with code that you want to execute when the event is stopped.
*/
protected abstract void onStop();
/**
* pause this event
* Pause this event.
* Next time when play() is called, the animation restarts from here.
*/
public void pause() {
onPause();
@ -183,12 +187,12 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* place here the code you want to execute when the event is paused
* Implement this method with code that you want to execute when the event is paused.
*/
public abstract void onPause();
/**
* returns the actual duration of the animtion (initialDuration/speed)
* Returns the actual duration of the animtion (initialDuration/speed)
* @return
*/
public float getDuration() {
@ -198,7 +202,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
/**
* Sets the speed of the animation.
* At speed = 1, the animation will last initialDuration seconds,
* At speed = 2 the animation will last initialDuraiton/2...
* At speed = 2, the animation will last initialDuration/2...
* @param speed
*/
public void setSpeed(float speed) {
@ -206,7 +210,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* returns the speed of the animation.
* Returns the speed of the animation.
* @return
*/
public float getSpeed() {
@ -214,7 +218,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Returns the current playstate of the animation
* Returns the current playstate of the animation (playing or paused or stopped).
* @return
*/
public PlayState getPlayState() {
@ -222,7 +226,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* returns the initial duration of the animation at speed = 1 in seconds.
* Returns the initial duration of the animation at speed = 1 in seconds.
* @return
*/
public float getInitialDuration() {
@ -230,7 +234,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Sets the duration of the antionamtion at speed = 1 in seconds
* Sets the duration of the animation at speed = 1 in seconds.
* @param initialDuration
*/
public void setInitialDuration(float initialDuration) {
@ -238,7 +242,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* retursthe loopMode of the animation
* Returns the loopMode of the animation.
* @see LoopMode
* @return
*/
@ -247,7 +251,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Sets the loopMode of the animation
* Sets the loopMode of the animation.
* @see LoopMode
* @param loopMode
*/
@ -256,7 +260,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* for serialization only
* Used for serialization only.
* @param ex exporter
* @throws IOException
*/
@ -269,7 +273,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* for serialization only
* Used for serialization only.
* @param im importer
* @throws IOException
*/
@ -282,7 +286,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* initialize this event (should be called internally only)
* Initialize this event (called internally only).
* @param app
* @param cinematic
*/
@ -290,7 +294,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* return a list of CinematicEventListener added on this event
* Returns the list of CinematicEventListeners added to this event.
* @return
*/
private List<CinematicEventListener> getListeners() {
@ -301,7 +305,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* Add a CinematicEventListener to this event
* Add a CinematicEventListener to this event.
* @param listener CinematicEventListener
*/
public void addListener(CinematicEventListener listener) {
@ -309,7 +313,7 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* remove a CinematicEventListener from this event
* Remove a CinematicEventListener from this event.
* @param listener CinematicEventListener
*/
public void removeListener(CinematicEventListener listener) {
@ -317,13 +321,16 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
}
/**
* When this method is invoked, the event should fast forward to the given time according tim 0 is the start of the event.
* @param time the time to fast forward to
* Fast-forward the event to the given timestamp. Time=0 is the start of the event.
* @param time the time to fast forward to.
*/
public void setTime(float time) {
this.time = time ;
}
/**
* Return the current timestamp of the event. Time=0 is the start of the event.
*/
public float getTime() {
return time;
}

@ -341,7 +341,11 @@ public class FlyByCamera implements AnalogListener, ActionListener {
float fovY = FastMath.atan(h / near)
/ (FastMath.DEG_TO_RAD * .5f);
fovY += value * 0.1f * zoomSpeed;
float newFovY = fovY + value * 0.1f * zoomSpeed;
if (newFovY > 0f) {
// Don't let the FOV go zero or negative.
fovY = newFovY;
}
h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f) * near;
w = h * aspect;

@ -602,6 +602,7 @@ public class InputManager implements RawInputListener {
if (mapping == null) {
//throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
logger.log(Level.WARNING, "Cannot find mapping to be removed, skipping: {0}", mappingName);
return;
}
ArrayList<Integer> triggers = mapping.triggers;

@ -149,7 +149,7 @@ public class KeyNames {
KEY_NAMES[KEY_BACK] = "Backspace";
KEY_NAMES[KEY_TAB] = "Tab";
KEY_NAMES[KEY_SYSRQ] = "SysEq";
KEY_NAMES[KEY_SYSRQ] = "SysRq";
KEY_NAMES[KEY_PAUSE] = "Pause";
KEY_NAMES[KEY_HOME] = "Home";

@ -69,8 +69,8 @@ public class DirectionalLight extends Light {
/**
* Sets the direction of the light.
* <p>
* Represents the vector direction the light is coming from.
* (1, 0, 0) would represent a directional light coming from the X axis.
* Represents the direction the light is shining.
* (1, 0, 0) would represent light shining in the +X direction.
*
* @param dir the direction of the light.
*/

@ -76,8 +76,7 @@ public class SpotLight extends Light implements Savable {
if(((int)packedAngleCos)== ((int)(outerCos*1000)) ){
outerCos -= 0.001f;
}
packedAngleCos+=outerCos;
System.out.println("anfle"+ packedAngleCos);
packedAngleCos+=outerCos;
}
@Override

@ -312,11 +312,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
}
} else {
if (renderFrameBufferMS != null) {
viewPort.setOutputFrameBuffer(renderFrameBufferMS);
} else {
viewPort.setOutputFrameBuffer(renderFrameBuffer);
}
setupViewPortFrameBuffer();
//init of the camera if it wasn't already
if (!cameraInit) {
viewPort.getCamera().resize(width, height, true);
@ -353,11 +349,20 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
for (int i = filters.size() - 1; i >= 0 && lastFilterIndex == -1; i--) {
if (filters.get(i).isEnabled()) {
lastFilterIndex = i;
//the Fpp is initialized, but the viwport framebuffer is the
//original out framebuffer so we must recover from a situation
//where no filter was enabled. So we set th correc framebuffer
//on the viewport
if(isInitialized() && viewPort.getOutputFrameBuffer()==outputBuffer){
setupViewPortFrameBuffer();
}
return;
}
}
if (lastFilterIndex == -1) {
cleanup();
if (isInitialized() && lastFilterIndex == -1) {
//There is no enabled filter, we restore the original framebuffer
//to the viewport to bypass the fpp.
viewPort.setOutputFrameBuffer(outputBuffer);
}
}
@ -441,12 +446,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
Filter filter = it.next();
initFilter(filter, vp);
}
if (renderFrameBufferMS != null) {
viewPort.setOutputFrameBuffer(renderFrameBufferMS);
} else {
viewPort.setOutputFrameBuffer(renderFrameBuffer);
}
setupViewPortFrameBuffer();
}
/**
@ -543,4 +543,12 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
public List<Filter> getFilterList(){
return Collections.unmodifiableList(filters);
}
private void setupViewPortFrameBuffer() {
if (renderFrameBufferMS != null) {
viewPort.setOutputFrameBuffer(renderFrameBufferMS);
} else {
viewPort.setOutputFrameBuffer(renderFrameBuffer);
}
}
}

@ -320,33 +320,33 @@ public class Camera implements Savable, Cloneable {
this.width = cam.width;
this.height = cam.height;
this.planeState = cam.planeState;
this.viewportChanged = cam.viewportChanged;
this.planeState = 0;
this.viewportChanged = true;
for (int i = 0; i < MAX_WORLD_PLANES; ++i) {
worldPlane[i].setNormal(cam.worldPlane[i].getNormal());
worldPlane[i].setConstant(cam.worldPlane[i].getConstant());
}
this.parallelProjection = cam.parallelProjection;
if(cam.projectionMatrixOverride != null) {
if(this.projectionMatrixOverride == null) {
this.projectionMatrixOverride = cam.projectionMatrixOverride.clone();
} else {
this.projectionMatrixOverride.set(cam.projectionMatrixOverride);
}
if (cam.projectionMatrixOverride != null) {
if (this.projectionMatrixOverride == null) {
this.projectionMatrixOverride = cam.projectionMatrixOverride.clone();
} else {
this.projectionMatrixOverride.set(cam.projectionMatrixOverride);
}
} else {
this.projectionMatrixOverride = null;
this.projectionMatrixOverride = null;
}
this.viewMatrix.set(cam.viewMatrix);
this.projectionMatrix.set(cam.projectionMatrix);
this.viewProjectionMatrix.set(cam.viewProjectionMatrix);
this.guiBounding.setXExtent(cam.guiBounding.getXExtent());
this.guiBounding.setYExtent(cam.guiBounding.getYExtent());
this.guiBounding.setZExtent(cam.guiBounding.getZExtent());
this.guiBounding.setCenter(cam.guiBounding.getCenter());
this.guiBounding.setCheckPlane(cam.guiBounding.getCheckPlane());
this.name = cam.name;
}

@ -55,10 +55,15 @@ public class RenderContext {
public boolean depthTestEnabled = false;
/**
* @see RenderState#setAlphaTest(boolean)
* @see RenderState#setAlphaFallOff(float)
*/
public float alphaTestFallOff = 0f;
/**
* @see RenderState#setAlphaTest(boolean)
*/
public boolean alphaTestEnabled = false;
/**
* @see RenderState#setDepthWrite(boolean)
*/

@ -754,4 +754,24 @@ public class BatchNode extends Node implements Savable {
public int getOffsetIndex(Geometry batchedGeometry) {
return batchedGeometry.startIndex;
}
@Override
public Node clone(boolean cloneMaterials) {
BatchNode clone = (BatchNode)super.clone(cloneMaterials);
if ( batches.size() > 0) {
for ( Batch b : batches ) {
for ( int i =0; i < clone.children.size(); i++ ) {
if ( clone.children.get(i).getName().equals(b.geometry.getName())) {
clone.children.remove(i);
break;
}
}
}
clone.needsFullRebatch = true;
clone.batches.clear();
clone.batchesByGeom.clear();
clone.batch();
}
return clone;
}
}

@ -240,8 +240,8 @@ public class Mesh implements Savable, Cloneable {
}
clone.vertexArrayID = -1;
clone.vertCount = -1;
clone.elementCount = -1;
clone.vertCount = vertCount;
clone.elementCount = elementCount;
// although this could change
// if the bone weight/index buffers are modified
@ -1166,7 +1166,9 @@ public class Mesh implements Savable, Cloneable {
// Now, create the vertex buffers
SafeArrayList<VertexBuffer> oldVertexData = other.getBufferList();
for (VertexBuffer oldVb : oldVertexData) {
if (oldVb.getBufferType() == VertexBuffer.Type.Index) {
if (oldVb.getBufferType() == VertexBuffer.Type.Index
||oldVb.getBufferType() == VertexBuffer.Type.HWBoneIndex
|| oldVb.getBufferType() == VertexBuffer.Type.HWBoneWeight ) {
// ignore the index buffer
continue;
}

@ -229,7 +229,7 @@ public class Node extends Spatial implements Savable {
* @param child
* the child to attach to this node.
* @return the number of children maintained by this node.
* @throws NullPointerException If child is null.
* @throws IllegalArgumentException if child is null.
*/
public int attachChild(Spatial child) {
if (child == null)

File diff suppressed because it is too large Load Diff

@ -250,7 +250,7 @@ public class Dome extends Mesh {
BufferUtils.populateFromBuffer(tempVa, vb, i);
kNormal = tempVa.subtractLocal(center);
kNormal.normalizeLocal();
if (insideView) {
if (!insideView) {
nb.put(kNormal.x).put(kNormal.y).put(kNormal.z);
} else {
nb.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);
@ -267,7 +267,7 @@ public class Dome extends Mesh {
// pole
vb.put(center.x).put(center.y + radius).put(center.z);
nb.put(0).put(insideView ? 1 : -1).put(0);
nb.put(0).put(insideView ? -1 : 1).put(0);
tb.put(0.5f).put(1.0f);
// allocate connectivity

@ -71,7 +71,7 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
@SuppressWarnings("all")
protected AbstractShadowFilter(AssetManager manager, int shadowMapSize, T shadowRenderer) {
super("Post Shadow");
material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");
material = new Material(manager, "Common/MatDefs/Shadow/PostShadowFilter.j3md");
this.shadowRenderer = shadowRenderer;
this.shadowRenderer.setPostShadowMaterial(material);
}
@ -86,7 +86,7 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
return true;
}
public Material getShadowMaterial() {
public Material getShadowMaterial() {
return material;
}
Vector4f tmpv = new Vector4f();
@ -103,11 +103,17 @@ public abstract class AbstractShadowFilter<T extends AbstractShadowRenderer> ext
@Override
protected void postQueue(RenderQueue queue) {
shadowRenderer.postQueue(queue);
if(shadowRenderer.skipPostPass){
//removing the shadow map so that the post pass is skipped
material.setTexture("ShadowMap0", null);
}
}
@Override
protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) {
shadowRenderer.setPostShadowParams();
if(!shadowRenderer.skipPostPass){
shadowRenderer.setPostShadowParams();
}
}
@Override

@ -92,18 +92,27 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
protected CompareMode shadowCompareMode = CompareMode.Hardware;
protected Picture[] dispPic;
protected boolean flushQueues = true;
// define if the fallback material should be used.
/**
* true if the fallback material should be used, otherwise false
*/
protected boolean needsfallBackMaterial = false;
//Name of the post material technique
/**
* name of the post material technique
*/
protected String postTechniqueName = "PostShadow";
//flags to know when to change params in the materials
//a list of material of the post shadow queue geometries.
/**
* list of materials for post shadow queue geometries
*/
protected List<Material> matCache = new ArrayList<Material>();
protected GeometryList sceneReceivers;
protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
protected GeometryList shadowMapOccluders = new GeometryList(new OpaqueComparator());
private String[] shadowMapStringCache;
private String[] lightViewStringCache;
/**
* true to skip the post pass when there are no shadow casters
*/
protected boolean skipPostPass;
/**
@ -113,14 +122,13 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* Create an abstract shadow renderer, this is to be called in extending
* classes
* Create an abstract shadow renderer. Subclasses invoke this constructor.
*
* @param assetManager the application asset manager
* @param shadowMapSize the size of the rendered shadowmaps (512,1024,2048,
* @param shadowMapSize the size of the rendered shadow maps (512,1024,2048,
* etc...)
* @param nbShadowMaps the number of shadow maps rendered (the more shadow
* maps the more quality, the less fps).
* maps the more quality, the fewer fps).
*/
protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, int nbShadowMaps) {
@ -187,10 +195,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* Sets the filtering mode for shadow edges see {@link EdgeFilteringMode}
* for more info
* Sets the filtering mode for shadow edges. See {@link EdgeFilteringMode}
* for more info.
*
* @param EdgeFilteringMode
* @param filterMode the desired filter mode (not null)
*/
final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
if (filterMode == null) {
@ -214,7 +222,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* returns the the edge filtering mode
* returns the edge filtering mode
*
* @see EdgeFilteringMode
* @return
@ -224,9 +232,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* sets the shadow compare mode see {@link CompareMode} for more info
* Sets the shadow compare mode. See {@link CompareMode} for more info.
*
* @param compareMode
* @param compareMode the desired compare mode (not null)
*/
final public void setShadowCompareMode(CompareMode compareMode) {
if (compareMode == null) {
@ -263,7 +271,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
return shadowCompareMode;
}
//debug function that create a displayable frustrum
/**
* debug function to create a visible frustum
*/
protected Geometry createFrustum(Vector3f[] pts, int i) {
WireFrustum frustum = new WireFrustum(pts);
Geometry frustumMdl = new Geometry("f", frustum);
@ -294,6 +304,12 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
return frustumMdl;
}
/**
* Initialize this shadow renderer prior to its first update.
*
* @param rm the render manager
* @param vp the viewport
*/
public void initialize(RenderManager rm, ViewPort vp) {
renderManager = rm;
viewPort = vp;
@ -305,25 +321,31 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
}
/**
* Test whether this shadow renderer has been initialized.
*
* @return true if initialized, otherwise false
*/
public boolean isInitialized() {
return viewPort != null;
}
/**
* This mehtod is called once per frame. it is responsible for updating the
* shadow cams according to the light view.
*
* Invoked once per frame to update the shadow cams according to the light
* view.
*
* @param viewCam the scene cam
*/
protected abstract void updateShadowCams(Camera viewCam);
/**
* this method must return the geomtryList that contains the oclluders to be
* Returns a subclass-specific geometryList containing the occluders to be
* rendered in the shadow map
*
* @param shadowMapIndex the index of the shadow map being rendered
* @param sceneOccluders the occluders of the whole scene
* @param sceneReceivers the recievers of the whole scene
* @param sceneReceivers the receivers of the whole scene
* @param shadowMapOcculders
* @return
*/
protected abstract GeometryList getOccludersToRender(int shadowMapIndex, GeometryList sceneOccluders, GeometryList sceneReceivers, GeometryList shadowMapOccluders);
@ -350,7 +372,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
public void postQueue(RenderQueue rq) {
GeometryList occluders = rq.getShadowQueueContent(ShadowMode.Cast);
sceneReceivers = rq.getShadowQueueContent(ShadowMode.Receive);
skipPostPass = false;
if (sceneReceivers.size() == 0 || occluders.size() == 0) {
skipPostPass = true;
return;
}
@ -401,7 +425,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
debugfrustums = true;
}
//debug only : displays depth shadow maps
/**
* For debugging purposes, display depth shadow maps.
*/
protected void displayShadowMap(Renderer r) {
Camera cam = viewPort.getCamera();
renderManager.setCamera(cam, true);
@ -417,8 +443,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* For dubuging purpose Allow to "snapshot" the current frustrum to the
* scene
* For debugging purposes, "snapshot" the current frustum to the scene.
*/
public void displayDebug() {
debug = true;
@ -427,7 +452,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
abstract GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers);
public void postFrame(FrameBuffer out) {
if (skipPostPass) {
return;
}
if (debug) {
displayShadowMap(renderManager.getRenderer());
}
@ -463,10 +490,10 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* This method is called once per frame and is responsible of setting the
* material parameters than sub class may need to set on the post material
* This method is called once per frame and is responsible for setting any
* material parameters than subclass may need to set on the post material.
*
* @param material the materail to use for the post shadow pass
* @param material the material to use for the post shadow pass
*/
protected abstract void setMaterialParameters(Material material);
@ -537,7 +564,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* returns the shdaow intensity
* Returns the shadow intensity.
*
* @see #setShadowIntensity(float shadowIntensity)
* @return shadowIntensity
@ -547,9 +574,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* Set the shadowIntensity, the value should be between 0 and 1, a 0 value
* gives a bright and invisilble shadow, a 1 value gives a pitch black
* shadow, default is 0.7
* Set the shadowIntensity. The value should be between 0 and 1. A 0 value
* gives a bright and invisible shadow, a 1 value gives a pitch black
* shadow. The default is 0.7
*
* @param shadowIntensity the darkness of the shadow
*/
@ -581,7 +608,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* returns true if the PssmRenderer flushed the shadow queues
* Returns true if this shadow renderer flushes the shadow queues.
*
* @return flushQueues
*/
@ -590,9 +617,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* Set this to false if you want to use several PssmRederers to have
* multiple shadows cast by multiple light sources. Make sure the last
* PssmRenderer in the stack DO flush the queues, but not the others
* Set flushQueues to false if you have multiple shadow renderers, in order
* for multiple light sources to cast shadows. Make sure the last shadow
* renderer in the stack DOES flush the queues, but not the others.
*
* @param flushQueues
*/
@ -600,11 +627,16 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
this.flushQueues = flushQueues;
}
/**
* De-serialize this instance, for example when loading from a J3O file.
*
* @param im importer (not null)
*/
public void read(JmeImporter im) throws IOException {
InputCapsule ic = (InputCapsule) im.getCapsule(this);
assetManager = im.getAssetManager();
nbShadowMaps = ic.readInt("nbShadowMaps", 1);
shadowMapSize = ic.readInt("shadowMapSize", 0);
shadowMapSize = ic.readFloat("shadowMapSize", 0f);
shadowIntensity = ic.readFloat("shadowIntensity", 0.7f);
edgeFilteringMode = ic.readEnum("edgeFilteringMode", EdgeFilteringMode.class, EdgeFilteringMode.Bilinear);
shadowCompareMode = ic.readEnum("shadowCompareMode", CompareMode.class, CompareMode.Hardware);
@ -615,6 +647,11 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
}
/**
* Serialize this instance, for example when saving to a J3O file.
*
* @param ex exporter (not null)
*/
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
oc.write(nbShadowMaps, "nbShadowMaps", 1);
@ -625,4 +662,4 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
oc.write(flushQueues, "flushQueues", false);
oc.write(edgesThickness, "edgesThickness", 1.0f);
}
}
}

@ -57,8 +57,13 @@ public enum EdgeFilteringMode {
*/
PCF4(3),
/**
* 8x8 percentage-closer filtering is used. Shadows will be smoother at the
* cost of performance
* 12 samples percentage-closer filtering with a POISON disc distribution
* is used.
* http://devmag.org.za/2009/05/03/poisson-disk-sampling/
* The principle is to eliminate the regular blurring pattern that can be
* seen with pcf4x4 by randomizing the samble position with a poisson disc.
* Shadows will look smoother than 4x4 PCF but with slightly better or
* similar performance.
*/
PCFPOISSON(4),
/**

@ -32,5 +32,5 @@
package com.jme3.system;
public class JmeVersion {
public static final String FULL_NAME = "jMonkeyEngine 3.0.0 RC2";
public static final String FULL_NAME = "jMonkeyEngine 3.0.9";
}

@ -237,6 +237,7 @@ public class NativeObjectManager {
}
}
refMap.clear();
refQueue = new ReferenceQueue<Object>();
}
// public void printObjects(){

@ -1,245 +1,298 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.util;
import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.bounding.BoundingSphere;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.TextureCubeMap;
import java.nio.ByteBuffer;
import java.util.ArrayList;
/**
* <code>SkyFactory</code> is used to create jME {@link Spatial}s that can
* be attached to the scene to display a sky image in the background.
*
* @author Kirill Vainer
*/
public class SkyFactory {
/**
* Creates a sky using the given texture (cubemap or spheremap).
*
* @param assetManager The asset manager to use to load materials
* @param texture Texture to use for the sky
* @param normalScale The normal scale is multiplied by the 3D normal
* to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
* and transformation to the normal.
* @param sphereMap The way the texture is used
* depends on this value:<br>
* <ul>
* <li>true: Its a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
* <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
* then the image is taken from it and is inserted into a TextureCubeMap</li>
* </ul>
* @return A spatial representing the sky
*/
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap) {
return createSky(assetManager, texture, normalScale, sphereMap, 10);
}
/**
* Creates a sky using the given texture (cubemap or spheremap).
*
* @param assetManager The asset manager to use to load materials
* @param texture Texture to use for the sky
* @param normalScale The normal scale is multiplied by the 3D normal
* to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
* and transformation to the normal.
* @param sphereMap The way the texture is used
* depends on this value:<br>
* <ul>
* <li>true: Its a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
* <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
* then the image is taken from it and is inserted into a TextureCubeMap</li>
* </ul>
* @param sphereRadius If specified, this will be the sky sphere's radius.
* This should be the camera's near plane for optimal quality.
* @return A spatial representing the sky
*/
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap, int sphereRadius) {
if (texture == null) {
throw new IllegalArgumentException("texture cannot be null");
}
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setVector3("NormalScale", normalScale);
if (sphereMap) {
skyMat.setBoolean("SphereMap", sphereMap);
} else if (!(texture instanceof TextureCubeMap)) {
// make sure its a cubemap
Image img = texture.getImage();
texture = new TextureCubeMap();
texture.setImage(img);
}
skyMat.setTexture("Texture", texture);
sky.setMaterial(skyMat);
return sky;
}
private static void checkImage(Image image) {
// if (image.getDepth() != 1)
// throw new IllegalArgumentException("3D/Array images not allowed");
if (image.getWidth() != image.getHeight()) {
throw new IllegalArgumentException("Image width and height must be the same");
}
if (image.getMultiSamples() != 1) {
throw new IllegalArgumentException("Multisample textures not allowed");
}
}
private static void checkImagesForCubeMap(Image... images) {
if (images.length == 1) {
return;
}
Format fmt = images[0].getFormat();
int width = images[0].getWidth();
int height = images[0].getHeight();
ByteBuffer data = images[0].getData(0);
int size = data != null ? data.capacity() : 0;
checkImage(images[0]);
for (int i = 1; i < images.length; i++) {
Image image = images[i];
checkImage(images[i]);
if (image.getFormat() != fmt) {
throw new IllegalArgumentException("Images must have same format");
}
if (image.getWidth() != width || image.getHeight() != height) {
throw new IllegalArgumentException("Images must have same resolution");
}
ByteBuffer data2 = image.getData(0);
if (data2 != null){
if (data2.capacity() != size) {
throw new IllegalArgumentException("Images must have same size");
}
}
}
}
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale) {
return createSky(assetManager, west, east, north, south, up, down, normalScale, 10);
}
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale, int sphereRadius) {
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Image westImg = west.getImage();
Image eastImg = east.getImage();
Image northImg = north.getImage();
Image southImg = south.getImage();
Image upImg = up.getImage();
Image downImg = down.getImage();
checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
cubeImage.addData(westImg.getData(0));
cubeImage.addData(eastImg.getData(0));
cubeImage.addData(downImg.getData(0));
cubeImage.addData(upImg.getData(0));
cubeImage.addData(southImg.getData(0));
cubeImage.addData(northImg.getData(0));
if (westImg.getEfficentData() != null){
// also consilidate efficient data
ArrayList<Object> efficientData = new ArrayList<Object>(6);
efficientData.add(westImg.getEfficentData());
efficientData.add(eastImg.getEfficentData());
efficientData.add(downImg.getEfficentData());
efficientData.add(upImg.getEfficentData());
efficientData.add(southImg.getEfficentData());
efficientData.add(northImg.getEfficentData());
cubeImage.setEfficentData(efficientData);
}
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
cubeMap.setAnisotropicFilter(0);
cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
cubeMap.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setTexture("Texture", cubeMap);
skyMat.setVector3("NormalScale", normalScale);
sky.setMaterial(skyMat);
return sky;
}
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down) {
return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
}
public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) {
return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
}
public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) {
TextureKey key = new TextureKey(textureName, true);
key.setGenerateMips(true);
key.setAsCube(!sphereMap);
Texture tex = assetManager.loadTexture(key);
return createSky(assetManager, tex, sphereMap);
}
}
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.util;
import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.bounding.BoundingSphere;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.TextureCubeMap;
import java.nio.ByteBuffer;
import java.util.ArrayList;
/**
* <code>SkyFactory</code> is used to create jME {@link Spatial}s that can
* be attached to the scene to display a sky image in the background.
*
* @author Kirill Vainer
*/
public class SkyFactory {
/**
* Create a sky with radius=10 using the given cubemap or spheremap texture.
*
* For the sky to be visible, its radius must fall between the near and far
* planes of the camera's frustrum.
*
* @param assetManager from which to load materials
* @param texture to use
* @param normalScale The normal scale is multiplied by the 3D normal to get
* a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
* transformation to the normal.
* @param sphereMap determines how the texture is used:<br>
* <ul>
* <li>true: The texture is a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere
* mapping</a>.</li>
* <li>false: The texture is either a TextureCubeMap or Texture2D. If it is
* a Texture2D then the image is taken from it and is inserted into a
* TextureCubeMap</li>
* </ul>
* @return a new spatial representing the sky, ready to be attached to the
* scene graph
*/
public static Spatial createSky(AssetManager assetManager, Texture texture,
Vector3f normalScale, boolean sphereMap) {
return createSky(assetManager, texture, normalScale, sphereMap, 10);
}
/**
* Create a sky using the given cubemap or spheremap texture.
*
* @param assetManager from which to load materials
* @param texture to use
* @param normalScale The normal scale is multiplied by the 3D normal to get
* a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
* transformation to the normal.
* @param sphereMap determines how the texture is used:<br>
* <ul>
* <li>true: The texture is a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere
* mapping</a>.</li>
* <li>false: The texture is either a TextureCubeMap or Texture2D. If it is
* a Texture2D then the image is taken from it and is inserted into a
* TextureCubeMap</li>
* </ul>
* @param sphereRadius the sky sphere's radius: for the sky to be visible,
* its radius must fall between the near and far planes of the camera's
* frustrum
* @return a new spatial representing the sky, ready to be attached to the
* scene graph
*/
public static Spatial createSky(AssetManager assetManager, Texture texture,
Vector3f normalScale, boolean sphereMap, int sphereRadius) {
if (texture == null) {
throw new IllegalArgumentException("texture cannot be null");
}
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setVector3("NormalScale", normalScale);
if (sphereMap) {
skyMat.setBoolean("SphereMap", sphereMap);
} else if (!(texture instanceof TextureCubeMap)) {
// make sure its a cubemap
Image img = texture.getImage();
texture = new TextureCubeMap();
texture.setImage(img);
}
skyMat.setTexture("Texture", texture);
sky.setMaterial(skyMat);
return sky;
}
private static void checkImage(Image image) {
// if (image.getDepth() != 1)
// throw new IllegalArgumentException("3D/Array images not allowed");
if (image.getWidth() != image.getHeight()) {
throw new IllegalArgumentException("Image width and height must be the same");
}
if (image.getMultiSamples() != 1) {
throw new IllegalArgumentException("Multisample textures not allowed");
}
}
private static void checkImagesForCubeMap(Image... images) {
if (images.length == 1) {
return;
}
Format fmt = images[0].getFormat();
int width = images[0].getWidth();
int height = images[0].getHeight();
ByteBuffer data = images[0].getData(0);
int size = data != null ? data.capacity() : 0;
checkImage(images[0]);
for (int i = 1; i < images.length; i++) {
Image image = images[i];
checkImage(images[i]);
if (image.getFormat() != fmt) {
throw new IllegalArgumentException("Images must have same format");
}
if (image.getWidth() != width || image.getHeight() != height) {
throw new IllegalArgumentException("Images must have same resolution");
}
ByteBuffer data2 = image.getData(0);
if (data2 != null){
if (data2.capacity() != size) {
throw new IllegalArgumentException("Images must have same size");
}
}
}
}
/**
* Create a cube-mapped sky with radius=10 using six textures.
*
* For the sky to be visible, its radius must fall between the near and far
* planes of the camera's frustrum.
*
* @param assetManager from which to load materials
* @param west texture for the western face of the cube
* @param east texture for the eastern face of the cube
* @param north texture for the northern face of the cube
* @param south texture for the southern face of the cube
* @param up texture for the top face of the cube
* @param down texture for the bottom face of the cube
* @param normalScale The normal scale is multiplied by the 3D normal to get
* a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
* transformation to the normal.
* @return a new spatial representing the sky, ready to be attached to the
* scene graph
*/
public static Spatial createSky(AssetManager assetManager, Texture west,
Texture east, Texture north, Texture south, Texture up,
Texture down, Vector3f normalScale) {
return createSky(assetManager, west, east, north, south, up, down,
normalScale, 10);
}
/**
* Create a cube-mapped sky using six textures.
*
* @param assetManager from which to load materials
* @param west texture for the western face of the cube
* @param east texture for the eastern face of the cube
* @param north texture for the northern face of the cube
* @param south texture for the southern face of the cube
* @param up texture for the top face of the cube
* @param down texture for the bottom face of the cube
* @param normalScale The normal scale is multiplied by the 3D normal to get
* a texture coordinate. Use Vector3f.UNIT_XYZ to not apply and
* transformation to the normal.
* @param sphereRadius the sky sphere's radius: for the sky to be visible,
* its radius must fall between the near and far planes of the camera's
* frustrum
* @return a new spatial representing the sky, ready to be attached to the
* scene graph
*/
public static Spatial createSky(AssetManager assetManager, Texture west,
Texture east, Texture north, Texture south, Texture up,
Texture down, Vector3f normalScale, float sphereRadius) {
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Image westImg = west.getImage();
Image eastImg = east.getImage();
Image northImg = north.getImage();
Image southImg = south.getImage();
Image upImg = up.getImage();
Image downImg = down.getImage();
checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
cubeImage.addData(westImg.getData(0));
cubeImage.addData(eastImg.getData(0));
cubeImage.addData(downImg.getData(0));
cubeImage.addData(upImg.getData(0));
cubeImage.addData(southImg.getData(0));
cubeImage.addData(northImg.getData(0));
if (westImg.getEfficentData() != null){
// also consilidate efficient data
ArrayList<Object> efficientData = new ArrayList<Object>(6);
efficientData.add(westImg.getEfficentData());
efficientData.add(eastImg.getEfficentData());
efficientData.add(downImg.getEfficentData());
efficientData.add(upImg.getEfficentData());
efficientData.add(southImg.getEfficentData());
efficientData.add(northImg.getEfficentData());
cubeImage.setEfficentData(efficientData);
}
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
cubeMap.setAnisotropicFilter(0);
cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
cubeMap.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setTexture("Texture", cubeMap);
skyMat.setVector3("NormalScale", normalScale);
sky.setMaterial(skyMat);
return sky;
}
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down) {
return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
}
public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) {
return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
}
public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) {
TextureKey key = new TextureKey(textureName, true);
key.setGenerateMips(true);
key.setAsCube(!sphereMap);
Texture tex = assetManager.loadTexture(key);
return createSky(assetManager, tex, sphereMap);
}
}

@ -41,6 +41,7 @@ import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
@ -210,13 +211,13 @@ public class CursorLoader implements AssetLoader {
}
} else if (isIco) {
DataInputStream in = new DataInputStream(inStream);
int bytesToRead;
while ((bytesToRead = in.available()) != 0) {
byte[] icoimage2 = new byte[icoimages.length + bytesToRead];
System.arraycopy(icoimages, 0, icoimage2, 0, icoimages.length);
in.read(icoimage2, icoimages.length, bytesToRead);
icoimages = icoimage2;
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[16384];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
icoimages = out.toByteArray();
}
BufferedImage bi[] = parseICOImage(icoimages);

@ -85,6 +85,7 @@ public final class Natives {
}
private static int computeNativesHash() {
URLConnection conn = null;
try {
String classpath = System.getProperty("java.class.path");
URL url = Thread.currentThread().getContextClassLoader().getResource("com/jme3/system/Natives.class");
@ -101,11 +102,18 @@ public final class Natives {
throw new UnsupportedOperationException(ex);
}
URLConnection conn = url.openConnection();
conn = url.openConnection();
int hash = classpath.hashCode() ^ (int) conn.getLastModified();
return hash;
} catch (IOException ex) {
throw new UnsupportedOperationException(ex);
} finally {
if (conn != null) {
try {
conn.getInputStream().close();
conn.getOutputStream().close();
} catch (IOException ex) { }
}
}
}
@ -233,7 +241,7 @@ public final class Natives {
String libraryPath = getExtractionDir().toString();
if (needLWJGL) {
logger.log(Level.FINE, "Extraction Directory: {0}", getExtractionDir().toString());
logger.log(Level.INFO, "Extraction Directory: {0}", getExtractionDir().toString());
// LWJGL supports this feature where
// it can load libraries from this path.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,67 @@
package com.jme3.audio.android;
import com.jme3.asset.AssetKey;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioRenderer;
import com.jme3.util.NativeObject;
public class AndroidAudioData extends AudioData {
protected AssetKey<?> assetKey;
protected float currentVolume = 0f;
public AndroidAudioData(){
super();
}
protected AndroidAudioData(int id){
super(id);
}
public AssetKey<?> getAssetKey() {
return assetKey;
}
public void setAssetKey(AssetKey<?> assetKey) {
this.assetKey = assetKey;
}
@Override
public DataType getDataType() {
return DataType.Buffer;
}
@Override
public float getDuration() {
return 0; // TODO: ???
}
@Override
public void resetObject() {
this.id = -1;
setUpdateNeeded();
}
@Override
public void deleteObject(Object rendererObject) {
((AudioRenderer)rendererObject).deleteAudioData(this);
}
public float getCurrentVolume() {
return currentVolume;
}
public void setCurrentVolume(float currentVolume) {
this.currentVolume = currentVolume;
}
@Override
public NativeObject createDestructableClone() {
return new AndroidAudioData(id);
}
@Override
public long getUniqueId() {
return ((long)OBJTYPE_AUDIOBUFFER << 32) | ((long)id);
}
}

@ -0,0 +1,24 @@
package com.jme3.audio.android;
import com.jme3.audio.AudioRenderer;
/**
* Android specific AudioRenderer interface that supports pausing and resuming
* audio files when the app is minimized or placed in the background
*
* @author iwgeric
*/
public interface AndroidAudioRenderer extends AudioRenderer {
/**
* Pauses all Playing audio. To be used when the app is placed in the
* background.
*/
public void pauseAll();
/**
* Resumes all Paused audio. To be used when the app is brought back to
* the foreground.
*/
public void resumeAll();
}

@ -0,0 +1,20 @@
package com.jme3.audio.plugins;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import com.jme3.audio.android.AndroidAudioData;
import java.io.IOException;
/**
* <code>AndroidAudioLoader</code> will create an
* {@link AndroidAudioData} object with the specified asset key.
*/
public class AndroidAudioLoader implements AssetLoader {
@Override
public Object load(AssetInfo assetInfo) throws IOException {
AndroidAudioData result = new AndroidAudioData();
result.setAssetKey(assetInfo.getKey());
return result;
}
}

@ -0,0 +1,203 @@
package com.jme3.input.ios;
import com.jme3.input.RawInputListener;
import com.jme3.input.TouchInput;
import com.jme3.input.event.InputEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.system.AppSettings;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
public class IosInputHandler implements TouchInput {
private static final Logger logger = Logger.getLogger(IosInputHandler.class.getName());
private final static int MAX_TOUCH_EVENTS = 1024;
// Custom settings
private boolean mouseEventsEnabled = true;
private boolean mouseEventsInvertX = false;
private boolean mouseEventsInvertY = false;
private boolean keyboardEventsEnabled = false;
private boolean dontSendHistory = false;
// Internal
private boolean initialized = false;
private RawInputListener listener = null;
private ConcurrentLinkedQueue<InputEvent> inputEventQueue = new ConcurrentLinkedQueue<InputEvent>();
private final TouchEventPool touchEventPool = new TouchEventPool(MAX_TOUCH_EVENTS);
private IosTouchHandler touchHandler;
private float scaleX = 1f;
private float scaleY = 1f;
private int width = 0;
private int height = 0;
public IosInputHandler() {
touchHandler = new IosTouchHandler(this);
}
@Override
public void initialize() {
touchEventPool.initialize();
if (touchHandler != null) {
touchHandler.initialize();
}
initialized = true;
}
@Override
public void update() {
logger.log(Level.FINE, "InputEvent update : {0}",
new Object[]{listener});
if (listener != null) {
InputEvent inputEvent;
while ((inputEvent = inputEventQueue.poll()) != null) {
if (inputEvent instanceof TouchEvent) {
listener.onTouchEvent((TouchEvent)inputEvent);
} else if (inputEvent instanceof MouseButtonEvent) {
listener.onMouseButtonEvent((MouseButtonEvent)inputEvent);
} else if (inputEvent instanceof MouseMotionEvent) {
listener.onMouseMotionEvent((MouseMotionEvent)inputEvent);
} else if (inputEvent instanceof KeyInputEvent) {
listener.onKeyEvent((KeyInputEvent)inputEvent);
}
}
}
}
@Override
public void destroy() {
initialized = false;
touchEventPool.destroy();
if (touchHandler != null) {
touchHandler.destroy();
}
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void setInputListener(RawInputListener listener) {
this.listener = listener;
}
@Override
public long getInputTimeNanos() {
return System.nanoTime();
}
@Override
public void setSimulateMouse(boolean simulate) {
this.mouseEventsEnabled = simulate;
}
@Override
public boolean getSimulateMouse() {
return mouseEventsEnabled;
}
@Override
public boolean isSimulateMouse() {
return mouseEventsEnabled;
}
@Override
public void setSimulateKeyboard(boolean simulate) {
this.keyboardEventsEnabled = simulate;
}
@Override
public void setOmitHistoricEvents(boolean dontSendHistory) {
this.dontSendHistory = dontSendHistory;
}
// @Override
public void showVirtualKeyboard(boolean visible) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
// ----------------
public void loadSettings(AppSettings settings) {
// TODO: add simulate keyboard to settings
// keyboardEventsEnabled = true;
mouseEventsEnabled = true;//settings.isEmulateMouse();
mouseEventsInvertX = settings.isEmulateMouseFlipX();
mouseEventsInvertY = settings.isEmulateMouseFlipY();
// view width and height are 0 until the view is displayed on the screen
//if (view.getWidth() != 0 && view.getHeight() != 0) {
// scaleX = (float)settings.getWidth() / (float)view.getWidth();
// scaleY = (float)settings.getHeight() / (float)view.getHeight();
//}
scaleX = 1.0f;
scaleY = 1.0f;
width = settings.getWidth();
height = settings.getHeight();
logger.log(Level.FINE, "Setting input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}",
new Object[]{scaleX, scaleY, width, height});
}
public boolean isMouseEventsInvertX() {
return mouseEventsInvertX;
}
public boolean isMouseEventsInvertY() {
return mouseEventsInvertY;
}
public float invertX(float origX) {
return getJmeX(width) - origX;
}
public float invertY(float origY) {
return getJmeY(height) - origY;
}
public float getJmeX(float origX) {
return origX * scaleX;
}
public float getJmeY(float origY) {
return origY * scaleY;
}
public TouchEvent getFreeTouchEvent() {
return touchEventPool.getNextFreeEvent();
}
public void addEvent(InputEvent event) {
inputEventQueue.add(event);
if (event instanceof TouchEvent) {
touchEventPool.storeEvent((TouchEvent)event);
}
}
// ----------------
public void injectTouchDown(int pointerId, long time, float x, float y) {
logger.log(Level.FINE, "Using input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}",
new Object[]{scaleX, scaleY, width, height});
if (touchHandler != null) {
touchHandler.actionDown(pointerId, time, x, y);
}
}
public void injectTouchUp(int pointerId, long time, float x, float y) {
if (touchHandler != null) {
touchHandler.actionUp(pointerId, time, x, y);
}
}
public void injectTouchMove(int pointerId, long time, float x, float y) {
if (touchHandler != null) {
touchHandler.actionMove(pointerId, time, x, y);
}
}
}

@ -0,0 +1,191 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.input.ios;
import com.jme3.input.event.InputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import static com.jme3.input.event.TouchEvent.Type.DOWN;
import static com.jme3.input.event.TouchEvent.Type.MOVE;
import static com.jme3.input.event.TouchEvent.Type.UP;
import com.jme3.math.Vector2f;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* AndroidTouchHandler is the base class that receives touch inputs from the
* Android system and creates the TouchEvents for jME. This class is designed
* to handle the base touch events for Android rev 9 (Android 2.3). This is
* extended by other classes to add features that were introducted after
* Android rev 9.
*
* @author iwgeric
*/
public class IosTouchHandler {
private static final Logger logger = Logger.getLogger(IosTouchHandler.class.getName());
final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
protected int numPointers = 1;
protected IosInputHandler iosInput;
public IosTouchHandler(IosInputHandler iosInput) {
this.iosInput = iosInput;
}
public void initialize() {
}
public void destroy() {
}
public void actionDown(int pointerId, long time, float x, float y) {
logger.log(Level.FINE, "Inject input pointer: {0}, time: {1}, x: {2}, y: {3}",
new Object[]{pointerId, time, x, y});
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.DOWN, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId);//TODO: pointer ID
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure
lastPositions.put(pointerId, new Vector2f(jmeX, jmeY));
processEvent(touch);
}
public void actionUp(int pointerId, long time, float x, float y) {
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.UP, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId);//TODO: pointer ID
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure
lastPositions.remove(pointerId);
processEvent(touch);
}
public void actionMove(int pointerId, long time, float x, float y) {
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
Vector2f lastPos = lastPositions.get(pointerId);
if (lastPos == null) {
lastPos = new Vector2f(jmeX, jmeY);
lastPositions.put(pointerId, lastPos);
}
float dX = jmeX - lastPos.x;
float dY = jmeY - lastPos.y;
if (dX != 0 || dY != 0) {
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.MOVE, jmeX, jmeY, dX, dY);
touch.setPointerId(pointerId);
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(p));
lastPos.set(jmeX, jmeY);
processEvent(touch);
}
}
protected void processEvent(TouchEvent event) {
// Add the touch event
iosInput.addEvent(event);
// MouseEvents do not support multi-touch, so only evaluate 1 finger pointer events
if (iosInput.isSimulateMouse() && numPointers == 1) {
InputEvent mouseEvent = generateMouseEvent(event);
if (mouseEvent != null) {
// Add the mouse event
iosInput.addEvent(mouseEvent);
}
}
}
// TODO: Ring Buffer for mouse events?
protected InputEvent generateMouseEvent(TouchEvent event) {
InputEvent inputEvent = null;
int newX;
int newY;
int newDX;
int newDY;
if (iosInput.isMouseEventsInvertX()) {
newX = (int) (iosInput.invertX(event.getX()));
newDX = (int)event.getDeltaX() * -1;
} else {
newX = (int) event.getX();
newDX = (int)event.getDeltaX();
}
if (iosInput.isMouseEventsInvertY()) {
newY = (int) (iosInput.invertY(event.getY()));
newDY = (int)event.getDeltaY() * -1;
} else {
newY = (int) event.getY();
newDY = (int)event.getDeltaY();
}
switch (event.getType()) {
case DOWN:
// Handle mouse down event
inputEvent = new MouseButtonEvent(0, true, newX, newY);
inputEvent.setTime(event.getTime());
break;
case UP:
// Handle mouse up event
inputEvent = new MouseButtonEvent(0, false, newX, newY);
inputEvent.setTime(event.getTime());
break;
// case HOVER_MOVE:
case MOVE:
inputEvent = new MouseMotionEvent(newX, newY, newDX, newDY, (int)event.getScaleSpan(), (int)event.getDeltaScaleSpan());
inputEvent.setTime(event.getTime());
break;
}
return inputEvent;
}
}

@ -0,0 +1,121 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.input.ios;
import com.jme3.input.event.TouchEvent;
import com.jme3.util.RingBuffer;
import java.util.logging.Logger;
/**
* TouchEventPool provides a RingBuffer of jME TouchEvents to help with garbage
* collection on Android. Each TouchEvent is stored in the RingBuffer and is
* reused if the TouchEvent has been consumed.
*
* If a TouchEvent has not been consumed, it is placed back into the pool at the
* end for later use. If a TouchEvent has been consumed, it is reused to avoid
* creating lots of little objects.
*
* If the pool is full of unconsumed events, then a new event is created and provided.
*
*
* @author iwgeric
*/
public class TouchEventPool {
private static final Logger logger = Logger.getLogger(TouchEventPool.class.getName());
private final RingBuffer<TouchEvent> eventPool;
private final int maxEvents;
public TouchEventPool (int maxEvents) {
eventPool = new RingBuffer<TouchEvent>(maxEvents);
this.maxEvents = maxEvents;
}
public void initialize() {
TouchEvent newEvent;
while (!eventPool.isEmpty()) {
eventPool.pop();
}
for (int i = 0; i < maxEvents; i++) {
newEvent = new TouchEvent();
newEvent.setConsumed();
eventPool.push(newEvent);
}
}
public void destroy() {
// Clean up queues
while (!eventPool.isEmpty()) {
eventPool.pop();
}
}
/**
* Fetches a touch event from the reuse pool
*
* @return a usable TouchEvent
*/
public TouchEvent getNextFreeEvent() {
TouchEvent evt = null;
int curSize = eventPool.size();
while (curSize > 0) {
evt = (TouchEvent)eventPool.pop();
if (evt.isConsumed()) {
break;
} else {
eventPool.push(evt);
evt = null;
}
curSize--;
}
if (evt == null) {
logger.warning("eventPool full of unconsumed events");
evt = new TouchEvent();
}
return evt;
}
/**
* Stores the TouchEvent back in the pool for later reuse. It is only reused
* if the TouchEvent has been consumed.
*
* @param event TouchEvent to store for later use if consumed.
*/
public void storeEvent(TouchEvent event) {
if (eventPool.size() < maxEvents) {
eventPool.push(event);
} else {
logger.warning("eventPool full");
}
}
}

@ -0,0 +1,273 @@
package com.jme3.renderer.ios;
import com.jme3.renderer.RendererException;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The <code>iOS GLES interface</code> iOS alternative to Android's GLES20 class
*
* @author Kostyantyn Hushchyn
*/
public class JmeIosGLES {
private static final Logger logger = Logger.getLogger(JmeIosGLES.class.getName());
private static boolean ENABLE_ERROR_CHECKING = true;
public static final int GL_ALPHA = 0x00001906;
public static final int GL_ALWAYS = 0x00000207;
public static final int GL_ARRAY_BUFFER = 0x00008892;
public static final int GL_BACK = 0x00000405;
public static final int GL_BLEND = 0x00000be2;
public static final int GL_BYTE = 0x00001400;
public static final int GL_CLAMP_TO_EDGE = 0x0000812f;
public static final int GL_COLOR_ATTACHMENT0 = 0x00008ce0;
public static final int GL_COLOR_BUFFER_BIT = 0x00004000;
public static final int GL_COMPILE_STATUS = 0x00008b81;
public static final int GL_COMPRESSED_TEXTURE_FORMATS = 0x000086a3;
public static final int GL_CULL_FACE = 0x00000b44;
public static final int GL_DEPTH_ATTACHMENT = 0x00008d00;
public static final int GL_DEPTH_BUFFER_BIT = 0x00000100;
public static final int GL_DEPTH_COMPONENT = 0x00001902;
public static final int GL_DEPTH_COMPONENT16 = 0x000081a5;
public static final int GL_DEPTH_TEST = 0x00000b71;
public static final int GL_DITHER = 0x00000bd0;
public static final int GL_DST_COLOR = 0x00000306;
public static final int GL_DYNAMIC_DRAW = 0x000088e8;
public static final int GL_EQUAL = 0x00000202;
public static final int GL_ELEMENT_ARRAY_BUFFER = 0x00008893;
public static final int GL_EXTENSIONS = 0x00001f03;
public static final int GL_FALSE = 0x00000000;
public static final int GL_FLOAT = 0x00001406;
public static final int GL_FRAGMENT_SHADER = 0x00008b30;
public static final int GL_FRAMEBUFFER = 0x00008d40;
public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x00008cd1;
public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x00008cd0;
public static final int GL_FRAMEBUFFER_COMPLETE = 0x00008cd5;
public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x00008cd6;
public static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x00008cd9;
public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x00008cd7;
public static final int GL_FRAMEBUFFER_UNSUPPORTED = 0x00008cdd;
public static final int GL_FRONT = 0x00000404;
public static final int GL_FRONT_AND_BACK = 0x00000408;
public static final int GL_GEQUAL = 0x00000206;
public static final int GL_GREATER = 0x00000204;
public static final int GL_HIGH_FLOAT = 0x00008df2;
public static final int GL_INFO_LOG_LENGTH = 0x00008b84;
public static final int GL_INT = 0x00001404;
public static final int GL_LEQUAL = 0x00000203;
public static final int GL_LESS = 0x00000201;
public static final int GL_LINEAR = 0x00002601;
public static final int GL_LINEAR_MIPMAP_LINEAR = 0x00002703;
public static final int GL_LINEAR_MIPMAP_NEAREST = 0x00002701;
public static final int GL_LINES = 0x00000001;
public static final int GL_LINE_LOOP = 0x00000002;
public static final int GL_LINE_STRIP = 0x00000003;
public static final int GL_LINK_STATUS = 0x00008b82;
public static final int GL_LUMINANCE = 0x00001909;
public static final int GL_LUMINANCE_ALPHA = 0x0000190a;
public static final int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x0000851c;
public static final int GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x00008dfd;
public static final int GL_MAX_RENDERBUFFER_SIZE = 0x000084e8;
public static final int GL_MAX_TEXTURE_IMAGE_UNITS = 0x00008872;
public static final int GL_MAX_TEXTURE_SIZE = 0x00000d33;
public static final int GL_MAX_VARYING_VECTORS = 0x00008dfc;
public static final int GL_MAX_VERTEX_ATTRIBS = 0x00008869;
public static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x00008b4c;
public static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x00008dfb;
public static final int GL_MIRRORED_REPEAT = 0x00008370;
public static final int GL_NEAREST = 0x00002600;
public static final int GL_NEAREST_MIPMAP_LINEAR = 0x00002702;
public static final int GL_NEAREST_MIPMAP_NEAREST = 0x00002700;
public static final int GL_NEVER = 0x00000200;
public static final int GL_NONE = 0x00000000;
public static final int GL_NOTEQUAL = 0x00000205;
public static final int GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x000086a2;
public static final int GL_ONE = 0x00000001;
public static final int GL_ONE_MINUS_SRC_ALPHA = 0x00000303;
public static final int GL_ONE_MINUS_SRC_COLOR = 0x00000301;
public static final int GL_POINTS = 0x00000000;
public static final int GL_POLYGON_OFFSET_FILL = 0x00008037;
public static final int GL_RENDERBUFFER = 0x00008d41;
public static final int GL_RENDERER = 0x00001f01;
public static final int GL_REPEAT = 0x00002901;
public static final int GL_RGB = 0x00001907;
public static final int GL_RGB565 = 0x00008d62;
public static final int GL_RGB5_A1 = 0x00008057;
public static final int GL_RGBA = 0x00001908;
public static final int GL_RGBA4 = 0x00008056;
public static final int GL_SAMPLE_ALPHA_TO_COVERAGE = 0x0000809e;
public static final int GL_SCISSOR_TEST = 0x00000c11;
public static final int GL_SHADING_LANGUAGE_VERSION = 0x00008b8c;
public static final int GL_SHORT = 0x00001402;
public static final int GL_SRC_COLOR = 0x00000300;
public static final int GL_SRC_ALPHA = 0x00000302;
public static final int GL_STATIC_DRAW = 0x000088e4;
public static final int GL_STENCIL_BUFFER_BIT = 0x00000400;
public static final int GL_STREAM_DRAW = 0x000088e0;
public static final int GL_SUBPIXEL_BITS = 0x00000d50;
public static final int GL_TEXTURE = 0x00001702;
public static final int GL_TEXTURE0 = 0x000084c0;
public static final int GL_TEXTURE_2D = 0x00000de1;
public static final int GL_TEXTURE_CUBE_MAP = 0x00008513;
public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x00008515;
public static final int GL_TEXTURE_MAG_FILTER = 0x00002800;
public static final int GL_TEXTURE_MIN_FILTER = 0x00002801;
public static final int GL_TEXTURE_WRAP_S = 0x00002802;
public static final int GL_TEXTURE_WRAP_T = 0x00002803;
public static final int GL_TRIANGLES = 0x00000004;
public static final int GL_TRIANGLE_FAN = 0x00000006;
public static final int GL_TRIANGLE_STRIP = 0x00000005;
public static final int GL_TRUE = 0x00000001;
public static final int GL_UNPACK_ALIGNMENT = 0x00000cf5;
public static final int GL_UNSIGNED_BYTE = 0x00001401;
public static final int GL_UNSIGNED_INT = 0x00001405;
public static final int GL_UNSIGNED_SHORT = 0x00001403;
public static final int GL_UNSIGNED_SHORT_4_4_4_4 = 0x00008033;
public static final int GL_UNSIGNED_SHORT_5_5_5_1 = 0x00008034;
public static final int GL_UNSIGNED_SHORT_5_6_5 = 0x00008363;
public static final int GL_VENDOR = 0x00001f00;
public static final int GL_VERSION = 0x00001f02;
public static final int GL_VERTEX_SHADER = 0x00008b31;
public static final int GL_ZERO = 0x00000000;
public static native void glActiveTexture(int texture);
public static native void glAttachShader(int program, int shader);
public static native void glBindBuffer(int target, int buffer);
public static native void glBindFramebuffer(int target, int framebuffer);
public static native void glBindRenderbuffer(int target, int renderbuffer);
public static native void glBindTexture(int target, int texture);
// public static native void glBindVertexArray // TODO: Investigate this
public static native void glBlendFunc(int sfactor, int dfactor);
public static native void glBufferData(int target, int size, Buffer data, int usage);
public static native void glBufferData2(int target, int size, byte[] data, int offset, int usage);
public static native void glBufferSubData(int target, int offset, int size, Buffer data);
public static native void glBufferSubData2(int target, int offset, int size, byte[] data, int dataoffset);
public static native int glCheckFramebufferStatus(int target);
public static native void glClear(int mask);
public static native void glClearColor(float red, float green, float blue, float alpha);
public static native void glColorMask(boolean red, boolean green, boolean blue, boolean alpha);
public static native void glCompileShader(int shader);
public static native void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, int imageSize, Buffer pixels);
public static native void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int imageSize, Buffer pixels);
public static native int glCreateProgram();
public static native int glCreateShader(int type);
public static native void glCullFace(int mode);
public static native void glDeleteBuffers(int n, int[] buffers, int offset);
public static native void glDeleteFramebuffers(int n, int[] framebuffers, int offset);
public static native void glDeleteProgram(int program);
public static native void glDeleteRenderbuffers(int n, int[] renderbuffers, int offset);
public static native void glDeleteShader(int shader);
public static native void glDeleteTextures(int n, int[] textures, int offset);
public static native void glDepthFunc(int func);
public static native void glDepthMask(boolean flag);
public static native void glDepthRangef(float zNear, float zFar);
public static native void glDetachShader(int program, int shader);
public static native void glDisableVertexAttribArray(int index);
public static native void glDisable(int cap);
public static native void glDrawArrays(int mode, int first, int count);
public static native void glDrawElements(int mode, int count, int type, Buffer indices);
public static native void glDrawElements2(int mode, int count, int type, byte[] indices, int offset);
public static native void glDrawElementsIndex(int mode, int count, int type, int offset);
public static native void glEnable(int cap);
public static native void glEnableVertexAttribArray(int index);
public static native void glFramebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer);
public static native void glFramebufferTexture2D(int target, int attachment, int textarget, int texture, int level);
public static native void glGenBuffers(int n, int[] buffers, int offset);
public static native void glGenFramebuffers(int n, int[] framebuffers, int offset);
public static native void glGenRenderbuffers(int n, int[] renderbuffers, int offset);
public static native void glGenTextures(int n, int[] textures, int offset);
public static native void glGenerateMipmap(int target);
public static native int glGetAttribLocation(int program, String name);
public static native int glGetError();
public static native void glGetFramebufferAttachmentParameteriv(int target, int attachment, int pname, int[] params, int offset);
public static native void glGetIntegerv (int pname, int[] params, int offset);
public static native String glGetProgramInfoLog(int program);
public static native void glGetProgramiv(int program, int pname, int[] params, int offset);
public static native String glGetShaderInfoLog(int shader);
public static native void glGetShaderiv(int shader, int pname, int[] params, int offset);
public static native String glGetString(int name);
public static native int glGetUniformLocation(int program, String name);
public static native boolean glIsFramebuffer(int framebuffer);
public static native boolean glIsRenderbuffer(int renderbuffer);
public static native void glLineWidth(float width);
public static native void glLinkProgram(int program);
public static native void glPixelStorei(int pname, int param);
public static native void glPolygonOffset(float factor, float units);
public static native void glReadPixels(int vpX, int vpY, int vpW, int vpH, int format, int type, Buffer pixels);
public static native void glReadPixels2(int vpX, int vpY, int vpW, int vpH, int format, int type, byte[] pixels, int offset, int size);
public static native void glRenderbufferStorage(int target, int internalformat, int width, int height);
public static native void glScissor(int x, int y, int width, int height);
public static native void glShaderSource(int shader, String string);
public static native void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, Buffer pixels);
public static native void glTexParameteri(int target, int pname, int param);
public static native void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, Buffer pixels);
public static native void glUniform1f(int location, float x);
public static native void glUniform1fv(int location, int count, FloatBuffer v);
public static native void glUniform1fv2(int location, int count, float[] v, int offset);
public static native void glUniform1i(int location, int x);
public static native void glUniform1iv(int location, int count, IntBuffer v);
public static native void glUniform1iv2(int location, int count, int[] v, int offset);
public static native void glUniform2f(int location, float x, float y);
public static native void glUniform2fv(int location, int count, FloatBuffer v);
public static native void glUniform2fv2(int location, int count, float[] v, int offset);
public static native void glUniform3f(int location, float x, float y, float z);
public static native void glUniform3fv(int location, int count, FloatBuffer v);
public static native void glUniform3fv2(int location, int count, float[] v, int offset);
public static native void glUniform4f(int location, float x, float y, float z, float w);
public static native void glUniform4fv(int location, int count, FloatBuffer v);
public static native void glUniform4fv2(int location, int count, float[] v, int offset);
public static native void glUniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer value);
public static native void glUniformMatrix3fv2(int location, int count, boolean transpose, float[] value, int offset);
public static native void glUniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer value);
public static native void glUniformMatrix4fv2(int location, int count, boolean transpose, float[] value, int offset);
public static native void glUseProgram(int program);
//public static native void glVertexAttribPointer(int indx, int size, int type, boolean normalized, int stride, byte[] ptr, int offset);
public static native void glVertexAttribPointer(int indx, int size, int type, boolean normalized, int stride, Buffer ptr);
public static native void glVertexAttribPointer2(int indx, int size, int type, boolean normalized, int stride, int offset);
public static native void glViewport(int x, int y, int width, int height);
public static void checkGLError() {
if (!ENABLE_ERROR_CHECKING) {
return;
}
int error = glGetError();
if (error != 0) {
String message = null;//GLU.gluErrorString(error);
if (message == null) {
throw new RendererException("An unknown [" + error + "] OpenGL error has occurred.");
} else {
throw new RendererException("An OpenGL error has occurred: " + message);
}
}
}
/*
public static String gluErrorString(int error) {
switch (error) {
case GL10.GL_NO_ERROR:
return "no error";
case GL10.GL_INVALID_ENUM:
return "invalid enum";
case GL10.GL_INVALID_VALUE:
return "invalid value";
case GL10.GL_INVALID_OPERATION:
return "invalid operation";
case GL10.GL_STACK_OVERFLOW:
return "stack overflow";
case GL10.GL_STACK_UNDERFLOW:
return "stack underflow";
case GL10.GL_OUT_OF_MEMORY:
return "out of memory";
default:
return null;
}
}
*/
}

@ -0,0 +1,591 @@
package com.jme3.renderer.ios;
//import android.graphics.Bitmap;
//import android.opengl.ETC1;
//import android.opengl.ETC1Util.ETC1Texture;
//import android.opengl.JmeIosGLES;
//import android.opengl.GLUtils;
//import com.jme3.asset.AndroidImageInfo;
import com.jme3.renderer.ios.JmeIosGLES;
import com.jme3.math.FastMath;
import com.jme3.renderer.RendererException;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.util.BufferUtils;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TextureUtil {
private static final Logger logger = Logger.getLogger(TextureUtil.class.getName());
//TODO Make this configurable through appSettings
public static boolean ENABLE_COMPRESSION = true;
private static boolean NPOT = false;
private static boolean ETC1support = false;
private static boolean DXT1 = false;
private static boolean PVRTC = false;
private static boolean DEPTH24_STENCIL8 = false;
private static boolean DEPTH_TEXTURE = false;
private static boolean RGBA8 = false;
// Same constant used by both GL_ARM_rgba8 and GL_OES_rgb8_rgba8.
private static final int GL_RGBA8 = 0x8058;
private static final int GL_DXT1 = 0x83F0;
private static final int GL_DXT1A = 0x83F1;
private static final int GL_DEPTH_STENCIL_OES = 0x84F9;
private static final int GL_UNSIGNED_INT_24_8_OES = 0x84FA;
private static final int GL_DEPTH24_STENCIL8_OES = 0x88F0;
public static void loadTextureFeatures(String extensionString) {
ETC1support = extensionString.contains("GL_OES_compressed_ETC1_RGB8_texture");
DEPTH24_STENCIL8 = extensionString.contains("GL_OES_packed_depth_stencil");
NPOT = extensionString.contains("GL_IMG_texture_npot")
|| extensionString.contains("GL_OES_texture_npot")
|| extensionString.contains("GL_NV_texture_npot_2D_mipmap");
PVRTC = extensionString.contains("GL_IMG_texture_compression_pvrtc");
DXT1 = extensionString.contains("GL_EXT_texture_compression_dxt1");
DEPTH_TEXTURE = extensionString.contains("GL_OES_depth_texture");
RGBA8 = extensionString.contains("GL_ARM_rgba8") ||
extensionString.contains("GL_OES_rgb8_rgba8");
logger.log(Level.FINE, "Supports ETC1? {0}", ETC1support);
logger.log(Level.FINE, "Supports DEPTH24_STENCIL8? {0}", DEPTH24_STENCIL8);
logger.log(Level.FINE, "Supports NPOT? {0}", NPOT);
logger.log(Level.FINE, "Supports PVRTC? {0}", PVRTC);
logger.log(Level.FINE, "Supports DXT1? {0}", DXT1);
logger.log(Level.FINE, "Supports DEPTH_TEXTURE? {0}", DEPTH_TEXTURE);
logger.log(Level.FINE, "Supports RGBA8? {0}", RGBA8);
}
/*
private static void buildMipmap(Bitmap bitmap, boolean compress) {
int level = 0;
int height = bitmap.getHeight();
int width = bitmap.getWidth();
logger.log(Level.FINEST, " - Generating mipmaps for bitmap using SOFTWARE");
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1);
while (height >= 1 || width >= 1) {
//First of all, generate the texture from our bitmap and set it to the according level
if (compress) {
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) with compression.", new Object[]{level, width, height});
uploadBitmapAsCompressed(JmeIosGLES.GL_TEXTURE_2D, level, bitmap, false, 0, 0);
} else {
logger.log(Level.FINEST, " - Uploading LOD level {0} ({1}x{2}) directly.", new Object[]{level, width, height});
GLUtils.texImage2D(JmeIosGLES.GL_TEXTURE_2D, level, bitmap, 0);
}
if (height == 1 || width == 1) {
break;
}
//Increase the mipmap level
height /= 2;
width /= 2;
Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true);
// Recycle any bitmaps created as a result of scaling the bitmap.
// Do not recycle the original image (mipmap level 0)
if (level != 0) {
bitmap.recycle();
}
bitmap = bitmap2;
level++;
}
}
private static void uploadBitmapAsCompressed(int target, int level, Bitmap bitmap, boolean subTexture, int x, int y) {
if (bitmap.hasAlpha()) {
logger.log(Level.FINEST, " - Uploading bitmap directly. Cannot compress as alpha present.");
if (subTexture) {
GLUtils.texSubImage2D(target, level, x, y, bitmap);
JmeIosGLES.checkGLError();
} else {
GLUtils.texImage2D(target, level, bitmap, 0);
JmeIosGLES.checkGLError();
}
} else {
// Convert to RGB565
int bytesPerPixel = 2;
Bitmap rgb565 = bitmap.copy(Bitmap.Config.RGB_565, true);
// Put texture data into ByteBuffer
ByteBuffer inputImage = BufferUtils.createByteBuffer(bitmap.getRowBytes() * bitmap.getHeight());
rgb565.copyPixelsToBuffer(inputImage);
inputImage.position(0);
// Delete the copied RGB565 image
rgb565.recycle();
// Encode the image into the output bytebuffer
int encodedImageSize = ETC1.getEncodedDataSize(bitmap.getWidth(), bitmap.getHeight());
ByteBuffer compressedImage = BufferUtils.createByteBuffer(encodedImageSize);
ETC1.encodeImage(inputImage, bitmap.getWidth(),
bitmap.getHeight(),
bytesPerPixel,
bytesPerPixel * bitmap.getWidth(),
compressedImage);
// Delete the input image buffer
BufferUtils.destroyDirectBuffer(inputImage);
// Create an ETC1Texture from the compressed image data
ETC1Texture etc1tex = new ETC1Texture(bitmap.getWidth(), bitmap.getHeight(), compressedImage);
// Upload the ETC1Texture
if (bytesPerPixel == 2) {
int oldSize = (bitmap.getRowBytes() * bitmap.getHeight());
int newSize = compressedImage.capacity();
logger.log(Level.FINEST, " - Uploading compressed image to GL, oldSize = {0}, newSize = {1}, ratio = {2}", new Object[]{oldSize, newSize, (float) oldSize / newSize});
if (subTexture) {
JmeIosGLES.glCompressedTexSubImage2D(target,
level,
x, y,
bitmap.getWidth(),
bitmap.getHeight(),
ETC1.ETC1_RGB8_OES,
etc1tex.getData().capacity(),
etc1tex.getData());
JmeIosGLES.checkGLError();
} else {
JmeIosGLES.glCompressedTexImage2D(target,
level,
ETC1.ETC1_RGB8_OES,
bitmap.getWidth(),
bitmap.getHeight(),
0,
etc1tex.getData().capacity(),
etc1tex.getData());
JmeIosGLES.checkGLError();
}
// ETC1Util.loadTexture(target, level, 0, JmeIosGLES.GL_RGB,
// JmeIosGLES.GL_UNSIGNED_SHORT_5_6_5, etc1Texture);
// } else if (bytesPerPixel == 3) {
// ETC1Util.loadTexture(target, level, 0, JmeIosGLES.GL_RGB,
// JmeIosGLES.GL_UNSIGNED_BYTE, etc1Texture);
}
BufferUtils.destroyDirectBuffer(compressedImage);
}
}
/**
* <code>uploadTextureBitmap</code> uploads a native android bitmap
*/
/*
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips) {
uploadTextureBitmap(target, bitmap, needMips, false, 0, 0);
}
/**
* <code>uploadTextureBitmap</code> uploads a native android bitmap
*/
/*
public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean needMips, boolean subTexture, int x, int y) {
boolean recycleBitmap = false;
//TODO, maybe this should raise an exception when NPOT is not supported
boolean willCompress = ENABLE_COMPRESSION && ETC1support && !bitmap.hasAlpha();
if (needMips && willCompress) {
// Image is compressed and mipmaps are desired, generate them
// using software.
buildMipmap(bitmap, willCompress);
} else {
if (willCompress) {
// Image is compressed but mipmaps are not desired, upload directly.
logger.log(Level.FINEST, " - Uploading compressed bitmap. Mipmaps are not generated.");
uploadBitmapAsCompressed(target, 0, bitmap, subTexture, x, y);
} else {
// Image is not compressed, mipmaps may or may not be desired.
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}",
(needMips
? " Mipmaps will be generated in HARDWARE"
: " Mipmaps are not generated."));
if (subTexture) {
System.err.println("x : " + x + " y :" + y + " , " + bitmap.getWidth() + "/" + bitmap.getHeight());
GLUtils.texSubImage2D(target, 0, x, y, bitmap);
JmeIosGLES.checkGLError();
} else {
GLUtils.texImage2D(target, 0, bitmap, 0);
JmeIosGLES.checkGLError();
}
if (needMips) {
// No pregenerated mips available,
// generate from base level if required
JmeIosGLES.glGenerateMipmap(target);
JmeIosGLES.checkGLError();
}
}
}
if (recycleBitmap) {
bitmap.recycle();
}
}
*/
public static void uploadTextureAny(Image img, int target, int index, boolean needMips) {
/*
if (img.getEfficentData() instanceof AndroidImageInfo) {
logger.log(Level.FINEST, " === Uploading image {0}. Using BITMAP PATH === ", img);
// If image was loaded from asset manager, use fast path
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData();
uploadTextureBitmap(target, imageInfo.getBitmap(), needMips);
} else {
*/
logger.log(Level.FINEST, " === Uploading image {0}. Using BUFFER PATH === ", img);
boolean wantGeneratedMips = needMips && !img.hasMipmaps();
if (wantGeneratedMips && img.getFormat().isCompressed()) {
logger.log(Level.WARNING, "Generating mipmaps is only"
+ " supported for Bitmap based or non-compressed images!");
}
// Upload using slower path
logger.log(Level.FINEST, " - Uploading bitmap directly.{0}",
(wantGeneratedMips
? " Mipmaps will be generated in HARDWARE"
: " Mipmaps are not generated."));
uploadTexture(img, target, index);
// Image was uploaded using slower path, since it is not compressed,
// then compress it
if (wantGeneratedMips) {
// No pregenerated mips available,
// generate from base level if required
JmeIosGLES.glGenerateMipmap(target);
JmeIosGLES.checkGLError();
}
//}
}
private static void unsupportedFormat(Format fmt) {
throw new UnsupportedOperationException("The image format '" + fmt + "' is unsupported by the video hardware.");
}
public static IosGLImageFormat getImageFormat(Format fmt) throws UnsupportedOperationException {
IosGLImageFormat imageFormat = new IosGLImageFormat();
switch (fmt) {
case RGBA16:
case RGB16:
case RGB10:
case Luminance16:
case Luminance16Alpha16:
case Alpha16:
case Depth32:
case Depth32F:
throw new UnsupportedOperationException("The image format '"
+ fmt + "' is not supported by OpenGL ES 2.0 specification.");
case Alpha8:
imageFormat.format = JmeIosGLES.GL_ALPHA;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
// Highest precision alpha supported by vanilla OGLES2
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4;
}
break;
case Luminance8:
imageFormat.format = JmeIosGLES.GL_LUMINANCE;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
// Highest precision luminance supported by vanilla OGLES2
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565;
}
break;
case Luminance8Alpha8:
imageFormat.format = JmeIosGLES.GL_LUMINANCE_ALPHA;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4;
}
break;
case RGB565:
imageFormat.format = JmeIosGLES.GL_RGB;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_5_6_5;
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565;
break;
case ARGB4444:
imageFormat.format = JmeIosGLES.GL_RGBA4;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_4_4_4_4;
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4;
break;
case RGB5A1:
imageFormat.format = JmeIosGLES.GL_RGBA;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT_5_5_5_1;
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB5_A1;
break;
case RGB8:
imageFormat.format = JmeIosGLES.GL_RGB;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
// Fallback: Use RGB565 if RGBA8 is not available.
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565;
}
break;
case BGR8:
imageFormat.format = JmeIosGLES.GL_RGB;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGB565;
}
break;
case RGBA8:
imageFormat.format = JmeIosGLES.GL_RGBA;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
if (RGBA8) {
imageFormat.renderBufferStorageFormat = GL_RGBA8;
} else {
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_RGBA4;
}
break;
case Depth:
case Depth16:
if (!DEPTH_TEXTURE) {
unsupportedFormat(fmt);
}
imageFormat.format = JmeIosGLES.GL_DEPTH_COMPONENT;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT;
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_DEPTH_COMPONENT16;
break;
case Depth24:
case Depth24Stencil8:
if (!DEPTH_TEXTURE) {
unsupportedFormat(fmt);
}
if (DEPTH24_STENCIL8) {
// NEW: True Depth24 + Stencil8 format.
imageFormat.format = GL_DEPTH_STENCIL_OES;
imageFormat.dataType = GL_UNSIGNED_INT_24_8_OES;
imageFormat.renderBufferStorageFormat = GL_DEPTH24_STENCIL8_OES;
} else {
// Vanilla OGLES2, only Depth16 available.
imageFormat.format = JmeIosGLES.GL_DEPTH_COMPONENT;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_SHORT;
imageFormat.renderBufferStorageFormat = JmeIosGLES.GL_DEPTH_COMPONENT16;
}
break;
case DXT1:
if (!DXT1) {
unsupportedFormat(fmt);
}
imageFormat.format = GL_DXT1;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
imageFormat.compress = true;
break;
case DXT1A:
if (!DXT1) {
unsupportedFormat(fmt);
}
imageFormat.format = GL_DXT1A;
imageFormat.dataType = JmeIosGLES.GL_UNSIGNED_BYTE;
imageFormat.compress = true;
break;
default:
throw new UnsupportedOperationException("Unrecognized format: " + fmt);
}
return imageFormat;
}
public static class IosGLImageFormat {
boolean compress = false;
int format = -1;
int renderBufferStorageFormat = -1;
int dataType = -1;
}
private static void uploadTexture(Image img,
int target,
int index) {
/*
if (img.getEfficentData() instanceof AndroidImageInfo) {
throw new RendererException("This image uses efficient data. "
+ "Use uploadTextureBitmap instead.");
}
*/
// Otherwise upload image directly.
// Prefer to only use power of 2 textures here to avoid errors.
Image.Format fmt = img.getFormat();
ByteBuffer data;
if (index >= 0 || img.getData() != null && img.getData().size() > 0) {
data = img.getData(index);
} else {
data = null;
}
int width = img.getWidth();
int height = img.getHeight();
if (!NPOT) {
// Check if texture is POT
if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) {
throw new RendererException("Non-power-of-2 textures "
+ "are not supported by the video hardware "
+ "and no scaling path available for image: " + img);
}
}
IosGLImageFormat imageFormat = getImageFormat(fmt);
if (data != null) {
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1);
JmeIosGLES.checkGLError();
}
int[] mipSizes = img.getMipMapSizes();
int pos = 0;
if (mipSizes == null) {
if (data != null) {
mipSizes = new int[]{data.capacity()};
} else {
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8};
}
}
for (int i = 0; i < mipSizes.length; i++) {
int mipWidth = Math.max(1, width >> i);
int mipHeight = Math.max(1, height >> i);
if (data != null) {
data.position(pos);
data.limit(pos + mipSizes[i]);
}
if (imageFormat.compress && data != null) {
JmeIosGLES.glCompressedTexImage2D(target,
i,
imageFormat.format,
mipWidth,
mipHeight,
0,
data.remaining(),
data);
} else {
JmeIosGLES.glTexImage2D(target,
i,
imageFormat.format,
mipWidth,
mipHeight,
0,
imageFormat.format,
imageFormat.dataType,
data);
}
JmeIosGLES.checkGLError();
pos += mipSizes[i];
}
}
/**
* Update the texture currently bound to target at with data from the given
* Image at position x and y. The parameter index is used as the zoffset in
* case a 3d texture or texture 2d array is being updated.
*
* @param image Image with the source data (this data will be put into the
* texture)
* @param target the target texture
* @param index the mipmap level to update
* @param x the x position where to put the image in the texture
* @param y the y position where to put the image in the texture
*/
public static void uploadSubTexture(
Image img,
int target,
int index,
int x,
int y) {
//TODO:
/*
if (img.getEfficentData() instanceof AndroidImageInfo) {
AndroidImageInfo imageInfo = (AndroidImageInfo) img.getEfficentData();
uploadTextureBitmap(target, imageInfo.getBitmap(), true, true, x, y);
return;
}
*/
// Otherwise upload image directly.
// Prefer to only use power of 2 textures here to avoid errors.
Image.Format fmt = img.getFormat();
ByteBuffer data;
if (index >= 0 || img.getData() != null && img.getData().size() > 0) {
data = img.getData(index);
} else {
data = null;
}
int width = img.getWidth();
int height = img.getHeight();
if (!NPOT) {
// Check if texture is POT
if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) {
throw new RendererException("Non-power-of-2 textures "
+ "are not supported by the video hardware "
+ "and no scaling path available for image: " + img);
}
}
IosGLImageFormat imageFormat = getImageFormat(fmt);
if (data != null) {
JmeIosGLES.glPixelStorei(JmeIosGLES.GL_UNPACK_ALIGNMENT, 1);
JmeIosGLES.checkGLError();
}
int[] mipSizes = img.getMipMapSizes();
int pos = 0;
if (mipSizes == null) {
if (data != null) {
mipSizes = new int[]{data.capacity()};
} else {
mipSizes = new int[]{width * height * fmt.getBitsPerPixel() / 8};
}
}
for (int i = 0; i < mipSizes.length; i++) {
int mipWidth = Math.max(1, width >> i);
int mipHeight = Math.max(1, height >> i);
if (data != null) {
data.position(pos);
data.limit(pos + mipSizes[i]);
}
if (imageFormat.compress && data != null) {
JmeIosGLES.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, data.remaining(), data);
JmeIosGLES.checkGLError();
} else {
JmeIosGLES.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, imageFormat.dataType, data);
JmeIosGLES.checkGLError();
}
pos += mipSizes[i];
}
}
}

@ -0,0 +1,200 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.system.ios;
import com.jme3.input.*;
import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.ios.IGLESShaderRenderer;
import com.jme3.system.*;
import com.jme3.input.ios.IosInputHandler;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
public class IGLESContext implements JmeContext {
private static final Logger logger = Logger.getLogger(IGLESContext.class.getName());
protected final AtomicBoolean created = new AtomicBoolean(false);
protected final AtomicBoolean renderable = new AtomicBoolean(false);
protected final AtomicBoolean needClose = new AtomicBoolean(false);
protected AppSettings settings = new AppSettings(true);
protected boolean autoFlush = true;
/*
* >= OpenGL ES 2.0 (iOS)
*/
protected IGLESShaderRenderer renderer;
protected Timer timer;
protected SystemListener listener;
protected IosInputHandler input;
protected int minFrameDuration = 0; // No FPS cap
public IGLESContext() {
logger.log(Level.FINE, "IGLESContext constructor");
}
@Override
public JmeContext.Type getType() {
return JmeContext.Type.Display;
}
@Override
public void setSettings(AppSettings settings) {
logger.log(Level.FINE, "IGLESContext setSettings");
this.settings.copyFrom(settings);
if (input != null) {
input.loadSettings(settings);
}
}
@Override
public void setSystemListener(SystemListener listener) {
logger.log(Level.FINE, "IGLESContext setSystemListener");
this.listener = listener;
}
@Override
public AppSettings getSettings() {
return settings;
}
@Override
public com.jme3.renderer.Renderer getRenderer() {
logger.log(Level.FINE, "IGLESContext getRenderer");
return renderer;
}
@Override
public MouseInput getMouseInput() {
return new DummyMouseInput();
}
@Override
public KeyInput getKeyInput() {
return new DummyKeyInput();
}
@Override
public JoyInput getJoyInput() {
/*
if (androidSensorJoyInput == null) {
androidSensorJoyInput = new AndroidSensorJoyInput();
}
return androidSensorJoyInput;
*/
return null;// new DummySensorJoyInput();
}
@Override
public TouchInput getTouchInput() {
return input;
}
@Override
public Timer getTimer() {
return timer;
}
@Override
public void setTitle(String title) {
}
@Override
public boolean isCreated() {
logger.log(Level.FINE, "IGLESContext isCreated");
return created.get();
}
@Override
public void setAutoFlushFrames(boolean enabled) {
this.autoFlush = enabled;
}
@Override
public boolean isRenderable() {
logger.log(Level.FINE, "IGLESContext isRenderable");
return true;// renderable.get();
}
@Override
public void create(boolean waitFor) {
logger.log(Level.FINE, "IGLESContext create");
renderer = new IGLESShaderRenderer();
input = new IosInputHandler();
timer = new NanoTimer();
//synchronized (createdLock){
created.set(true);
//createdLock.notifyAll();
//}
listener.initialize();
if (waitFor) {
//waitFor(true);
}
logger.log(Level.FINE, "IGLESContext created");
}
public void create() {
create(false);
}
@Override
public void restart() {
}
@Override
public void destroy(boolean waitFor) {
logger.log(Level.FINE, "IGLESContext destroy");
listener.destroy();
needClose.set(true);
if (waitFor) {
//waitFor(false);
}
}
public void destroy() {
destroy(true);
}
protected void waitFor(boolean createdVal) {
while (renderable.get() != createdVal) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
}
}
}
}

@ -35,6 +35,7 @@ import com.jme3.asset.AssetLoader;
import com.jme3.asset.DesktopAssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.audio.plugins.WAVLoader;
import com.jme3.texture.Texture;
import java.io.InputStream;
import java.net.URL;
@ -87,8 +88,10 @@ public class IosAssetManager extends DesktopAssetManager {
registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o");
registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt");
registerLoader(WAVLoader.class, "wav");
// Less common loaders (especially on Android)
// Less common loaders (especially on iOS)
registerLoaderSafe("com.jme3.audio.plugins.OGGLoader", "ogg");
registerLoaderSafe("com.jme3.texture.plugins.DDSLoader", "dds");
registerLoaderSafe("com.jme3.texture.plugins.PFMLoader", "pfm");
registerLoaderSafe("com.jme3.texture.plugins.HDRLoader", "hdr");

@ -51,4 +51,11 @@ public abstract class IosHarness extends ObjcNativeObject {
public abstract void appReactivated();
public abstract void appClosed();
public abstract void appUpdate();
public abstract void appDraw();
public abstract void appReshape(int width, int height);
}

@ -33,6 +33,7 @@ package com.jme3.system.ios;
import com.jme3.asset.AssetManager;
import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidOpenALSoftAudioRenderer;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.JmeSystemDelegate;
@ -89,7 +90,7 @@ public class JmeIosSystem extends JmeSystemDelegate {
ctx = new NullContext();
ctx.setSettings(settings);
} else {
ctx = new NullContext();
ctx = new IGLESContext();
ctx.setSettings(settings);
}
return ctx;
@ -97,7 +98,7 @@ public class JmeIosSystem extends JmeSystemDelegate {
@Override
public AudioRenderer newAudioRenderer(AppSettings settings) {
throw new UnsupportedOperationException("Not supported yet.");
return new AndroidOpenALSoftAudioRenderer();
}
@Override

@ -0,0 +1,76 @@
package com.jme3.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Ring buffer (fixed size queue) implementation using a circular array (array
* with wrap-around).
*/
// suppress unchecked warnings in Java 1.5.0_6 and later
@SuppressWarnings("unchecked")
public class RingBuffer<T> implements Iterable<T> {
private T[] buffer; // queue elements
private int count = 0; // number of elements on queue
private int indexOut = 0; // index of first element of queue
private int indexIn = 0; // index of next available slot
// cast needed since no generic array creation in Java
public RingBuffer(int capacity) {
buffer = (T[]) new Object[capacity];
}
public boolean isEmpty() {
return count == 0;
}
public int size() {
return count;
}
public void push(T item) {
if (count == buffer.length) {
throw new RuntimeException("Ring buffer overflow");
}
buffer[indexIn] = item;
indexIn = (indexIn + 1) % buffer.length; // wrap-around
count++;
}
public T pop() {
if (isEmpty()) {
throw new RuntimeException("Ring buffer underflow");
}
T item = buffer[indexOut];
buffer[indexOut] = null; // to help with garbage collection
count--;
indexOut = (indexOut + 1) % buffer.length; // wrap-around
return item;
}
public Iterator<T> iterator() {
return new RingBufferIterator();
}
// an iterator, doesn't implement remove() since it's optional
private class RingBufferIterator implements Iterator<T> {
private int i = 0;
public boolean hasNext() {
return i < count;
}
public void remove() {
throw new UnsupportedOperationException();
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return buffer[i++];
}
}
}

@ -490,15 +490,19 @@ public class LwjglRenderer implements Renderer {
context.depthTestEnabled = false;
}
if (state.isAlphaTest() && context.alphaTestFallOff == 0) {
if (state.isAlphaTest() && !context.alphaTestEnabled) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, state.getAlphaFallOff());
context.alphaTestFallOff = state.getAlphaFallOff();
} else if (!state.isAlphaTest() && context.alphaTestFallOff != 0) {
glAlphaFunc(GL_GREATER, context.alphaTestFallOff);
context.alphaTestEnabled = true;
} else if (!state.isAlphaTest() && context.alphaTestEnabled) {
glDisable(GL_ALPHA_TEST);
context.alphaTestFallOff = 0;
context.alphaTestEnabled = false;
}
if (state.getAlphaFallOff() != context.alphaTestFallOff) {
glAlphaFunc(GL_GREATER, context.alphaTestFallOff);
context.alphaTestFallOff = state.getAlphaFallOff();
}
if (state.isDepthWrite() && !context.depthWriteEnabled) {
glDepthMask(true);
context.depthWriteEnabled = true;
@ -1762,6 +1766,7 @@ public class LwjglRenderer implements Renderer {
case ThreeDimensional:
case CubeMap: // cubemaps use 3D coords
glTexParameteri(target, GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R)));
//There is no break statement on purpose here
case TwoDimensional:
case TwoDimensionalArray:
glTexParameteri(target, GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T)));

@ -130,7 +130,42 @@ public class InputSystemJme implements InputSystem, RawInputListener {
//System.out.format("niftyMouse(%d, %d, %d, true) = %b\n", x, y, button, consumed);
} else {
// Forward the event if nifty owns it or if the cursor is visible.
if (niftyOwnsDragging[button] || inputManager.isCursorVisible()){
//
// 2013-10-06: void256 was here and changed stuff ;-) Explanation:
//
// Currently Nifty remembers any mouse down event internally as "mouse button now down" regardless of it
// hitting a Nifty element. As long as it does not receive a mouse up event, Nifty will think of the mouse
// button as being pressed.
//
// The original code:
// -> if (niftyOwnsDragging[button] || inputManager.isCursorVisible()){
//
// forwarded mouse up events to Nifty when:
// a) Nifty owns dragging, e.g. there was a mouse down event that actually hit a Nifty element before OR
// b) when the jme mouse cursor is visible.
//
// That's ok but the "Nifty remembers the mouse down event" thing had the following consequences in one
// special case:
// 1) You click on the jme scene (not Nifty) and Nifty will correctly return false (event not consumed) but
// internally it remembers: "mouse button is now down". Note that the jme mouse cursor is now hidden.
// 2) You release the mouse button but the mouse down event will not be forwarded to Nifty because it did
// owned the mouse and the jme mouse cursor is not visible.
//
// Nifty now still thinks that the mouse button is down although it's not. The result is that the next click
// on any Nifty element will not be recognized as an initial click by Nifty. So you need an additional click
// on the Nifty element to activate it correctly. In case of drag and drop this additional click was quite
// irritating.
//
// To fix that we'll now forward the mouse button up event ALWAYS to Nifty regardless of it owning the mouse
// or the jme mouse cursor visibility.
//
// Please note: Compared to the original version a side effect is that jme will now always send mouse move
// events to Nifty even when the mouse cursor is hidden. So in theory it could happen that input events are
// handled by both: jme and Nifty when f.i. you move around your scene with the mouse cursor hidden and that
// invisible cursor is moved over some Nifty element. I've not been able to reproduce that case though,
// which is good ;-) If that ever happens to someone there is an easy fix possible:
// nifty.setIgnoreMouseEvents() to completely stop Nifty from processing events.
boolean consumed = nic.processMouseEvent(x, y, 0, button, false);
// Only consume event if it ORIGINATED in nifty!
@ -138,7 +173,7 @@ public class InputSystemJme implements InputSystem, RawInputListener {
evt.setConsumed();
processSoftKeyboard();
}
}
niftyOwnsDragging[button] = false;
//System.out.format("niftyMouse(%d, %d, %d, false) = %b\n", x, y, button, consumed);
}

@ -253,9 +253,12 @@ public abstract class AbstractHeightMap implements HeightMap {
throw new Exception("Filename must not be null");
}
//open the streams and send the height data to the file.
FileOutputStream fos = null;
DataOutputStream dos = null;
try {
FileOutputStream fos = new FileOutputStream(filename);
DataOutputStream dos = new DataOutputStream(fos);
fos = new FileOutputStream(filename);
dos = new DataOutputStream(fos);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
dos.write((int) heightData[j + (i * size)]);
@ -270,6 +273,13 @@ public abstract class AbstractHeightMap implements HeightMap {
} catch (IOException e) {
logger.log(Level.WARNING, "Error writing to file {0}", filename);
return false;
} finally {
if (fos != null) {
fos.close();
}
if (dos != null) {
dos.close();
}
}
logger.log(Level.FINE, "Saved terrain to {0}", filename);

@ -47,6 +47,8 @@ public class TestMusicStreaming extends SimpleApplication {
public void simpleInitApp(){
assetManager.registerLocator("http://www.vorbis.com/music/", UrlLocator.class);
AudioNode audioSource = new AudioNode(assetManager, "Lumme-Badloop.ogg", true);
audioSource.setPositional(false);
audioSource.setReverbEnabled(false);
audioSource.play();
}

@ -10,11 +10,11 @@ source="$2"
if [ -z "$1" ]; then
echo "No platform supplied"
echo "Specify a platform like macosx, windows-x86, linux-x64 and a source like /path/to/jdk/home"
echo "If no source is specified, local/jdk7u11-platform will be used"
echo "If no source is specified, local/jdk-(platform) will be used"
exit 1
fi
if [ -z "$2" ]; then
source="local/jdk7u11-$os"
source="local/jdk-$os"
fi
if [ ! -d "$source" ]; then
echo "Source JDK directory $source was not found, specify another source folder as second parameter or copy the needed JDK to $source"

@ -1,5 +1,5 @@
MacOSX: 1.7u11
Win32: 1.7u11
Win64: 1.7u11
Linux32: 1.7u11
Linux64: 1.7u11
MacOSX: 1.7u51
Win32: 1.7u51
Win64: 1.7u51
Linux32: 1.7u51
Linux64: 1.7u51

@ -1,8 +1,8 @@
build.xml.data.CRC32=f7a25959
build.xml.data.CRC32=daa2838d
build.xml.script.CRC32=6461359b
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=f7a25959
nbproject/build-impl.xml.data.CRC32=daa2838d
nbproject/build-impl.xml.script.CRC32=abd1e01a
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -21,13 +21,13 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.28.1</specification-version>
<specification-version>1.32.1</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
<run-dependency>
<specification-version>1.33.2</specification-version>
<specification-version>1.39.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -45,7 +45,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -54,7 +54,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.26.1</specification-version>
<specification-version>1.31.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -63,7 +63,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.48.1</specification-version>
<specification-version>1.51.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -72,7 +72,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -81,7 +81,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.57.1.8</specification-version>
<specification-version>1.65.1.8</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -89,7 +89,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -97,7 +97,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -105,7 +105,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -113,7 +113,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -121,7 +121,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -129,7 +129,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -137,7 +137,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -1,8 +1,8 @@
build.xml.data.CRC32=5d1ce5ab
build.xml.data.CRC32=4bef7409
build.xml.script.CRC32=03444ead
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=5d1ce5ab
nbproject/build-impl.xml.data.CRC32=4bef7409
nbproject/build-impl.xml.script.CRC32=8812c775
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -30,7 +30,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -38,7 +38,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -46,7 +46,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -54,7 +54,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -62,7 +62,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -70,7 +70,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -3,6 +3,6 @@ build.xml.script.CRC32=c0969383
build.xml.stylesheet.CRC32=a56c6a5b@1.42.2
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=e7b70c27
nbproject/build-impl.xml.data.CRC32=f4e70226
nbproject/build-impl.xml.script.CRC32=4d376df0
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -48,7 +48,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.33.1</specification-version>
<specification-version>1.36.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -57,7 +57,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.28.1</specification-version>
<specification-version>1.32.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -66,7 +66,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.26.1</specification-version>
<specification-version>1.31.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -75,7 +75,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -84,7 +84,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.57.1.8</specification-version>
<specification-version>1.65.1.8</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -93,7 +93,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.35.1</specification-version>
<specification-version>1.38.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -101,7 +101,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.26.1</specification-version>
<specification-version>6.29.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -109,7 +109,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -117,7 +117,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -125,7 +125,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.45.1</specification-version>
<specification-version>6.50.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -133,7 +133,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -141,7 +141,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -149,7 +149,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.32.1</specification-version>
<specification-version>7.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -157,7 +157,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -165,7 +165,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -173,7 +173,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -181,7 +181,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.55.2</specification-version>
<specification-version>6.60.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -1,8 +1,8 @@
build.xml.data.CRC32=950a438b
build.xml.data.CRC32=33d82a49
build.xml.script.CRC32=0f77a514
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=950a438b
nbproject/build-impl.xml.data.CRC32=33d82a49
nbproject/build-impl.xml.script.CRC32=5c5042d6
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -30,7 +30,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.28.1</specification-version>
<specification-version>1.32.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -39,7 +39,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -47,7 +47,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -55,7 +55,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -63,7 +63,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -71,7 +71,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -79,7 +79,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.32.1</specification-version>
<specification-version>7.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -87,7 +87,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -95,7 +95,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -103,7 +103,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -111,7 +111,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.55.2</specification-version>
<specification-version>6.60.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -250,7 +250,10 @@ public class BlenderTool {
}
private static File getBlenderSettingsFolder() {
File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.67", null, false);
File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.69", null, false);
if (blender == null) {
blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.67", null, false);
}
if (blender == null) {
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings"));
logger.log(Level.SEVERE, "Error finding Blender settings");

@ -4,7 +4,6 @@
*/
package com.jme3.gde.blender.filetypes;
import com.jme3.gde.core.assets.SpatialAssetDataObject;
import java.io.IOException;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
@ -20,65 +19,65 @@ import org.openide.util.NbBundle.Messages;
"LBL_Blender3ds_LOADER=3DS Files (via Blender)"
})
@MIMEResolver.ExtensionRegistration(
displayName = "#LBL_Blender3ds_LOADER",
mimeType = "application/x-3ds",
extension = {"3ds", "3DS"})
displayName = "#LBL_Blender3ds_LOADER",
mimeType = "application/x-3ds",
extension = {"3ds", "3DS"})
@DataObject.Registration(
mimeType = "application/x-3ds",
iconBase = "com/jme3/gde/blender/blender.png",
displayName = "#LBL_Blender3ds_LOADER",
position = 300)
mimeType = "application/x-3ds",
iconBase = "com/jme3/gde/blender/blender.png",
displayName = "#LBL_Blender3ds_LOADER",
position = 300)
@ActionReferences({
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.OpenAction"),
position = 100,
separatorAfter = 200),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.OpenAction"),
position = 100,
separatorAfter = 200),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CutAction"),
position = 300),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CutAction"),
position = 300),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CopyAction"),
position = 400,
separatorAfter = 500),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CopyAction"),
position = 400,
separatorAfter = 500),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
position = 600),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
position = 600),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.RenameAction"),
position = 700,
separatorAfter = 800),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.RenameAction"),
position = 700,
separatorAfter = 800),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"),
position = 900,
separatorAfter = 1000),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"),
position = 900,
separatorAfter = 1000),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.FileSystemAction"),
position = 1100,
separatorAfter = 1200),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.FileSystemAction"),
position = 1100,
separatorAfter = 1200),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
position = 1300),
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
position = 1300),
@ActionReference(
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.PropertiesAction"),
position = 1400)
path = "Loaders/application/x-3ds/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.PropertiesAction"),
position = 1400)
})
public class Blender3dsDataObject extends AbstractBlenderImportDataObject {

@ -0,0 +1,93 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.gde.blender.filetypes;
import java.io.IOException;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.MIMEResolver;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectExistsException;
import org.openide.loaders.MultiFileLoader;
import org.openide.util.NbBundle.Messages;
@Messages({
"LBL_BlenderFbx_LOADER=Files of BlenderFbx"
})
@MIMEResolver.ExtensionRegistration(
displayName = "#LBL_BlenderFbx_LOADER",
mimeType = "application/fbx",
extension = {"fbx"})
@DataObject.Registration(
mimeType = "application/fbx",
iconBase = "com/jme3/gde/blender/blender.png",
displayName = "#LBL_BlenderFbx_LOADER",
position = 300)
@ActionReferences({
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.OpenAction"),
position = 100,
separatorAfter = 200),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CutAction"),
position = 300),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.CopyAction"),
position = 400,
separatorAfter = 500),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
position = 600),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.RenameAction"),
position = 700,
separatorAfter = 800),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"),
position = 900,
separatorAfter = 1000),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.FileSystemAction"),
position = 1100,
separatorAfter = 1200),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
position = 1300),
@ActionReference(
path = "Loaders/application/fbx/Actions",
id =
@ActionID(category = "System", id = "org.openide.actions.PropertiesAction"),
position = 1400)
})
public class BlenderFbxDataObject extends AbstractBlenderImportDataObject {
public BlenderFbxDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
super(pf, loader);
SUFFIX = "fbx";
// registerEditor("application/fbx", false);
}
// @Override
// protected int associateLookup() {
// return 1;
// }
}

@ -30,6 +30,7 @@ public class Scripts {
}
checkScript(folder, "import_3ds.py");
checkScript(folder, "import_dae.py");
checkScript(folder, "import_fbx.py");
}
private static void checkScript(FileObject folder, String name) {

@ -0,0 +1,83 @@
# This script invokes blender to import and save external model formats as
# .blend files to be processed further.
#
# Example usage for this importer:
# blender --background --factory-startup --python $HOME/import_3ds.py -- \
# --i="/tmp/hello.3ds" \
# --o="/tmp/hello.blend" \
#
# See blender --help for details.
import bpy
# Imports a file using importer
def import_file(file_path):
# Import the model
bpy.ops.import_scene.fbx(filepath = file_path)
# Clear existing objects.
def clear_scene():
scene = bpy.context.scene
scene.camera = None
for obj in scene.objects:
scene.objects.unlink(obj)
# Save current scene as .blend file
def save_file(save_path):
# Check if output file exists already
try:
f = open(save_path, 'w')
f.close()
ok = True
except:
print("Cannot save to path %r" % save_path)
import traceback
traceback.print_exc()
# Save .blend file
if ok:
bpy.ops.wm.save_as_mainfile(filepath=save_path)
def main():
import sys # to get command line args
import argparse # to parse options for us and print a nice help message
# get the args passed to blender after "--", all of which are ignored by
# blender so scripts may receive their own arguments
argv = sys.argv
if "--" not in argv:
argv = [] # as if no args are passed
else:
argv = argv[argv.index("--") + 1:] # get all args after "--"
# When --help or no args are given, print this help
usage_text = \
"Run blender in background mode with this script:"
" blender --background --factory-startup --python " + __file__ + " -- [options]"
parser = argparse.ArgumentParser(description=usage_text)
# Possible types are: string, int, long, choice, float and complex.
parser.add_argument("-i", "--input", dest="file_path", metavar='FILE',
help="Import the specified file")
parser.add_argument("-o", "--output", dest="save_path", metavar='FILE',
help="Save the generated file to the specified path")
args = parser.parse_args(argv) # In this example we wont use the args
if not argv:
parser.print_help()
return
# Run the conversion
clear_scene()
import_file(args.file_path)
save_file(args.save_path)
print("batch job finished, exiting")
if __name__ == "__main__":
main()

@ -1,8 +1,8 @@
build.xml.data.CRC32=39a997e3
build.xml.data.CRC32=40119967
build.xml.script.CRC32=d8082083
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=39a997e3
nbproject/build-impl.xml.data.CRC32=40119967
nbproject/build-impl.xml.script.CRC32=a2681ce5
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -39,7 +39,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.35.1</specification-version>
<specification-version>1.38.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -47,7 +47,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -55,7 +55,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -63,7 +63,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -71,7 +71,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -79,7 +79,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -87,7 +87,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -95,7 +95,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -103,7 +103,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.55.2</specification-version>
<specification-version>6.60.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -1,8 +1,8 @@
build.xml.data.CRC32=11faf2dd
build.xml.data.CRC32=e5661c7c
build.xml.script.CRC32=a481f885
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=11faf2dd
nbproject/build-impl.xml.data.CRC32=e5661c7c
nbproject/build-impl.xml.script.CRC32=0691bb76
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -21,7 +21,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.40.1</specification-version>
<specification-version>1.43.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -29,7 +29,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.10.1.3</specification-version>
<specification-version>7.13.1.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -38,7 +38,7 @@
<compile-dependency/>
<run-dependency>
<release-version>3</release-version>
<specification-version>1.63.1.5.20.32</specification-version>
<specification-version>1.71.2.5.21.40</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -47,7 +47,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.61.1.32</specification-version>
<specification-version>1.71.2.40</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -73,7 +73,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>0.104.2.23.1.19.6</specification-version>
<specification-version>0.110.3.23.1.20.6</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -82,7 +82,7 @@
<compile-dependency/>
<run-dependency>
<release-version>0-1</release-version>
<specification-version>1.25.1.7.32</specification-version>
<specification-version>1.28.3.7.40</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -90,7 +90,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -98,7 +98,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -106,7 +106,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -114,7 +114,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -122,7 +122,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.49.3</specification-version>
<specification-version>6.54.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -130,7 +130,15 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.openide.util.lookup</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -1,8 +1,8 @@
build.xml.data.CRC32=77dd4012
build.xml.data.CRC32=05673774
build.xml.script.CRC32=27967d2c
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=77dd4012
nbproject/build-impl.xml.data.CRC32=05673774
nbproject/build-impl.xml.script.CRC32=c9af9eda
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -12,7 +12,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.26.1.1</specification-version>
<specification-version>1.30.1.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -21,7 +21,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -30,7 +30,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.32.1</specification-version>
<specification-version>1.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -38,7 +38,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -46,7 +46,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.49.3</specification-version>
<specification-version>6.54.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -54,7 +54,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -62,7 +62,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -1,8 +1,8 @@
build.xml.data.CRC32=71ea1e3c
build.xml.data.CRC32=618a92db
build.xml.script.CRC32=cfa8d5c5
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
build.xml.stylesheet.CRC32=a56c6a5b@2.56.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=71ea1e3c
nbproject/build-impl.xml.data.CRC32=618a92db
nbproject/build-impl.xml.script.CRC32=270846fb
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -9,7 +9,7 @@
<dependency>
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
<run-dependency>
<specification-version>1.33.2</specification-version>
<specification-version>1.39.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -17,7 +17,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.32.1</specification-version>
<specification-version>7.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -25,7 +25,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -43,7 +43,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.1.0</specification-version>
<specification-version>1.1.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -52,7 +52,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.21.1</specification-version>
<specification-version>1.24.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -61,7 +61,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.40.1</specification-version>
<specification-version>1.43.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -70,7 +70,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.33.1</specification-version>
<specification-version>1.36.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -79,7 +79,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.28.1</specification-version>
<specification-version>1.32.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -87,13 +87,13 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.10.1.3</specification-version>
<specification-version>7.13.1.3</specification-version>
</run-dependency>
</dependency>
<dependency>
<code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
<run-dependency>
<specification-version>1.33.2</specification-version>
<specification-version>1.39.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -102,7 +102,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.30.1.1</specification-version>
<specification-version>1.33.1.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -111,7 +111,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.61.1.32</specification-version>
<specification-version>1.71.2.40</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -120,7 +120,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.26.1</specification-version>
<specification-version>1.29.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -138,7 +138,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -146,7 +146,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>0.104.2.23.1.19.6</specification-version>
<specification-version>0.110.3.23.1.20.6</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -155,7 +155,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.26.1</specification-version>
<specification-version>1.31.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -164,7 +164,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.48.1</specification-version>
<specification-version>1.51.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -173,7 +173,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.36.1</specification-version>
<specification-version>1.41.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -182,7 +182,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -191,7 +191,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.57.1.8</specification-version>
<specification-version>1.65.1.8</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -200,7 +200,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.35.1</specification-version>
<specification-version>1.38.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -209,7 +209,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.23.1</specification-version>
<specification-version>1.27.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -218,7 +218,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.32.1</specification-version>
<specification-version>1.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -226,7 +226,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.26.1</specification-version>
<specification-version>6.29.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -234,7 +234,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.46.1</specification-version>
<specification-version>7.55.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -242,7 +242,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.25.1</specification-version>
<specification-version>7.28.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -250,7 +250,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.45.1</specification-version>
<specification-version>6.50.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -258,7 +258,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -266,7 +266,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.31.2</specification-version>
<specification-version>1.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -274,7 +274,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.37.3</specification-version>
<specification-version>7.44.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -282,7 +282,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.32.1</specification-version>
<specification-version>7.35.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -290,7 +290,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.28.1</specification-version>
<specification-version>7.33.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -298,7 +298,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.49.3</specification-version>
<specification-version>6.54.2</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -306,7 +306,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -314,7 +314,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -322,7 +322,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>6.55.2</specification-version>
<specification-version>6.60.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -35,6 +35,7 @@ import com.jme3.gde.core.filters.actions.EnableFiterAction;
import com.jme3.gde.core.icons.IconList;
import com.jme3.gde.core.properties.SceneExplorerProperty;
import com.jme3.gde.core.properties.ScenePropertyChangeListener;
import com.jme3.gde.core.scene.SceneSyncListener;
import com.jme3.gde.core.util.PropertyUtils;
import com.jme3.post.Filter;
import java.awt.Image;
@ -59,7 +60,7 @@ import org.openide.util.actions.SystemAction;
* @author normenhansen
*/
@SuppressWarnings("unchecked")
public abstract class AbstractFilterNode extends AbstractNode implements FilterNode, ScenePropertyChangeListener {
public abstract class AbstractFilterNode extends AbstractNode implements FilterNode, ScenePropertyChangeListener, SceneSyncListener {
protected boolean readOnly = false;
protected DataObject dataObject;
@ -112,6 +113,18 @@ public abstract class AbstractFilterNode extends AbstractNode implements FilterN
};
}
public void syncSceneData(float tpf) {
//TODO: precache structure to avoid locks? Do it backwards, sending the actual bean value?
for (PropertySet propertySet : getPropertySets()) {
for (Property<?> property : propertySet.getProperties()) {
if(property instanceof SceneExplorerProperty){
SceneExplorerProperty prop = (SceneExplorerProperty)property;
prop.syncValue();
}
}
}
}
@Override
public Action getPreferredAction() {
return Actions.alwaysEnabled(new EnableFiterAction(this), "Toggle enabled", "", false);
@ -222,8 +235,10 @@ public abstract class AbstractFilterNode extends AbstractNode implements FilterN
if (name.equals("Name")) {
setName((String)after);
}
fireSave(true);
firePropertyChange(name, before, after);
if (!SceneExplorerProperty.PROP_INIT_CHANGE.equals(type)) {
fireSave(true);
}
}
public Filter getFilter() {

@ -21,7 +21,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.46.1</specification-version>
<specification-version>1.50.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -30,7 +30,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>1.57.1.8</specification-version>
<specification-version>1.65.1.8</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -38,7 +38,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>7.62.1</specification-version>
<specification-version>8.5.1</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -46,7 +46,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.25.2</specification-version>
<specification-version>8.29.3</specification-version>
</run-dependency>
</dependency>
<dependency>
@ -54,7 +54,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>8.15.2</specification-version>
<specification-version>8.19.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -3,6 +3,6 @@ build.xml.script.CRC32=20380530
build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=04f2ab5a
nbproject/build-impl.xml.data.CRC32=ff76c7e7
nbproject/build-impl.xml.script.CRC32=0cdd5704
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.56.1

@ -12,7 +12,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
<specification-version>2.27.1</specification-version>
<specification-version>2.30.1</specification-version>
</run-dependency>
</dependency>
</module-dependencies>

@ -83,7 +83,7 @@ To export your models as Ogre <acronym title="Extensible Markup Language">XML</a
<p>
You can now use the <a href="/com/jme3/gde/docs/sdk.html">jMonkeyEngine SDK</a> to <a href="/com/jme3/gde/docs/sdk/model_loader_and_viewer.html">load and view models</a>. You can <a href="/com/jme3/gde/docs/sdk/scene_composer.html">create scenes</a> from them and write cde that loads them into your application.
You can now use the <a href="/com/jme3/gde/docs/sdk.html">jMonkeyEngine SDK</a> to <a href="/com/jme3/gde/docs/sdk/model_loader_and_viewer.html">load and view models</a>. You can <a href="/com/jme3/gde/docs/sdk/scene_composer.html">create scenes</a> from them and write code that loads them into your application.
</p>
</div>

@ -4,16 +4,16 @@
<p>
The <code>com.jme3.app.state.AppState</code> class is a customizable jME3 interface that allows you to control the global game logic ??? the overall game mechanics. (To control the behaviour of a Spatial, see <a href="/com/jme3/gde/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead. Controls and AppStates can be used together.)
The <code>com.jme3.app.state.AppState</code> class is a customizable jME3 interface that allows you to control the global game logic, the overall game mechanics. (To control the behaviour of a Spatial, see <a href="/com/jme3/gde/docs/jme3/advanced/custom_controls.html">Custom Controls</a> instead. Controls and AppStates can be used together.)
</p>
</div>
<!-- EDIT1 SECTION "Application States" [1-324] -->
<!-- EDIT1 SECTION "Application States" [1-322] -->
<h2><a>Overview</a></h2>
<div>
</div>
<!-- EDIT2 SECTION "Overview" [325-346] -->
<!-- EDIT2 SECTION "Overview" [323-344] -->
<h3><a>Use Case Examples</a></h3>
<div>
@ -56,7 +56,7 @@ You can! This is what AppStates are there for. An AppState class is subset of (o
</ul>
</div>
<!-- EDIT3 SECTION "Use Case Examples" [347-2034] -->
<!-- EDIT3 SECTION "Use Case Examples" [345-2032] -->
<h3><a>Supported Features</a></h3>
<div>
@ -86,7 +86,7 @@ Each AppState has its own update loop, which hooks into the main simpleUpdate()
</p>
</div>
<!-- EDIT4 SECTION "Supported Features" [2035-3763] -->
<!-- EDIT4 SECTION "Supported Features" [2033-3761] -->
<h3><a>Usage</a></h3>
<div>
@ -109,7 +109,7 @@ To implement game logic:
</li>
<li><div> Enable and disable (unpause and pause) the AppStates that you need during the game.</div>
</li>
<li><div> Detach the AppState from the AppStateManager (<code>stateManager.detach(myAppState);</code>) and clean it up it.</div>
<li><div> Detach the AppState from the AppStateManager (<code>stateManager.detach(myAppState);</code>) and clean it up.</div>
</li>
</ol>
@ -119,7 +119,7 @@ When you add several AppStates to one Application and activate them, their initi
</p>
</div>
<!-- EDIT5 SECTION "Usage" [3764-4625] -->
<!-- EDIT5 SECTION "Usage" [3762-4620] -->
<h3><a>Code Samples</a></h3>
<div>
@ -139,7 +139,7 @@ JME3 comes with a BulletAppState that implements Physical behaviour (using the j
</ul>
</div>
<!-- EDIT6 SECTION "Code Samples" [4626-5406] -->
<!-- EDIT6 SECTION "Code Samples" [4621-5401] -->
<h2><a>AppState</a></h2>
<div>
@ -184,9 +184,9 @@ stateDetached(asm)</td><td>The AppState knows when it is attached to, or detache
<td>postRender()</td><td>Called after all rendering commands are flushed, including your optional customizations. (Typically not used.)</td>
</tr>
</table></div>
<!-- EDIT8 TABLE [5555-7117] -->
<!-- EDIT8 TABLE [5550-7112] -->
</div>
<!-- EDIT7 SECTION "AppState" [5407-7118] -->
<!-- EDIT7 SECTION "AppState" [5402-7113] -->
<h2><a>AbstractAppState</a></h2>
<div>
@ -249,7 +249,7 @@ Definition:
&#125;</pre>
</div>
<!-- EDIT9 SECTION "AbstractAppState" [7119-9291] -->
<!-- EDIT9 SECTION "AbstractAppState" [7114-9286] -->
<h2><a>Pausing and Unpausing</a></h2>
<div>
@ -259,7 +259,7 @@ You define what an AppState does when Paused or Unpaused, in the <code>setEnable
</p>
</div>
<!-- EDIT10 SECTION "Pausing and Unpausing" [9292-9582] -->
<!-- EDIT10 SECTION "Pausing and Unpausing" [9287-9577] -->
<h2><a>AppStateManager</a></h2>
<div>
@ -279,7 +279,7 @@ The com.jme3.app.state.AppStateManager holds the list of AppStates for an applic
<td>getState(MyAppState.class)</td><td>Returns the first attached state that is an instance of a subclass of <code>MyAppState.class</code>.</td>
</tr>
</table></div>
<!-- EDIT12 TABLE [9990-10200] -->
<!-- EDIT12 TABLE [9985-10195] -->
<p>
The AppStateManager&#039;s <code>render(), postRender(), cleanup()</code> methods are internal, ignore them, users never call them directly.
@ -299,12 +299,12 @@ The AppStateManager&#039;s <code>render(), postRender(), cleanup()</code> method
</ul>
</div>
<!-- EDIT11 SECTION "AppStateManager" [9583-10966] -->
<!-- EDIT11 SECTION "AppStateManager" [9578-10961] -->
<h2><a>Best Practices</a></h2>
<div>
</div>
<!-- EDIT13 SECTION "Best Practices" [10967-10994] -->
<!-- EDIT13 SECTION "Best Practices" [10962-10989] -->
<h3><a>Communication Among AppStates</a></h3>
<div>
@ -320,7 +320,7 @@ You can use custom accessors to get data from AppStates, to set data in AppState
<pre>this.app.getStateManager&#40;&#41;.getState&#40;MyAppState.class&#41;.doSomeCustomStuffInThisState&#40;&#41;;</pre>
</div>
<!-- EDIT14 SECTION "Communication Among AppStates" [10995-11750] -->
<!-- EDIT14 SECTION "Communication Among AppStates" [10990-11745] -->
<h3><a>Initialize Familiar Class Fields</a></h3>
<div>
@ -351,5 +351,5 @@ public class MyAppState extends AbstractAppState &#123;
&#125;</pre>
</div>
<!-- EDIT15 SECTION "Initialize Familiar Class Fields" [11751-] -->
<!-- EDIT15 SECTION "Initialize Familiar Class Fields" [11746-] -->
<p><em><a href="http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:application_states?do=export_xhtmlbody">view online version</a></em></p>

@ -50,7 +50,7 @@ AudioNode boom = new AudioNode&#40;assetManager, &quot;Sound/boom.wav&quot;, fal
<th>AudioNode Method</th><th>Usage</th>
</tr>
<tr>
<td>getStatus()</td><td>Returns either Status.Playing, Status.Stopped, or Status.Paused. </td>
<td>getStatus()</td><td>Returns either AudioSource.Status.Playing, AudioSource.Status.Stopped, or AudioSource.Status.Paused. </td>
</tr>
<tr>
<td>getVolume()</td><td>Returns the volume. </td>
@ -59,14 +59,13 @@ AudioNode boom = new AudioNode&#40;assetManager, &quot;Sound/boom.wav&quot;, fal
<td>getPitch()</td><td>Returns the pitch. </td>
</tr>
</table></div>
<!-- EDIT5 TABLE [1882-2054] -->
<!-- EDIT5 TABLE [1882-2090] -->
<p>
Note: There are other obvious getters to poll the status of all corresponding setters listed here.
</p>
</div>
<!-- EDIT4 SECTION "Getting AudioNode Properties" [1840-2155] -->
<!-- EDIT4 SECTION "Getting AudioNode Properties" [1840-2192] -->
<h2><a>Setting AudioNode Properties</a></h2>
<div>
<div><table>
@ -92,9 +91,9 @@ Note: There are other obvious getters to poll the status of all corresponding se
<td>setLooping(false)</td><td>Configures the sound so that, if it is played, it plays once and stops. No looping is the default.</td>
</tr>
</table></div>
<!-- EDIT7 TABLE [2198-3327] -->
<!-- EDIT7 TABLE [2235-3364] -->
</div>
<!-- EDIT6 SECTION "Setting AudioNode Properties" [2156-3328] -->
<!-- EDIT6 SECTION "Setting AudioNode Properties" [2193-3365] -->
<h3><a>Looping &amp; Ambient Sounds</a></h3>
<div>
<div><table>
@ -110,9 +109,9 @@ setDirectional(false)</td><td>All 3D effects switched off. This sound is global
<strong>Looping does not work on streamed sounds.</strong> </td>
</tr>
</table></div>
<!-- EDIT9 TABLE [3365-3846] -->
<!-- EDIT9 TABLE [3402-3883] -->
</div>
<!-- EDIT8 SECTION "Looping & Ambient Sounds" [3329-3847] -->
<!-- EDIT8 SECTION "Looping & Ambient Sounds" [3366-3884] -->
<h3><a>Positional 3D Sounds</a></h3>
<div>
<div><table>
@ -127,7 +126,7 @@ setLocalTranslation(???)</td><td>Activates 3D audio: The sound appears to come f
<td>setReverbEnabled(true)</td><td>Reverb is a 3D echo effect that only makes sense with positional AudioNodes. Use Audio Environments to make scenes sound as if they were &quot;outdoors&quot;, or &quot;indoors&quot; in a large or small room, etc. The reverb effect is defined by the <code>com.jme3.audio.Environment</code> that the <code>audioRenderer</code> is in. See &quot;Setting Audio Environment Properties&quot; below. </td>
</tr>
</table></div>
<!-- EDIT11 TABLE [3880-4496] -->
<!-- EDIT11 TABLE [3917-4533] -->
<p>
<p><div>Positional 3D sounds require an <code>AudioListener</code> object in the scene (representing the player&#039;s ears).
@ -135,7 +134,7 @@ setLocalTranslation(???)</td><td>Activates 3D audio: The sound appears to come f
</p>
</div>
<!-- EDIT10 SECTION "Positional 3D Sounds" [3848-4625] -->
<!-- EDIT10 SECTION "Positional 3D Sounds" [3885-4662] -->
<h3><a>Directional 3D Sounds</a></h3>
<div>
<div><table>
@ -151,7 +150,7 @@ setDirection(???) </td><td>Activates 3D audio: This sound can only be heard from
setOuterAngle()</td><td>Set the angle in degrees for the directional audio. The angle is relative to the direction. Note: By default, both angles are 360?? and the sound can be heard from all directions!</td>
</tr>
</table></div>
<!-- EDIT13 TABLE [4659-5186] -->
<!-- EDIT13 TABLE [4696-5223] -->
<p>
<p><div>Directional 3D sounds require an AudioListener object in the scene (representing the player&#039;s ears).
@ -159,7 +158,7 @@ setOuterAngle()</td><td>Set the angle in degrees for the directional audio. The
</p>
</div>
<!-- EDIT12 SECTION "Directional 3D Sounds" [4626-5313] -->
<!-- EDIT12 SECTION "Directional 3D Sounds" [4663-5350] -->
<h2><a>Play, Pause, Stop</a></h2>
<div>
@ -181,7 +180,7 @@ You can also start playing instances of an AudioNode. Use the <code>playInstance
<pre>myAudioNode.playInstance&#40;&#41;;</pre>
</div>
<!-- EDIT14 SECTION "Play, Pause, Stop" [5314-6018] -->
<!-- EDIT14 SECTION "Play, Pause, Stop" [5351-6055] -->
<h2><a>The Audio Listener</a></h2>
<div>
@ -197,7 +196,7 @@ The default AudioListener object <code>listener</code> in <code>SimpleApplicatio
&#125;</pre>
</div>
<!-- EDIT15 SECTION "The Audio Listener" [6019-6655] -->
<!-- EDIT15 SECTION "The Audio Listener" [6056-6692] -->
<h2><a>Setting Audio Environment Properties</a></h2>
<div>
@ -226,7 +225,7 @@ Optionally, You can choose from the following environmental presets from <code>c
<td>Closet </td><td>1.00f</td><td>1.0f</td><td>1.0f</td><td>1.00f</td><td>0.15f</td><td>1.0f</td><td>0.600f</td><td>0.0025f</td><td>0.500f</td><td>0.0006f</td>
</tr>
</table></div>
<!-- EDIT17 TABLE [7098-7587] --><ol>
<!-- EDIT17 TABLE [7135-7624] --><ol>
<li><div> Activate a Environment preset</div>
<ul>
<li><div> Either use a default, e.g. make you scene sounds like a dungeon environment: <pre>audioRenderer.setEnvironment&#40;new Environment&#40;Environment.Dungeon&#41;&#41;;</pre>
@ -266,5 +265,5 @@ Advanced users find more info about OpenAL and its features here: <object classi
</span></div>
</div>
<!-- EDIT16 SECTION "Setting Audio Environment Properties" [6656-] -->
<!-- EDIT16 SECTION "Setting Audio Environment Properties" [6693-] -->
<p><em><a href="http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:audio?do=export_xhtmlbody">view online version</a></em></p>

@ -571,7 +571,7 @@ public class Advanced extends SimpleApplication &#123;
&nbsp;
public void simpleUpdate&#40;float tpf&#41; &#123;
motionTimer.update&#40;&#41;;
if &#40;music.getStatus&#40;&#41; != AudioNode.Status.Playing&#41;&#123;
if &#40;music.getStatus&#40;&#41; != AudioSource.Status.Playing&#41;&#123;
music.play&#40;&#41;;
&#125;
Vector3f loc = cam.getLocation&#40;&#41;;
@ -600,7 +600,7 @@ The <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param
</p>
</div>
<!-- EDIT6 SECTION "Advanced Example" [7328-17231] -->
<!-- EDIT6 SECTION "Advanced Example" [7328-17233] -->
<h3><a>Using Advanced features to Record from more than one perspective at once</a></h3>
<div>
@ -621,7 +621,7 @@ The <object classid="java:org.netbeans.modules.javahelp.BrowserDisplayer"><param
</p>
</div>
<!-- EDIT7 SECTION "Using Advanced features to Record from more than one perspective at once" [17232-17373] -->
<!-- EDIT7 SECTION "Using Advanced features to Record from more than one perspective at once" [17234-17375] -->
<h2><a>More Information</a></h2>
<div>
@ -653,5 +653,5 @@ listeners can be found here.
</p>
</div>
<!-- EDIT8 SECTION "More Information" [17374-] -->
<!-- EDIT8 SECTION "More Information" [17376-] -->
<p><em><a href="http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:capture_audio_video_to_a_file?do=export_xhtmlbody">view online version</a></em></p>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save