Compare commits

...

78 Commits
master ... v3.3

Author SHA1 Message Date
Stephen Gold 1ab3e92d04 jme3-examples: add TestIssue796 5 years ago
Stephen Gold 1a05e3fc5f make TestMorph (in jme3-examples) more user-friendly 5 years ago
Github Actions c303c899b9 [skip ci] update natives snapshot 5 years ago
Stephen Gold 9f026b41ca enable the main.yml workflow for v3.3 branch 5 years ago
Stephen Gold d785a03ec1 update jmeVersion to 3.3.1 in gradle.properties 5 years ago
Stephen Gold 618e890ddb Fix issue 1360: ArmatureDebugAppState causes OpenGLException 5 years ago
Stephen Gold 1284671d6f T key had to be pressed 2x before worked in jme3test.terrain (4 files) 5 years ago
Stephen Gold d5339a1ec0 improve initial camera orientations in jme3test.terrain (9 files) 5 years ago
Stephen Gold 1491ffe775 remove an unused empty file jme3test/light/DlsfError.java 5 years ago
rvandoosselaer 4b62b70a5b Set the minimum required OpenGL profiles for the geometry and tessellation shader test cases. Resolves #1357 5 years ago
Stephen Gold 9a5b3864b2 remove an unused empty file jme3test/collision/Main.java 5 years ago
Stephen Gold f71c312338 Fixes issue #1350 for getters (MorphTrack documentation) 5 years ago
Stephen Gold e09adbf014 Fixes issue #1350 (MorphTrack documentation) 5 years ago
Stephen Gold 415a52df51 convert tabs to blanks in FixedScale100.frag 5 years ago
Stephen Gold 5d969f29a1 correct a typographic error in TestUseAfterFree output 5 years ago
Stephen Gold a667f5e8cd Revert "Fixes issue #1336: AWTPanels forcing OpenGL 2.0 (Compat Profile)" 5 years ago
Stephen Gold a150deb8be improve format and rm trailing whitespace (10 files in com.jme3.opencl) 5 years ago
Stephen Gold 1fa283f06a correct the javadoc of Matrix4f.set(float[][]) -- missing "not"! 5 years ago
Stephen Gold 06a8a056c1 clarify the javadoc of Quaternion.toString() "displaced"? 5 years ago
Stephen Gold d99c378bdc add missing javadoc tags to BufferUtils 5 years ago
Stephen Gold 33ebbef214 add some missing javadoc (2 files in com.jme3.util) 5 years ago
Stephen Gold 84912d5803 Fixes issue #1336: AWTPanels forcing OpenGL 2.0 (Compat Profile) 5 years ago
Stephen Gold e1d5e3c64d FastMathTest: test the reversibility of coordinate transformations 5 years ago
Stephen Gold a1fb4837f5 add missing javadoc tags to 10 files in the com.jme3.math package 5 years ago
Stephen Gold 72de37be21 resolve an unknown HTML tag in the ColorRGBA javadoc 5 years ago
Stephen Gold 4731069110 javadoc correction: Quaternion.negate() doesn't "invert" anything 5 years ago
Stephen Gold 8896cd5a68 don't refer to transforms as "matrices" in the Transform javadoc 5 years ago
Stephen Gold ede7af0573 remove the javadoc reference to the mythical USE_FAST_TRIG setting 5 years ago
Stephen Gold a124fcd284 remove all javadoc references to the mythical JmeException 5 years ago
Stephen Gold e98df18a9c improve formatting and rm trailing whitespace (16 files in jme3-core) 5 years ago
Stephen Gold ce862bc09e IndexBuffer: resolve a javadoc warning 5 years ago
Stephen Gold 3a5f9661ab jme3-terrain: handle 2 more ByteBuffer cases 5 years ago
matthias plasser c85e2bcfd4 Fixes #1341: AudioBuffer.updateData only allows direct buffers (#1342) 5 years ago
Stephen Gold 98a283beb6 remove unnecessary casts and tests for null, discovered using NetBeans (#1285) 5 years ago
rvandoosselaer 9a84e72f03 Clean up the test case and add some more context. #1340 5 years ago
rvandoosselaer 227de6f22a Add a check to see if the NB_PROBES identifier is defined. Fixes #1340 5 years ago
rvandoosselaer ded268a660 Add a check to see if the NB_PROBES identifier is defined. Fixes #1340 5 years ago
Riccardo Balbo 6d2ea28108 Fix last query not closed in profiler 5 years ago
Ali-RS 0bdb0159be Fixed an issue with AndroidNativeImageLoader which was opening stream twice. (#1338) 5 years ago
Stephen Gold 969e2808e4 correct some typographic errors in Billboard100.frag comments 5 years ago
Stephen Gold a96dbe8604 elimiate incidental hard tabs from jme3-examples 5 years ago
Stephen Gold efc9c443de elimiate incidental hard tabs from jme3-core 5 years ago
Jérôme 1acd1d299a Removes tabs 5 years ago
Jérôme 0e0c75c85c Migrate TestOgreComplexAnim to new anim system 5 years ago
Jérôme 61cbaa72ee Migrate TestBlenderObjectAnim to new anim system 5 years ago
Jérôme 821a18be21 Migrate TestCutomAnim to the new Animation system 5 years ago
Jérôme 68c6f71c73 Migrate TestSpatialAnim to the new Anim class 5 years ago
Grabli66 21cbdb5da3 Fixes error of loading assets 5 years ago
MeFisto94 7e3ae5e8ca Fixes #1319 - LWJGL2: start(true) should not freeze when context could not be initialized 5 years ago
MeFisto94 828ca9212a UBO: Re-order the caps detection for a more clean code. 5 years ago
MeFisto94 5100d0b995 UBO: GL_INVALID_ENUM on Mesa 5 years ago
MeFisto94 66f316b3aa Fixes SSBO causing GL_INVALID_ENUM in Debug Mode 5 years ago
MeFisto94 f68d88937f GLSLCompat: The Matrix3 Sub-Constructor is called mat3_sub and defers to the builtin mat3 if available. 5 years ago
MeFisto94 728a07a25f Fixing PBR on <= GLSL 130: 5 years ago
MeFisto94 4c2c3fa375 GLDebug: Throw an IllegalArgumentException instead of an IllegalStateException 5 years ago
MeFisto94 00281b21a1 GLDebug: Throw an unchecked exception instead of returning null to enforce a crash when glGetError is not present. 5 years ago
MeFisto94 b00c245e8e GLDebug: Use a method handle instead of a string comparison to increase the performance 5 years ago
Stephen Gold 9be8f5dd3a Use a reflection-based approach to call checkError() after every call to the openGL API to reduce Code Duplication and increase Maintainability, while also fixing the regression caused by GLDebugDesktop extending from GLDebugES and thus making the Renderer think it is on mobile. 5 years ago
MeFisto94 9dfbcde88c Fixes #1304 - Don't use mat3() constructor to keep compatibility with GLSL110 5 years ago
Riccardo Balbo 391e0dc6d0 Update checkout action to v2 5 years ago
Toni Helenius 1e7e12ee69 Fix for resizing the window (issue 1191) (#1308) 5 years ago
Stephen Gold f0e09b2a9e main.yml: add Gradle-wrapper validation to several jobs 5 years ago
Toni Helenius 1198908555 Lwjgl3 restart input handle (#1268) 5 years ago
Stephen Gold fecd018fae BufferUtils: resolve issue #1288 (rewrite isDirect()) (#1299) 5 years ago
Stephen Gold b102eabb56 Fixes issue #1286 5 years ago
Riccardo Balbo 836455826b Fix openal-soft dead link 5 years ago
Riccardo Balbo 3c93e50d99 Update link for stb_image.h 5 years ago
Ali-RS 78779ffe0a Removed extra PostShadow Technique from PBRLighting.j3md (#1273) 5 years ago
Toni Helenius 9002d088e7 Issue 801 (#1269) 5 years ago
Ryan McDonough 753c3cc173 PreShadow & PostShadow Support for PBRLighting.j3md (#1265) 5 years ago
MeFisto94 55a36abe9d Fixes #1261 - Clone the Terrain Picker, so that loading a terrain from file still works (after cloning, the picker would have the wrong terrain quad instance) 5 years ago
MeFisto94 17fbedd5fe Fixes Bullet-Native Artifacts not containing natives when not building from cpp source and not using the build target. 5 years ago
Riccardo Balbo 2e30b24438 Fix #1236 non-lvalue cannot be out parameter 5 years ago
Stephen Gold bd1b6d284c com.jme3.scene.shape.Line: protect the no-argument constructor (#1234) 5 years ago
Stephen Gold 8a04afd7a1 AnimControl: correct javadoc for the no-arg constructor (#1233) 5 years ago
Stephen Gold f9d2e03362 Mesh: avoid NPE in getMorphTargets() when there are no targets (#1231) 5 years ago
Paul Speed 8905b3d8f8 Refactored how versions are auto-built to provide more normal versions 5 years ago
Riccardo Balbo a2169999e5 Remove "v" from version tag to maintain consistency with old releases 5 years ago
  1. 183
      .github/workflows/main.yml
  2. 36
      build.gradle
  3. 6
      gradle.properties
  4. 2
      jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java
  5. 2
      jme3-android-native/decode.gradle
  6. 4
      jme3-android-native/openalsoft.gradle
  7. 6
      jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java
  8. 4
      jme3-android/src/main/java/com/jme3/app/state/MjpegFileWriter.java
  9. 2
      jme3-android/src/main/java/com/jme3/app/state/VideoRecorderAppState.java
  10. 4
      jme3-android/src/main/java/com/jme3/input/android/AndroidSensorJoyInput.java
  11. 6
      jme3-android/src/main/java/com/jme3/input/android/AndroidTouchInput.java
  12. 4
      jme3-android/src/main/java/com/jme3/input/android/TouchEventPool.java
  13. 18
      jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
  14. 2
      jme3-android/src/main/java/com/jme3/texture/plugins/AndroidNativeImageLoader.java
  15. 4
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/file/Structure.java
  16. 2
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/MeshBuffers.java
  17. 2
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/textures/generating/NoiseGenerator.java
  18. 8
      jme3-bullet/src/common/java/com/jme3/bullet/control/KinematicRagdollControl.java
  19. 4
      jme3-bullet/src/common/java/com/jme3/bullet/util/CollisionShapeFactory.java
  20. 8
      jme3-bullet/src/main/java/com/jme3/bullet/PhysicsSpace.java
  21. 25
      jme3-core/src/main/java/com/jme3/anim/MorphTrack.java
  22. 2
      jme3-core/src/main/java/com/jme3/anim/tween/action/LinearBlendSpace.java
  23. 12
      jme3-core/src/main/java/com/jme3/animation/AnimControl.java
  24. 14
      jme3-core/src/main/java/com/jme3/animation/AnimationFactory.java
  25. 2
      jme3-core/src/main/java/com/jme3/animation/BoneTrack.java
  26. 10
      jme3-core/src/main/java/com/jme3/app/DetailedProfiler.java
  27. 2
      jme3-core/src/main/java/com/jme3/app/LegacyApplication.java
  28. 10
      jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java
  29. 8
      jme3-core/src/main/java/com/jme3/audio/AudioBuffer.java
  30. 2
      jme3-core/src/main/java/com/jme3/audio/AudioNode.java
  31. 2
      jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java
  32. 118
      jme3-core/src/main/java/com/jme3/bounding/BoundingBox.java
  33. 22
      jme3-core/src/main/java/com/jme3/bounding/BoundingSphere.java
  34. 36
      jme3-core/src/main/java/com/jme3/bounding/BoundingVolume.java
  35. 8
      jme3-core/src/main/java/com/jme3/bounding/Intersection.java
  36. 2
      jme3-core/src/main/java/com/jme3/bounding/OrientedBoundingBox.java
  37. 4
      jme3-core/src/main/java/com/jme3/cinematic/MotionPath.java
  38. 2
      jme3-core/src/main/java/com/jme3/cinematic/TimeLine.java
  39. 2
      jme3-core/src/main/java/com/jme3/effect/influencers/DefaultParticleInfluencer.java
  40. 4
      jme3-core/src/main/java/com/jme3/environment/generation/PrefilteredEnvMapFaceGenerator.java
  41. 4
      jme3-core/src/main/java/com/jme3/environment/generation/RunnableWithProgress.java
  42. 10
      jme3-core/src/main/java/com/jme3/environment/util/CubeMapWrapper.java
  43. 36
      jme3-core/src/main/java/com/jme3/environment/util/EnvMapUtils.java
  44. 4
      jme3-core/src/main/java/com/jme3/font/BitmapFont.java
  45. 2
      jme3-core/src/main/java/com/jme3/font/ColorTags.java
  46. 4
      jme3-core/src/main/java/com/jme3/input/InputManager.java
  47. 4
      jme3-core/src/main/java/com/jme3/light/LightProbe.java
  48. 4
      jme3-core/src/main/java/com/jme3/material/MatParamTexture.java
  49. 2
      jme3-core/src/main/java/com/jme3/math/ColorRGBA.java
  50. 237
      jme3-core/src/main/java/com/jme3/math/CurveAndSurfaceMath.java
  51. 8
      jme3-core/src/main/java/com/jme3/math/Eigen3f.java
  52. 207
      jme3-core/src/main/java/com/jme3/math/FastMath.java
  53. 2
      jme3-core/src/main/java/com/jme3/math/Line.java
  54. 15
      jme3-core/src/main/java/com/jme3/math/LineSegment.java
  55. 192
      jme3-core/src/main/java/com/jme3/math/Matrix3f.java
  56. 308
      jme3-core/src/main/java/com/jme3/math/Matrix4f.java
  57. 52
      jme3-core/src/main/java/com/jme3/math/Plane.java
  58. 143
      jme3-core/src/main/java/com/jme3/math/Quaternion.java
  59. 205
      jme3-core/src/main/java/com/jme3/math/Spline.java
  60. 176
      jme3-core/src/main/java/com/jme3/math/Transform.java
  61. 8
      jme3-core/src/main/java/com/jme3/math/Vector2f.java
  62. 157
      jme3-core/src/main/java/com/jme3/math/Vector3f.java
  63. 16
      jme3-core/src/main/java/com/jme3/math/Vector4f.java
  64. 2
      jme3-core/src/main/java/com/jme3/opencl/AbstractOpenCLObject.java
  65. 79
      jme3-core/src/main/java/com/jme3/opencl/Buffer.java
  66. 42
      jme3-core/src/main/java/com/jme3/opencl/CommandQueue.java
  67. 98
      jme3-core/src/main/java/com/jme3/opencl/Context.java
  68. 176
      jme3-core/src/main/java/com/jme3/opencl/Device.java
  69. 22
      jme3-core/src/main/java/com/jme3/opencl/Event.java
  70. 147
      jme3-core/src/main/java/com/jme3/opencl/Image.java
  71. 160
      jme3-core/src/main/java/com/jme3/opencl/Kernel.java
  72. 24
      jme3-core/src/main/java/com/jme3/opencl/KernelCompilationException.java
  73. 8
      jme3-core/src/main/java/com/jme3/opencl/MappingAccess.java
  74. 6
      jme3-core/src/main/java/com/jme3/opencl/MemoryAccess.java
  75. 59
      jme3-core/src/main/java/com/jme3/opencl/OpenCLException.java
  76. 10
      jme3-core/src/main/java/com/jme3/opencl/OpenCLObject.java
  77. 50
      jme3-core/src/main/java/com/jme3/opencl/Program.java
  78. 14
      jme3-core/src/main/java/com/jme3/renderer/Camera.java
  79. 224
      jme3-core/src/main/java/com/jme3/renderer/RenderContext.java
  80. 93
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebug.java
  81. 134
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java
  82. 662
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
  83. 31
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  84. 4
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java
  85. 4
      jme3-core/src/main/java/com/jme3/scene/AssetLinkNode.java
  86. 6
      jme3-core/src/main/java/com/jme3/scene/Mesh.java
  87. 6
      jme3-core/src/main/java/com/jme3/scene/debug/WireSphere.java
  88. 6
      jme3-core/src/main/java/com/jme3/scene/debug/custom/ArmatureDebugger.java
  89. 2
      jme3-core/src/main/java/com/jme3/scene/mesh/IndexBuffer.java
  90. 73
      jme3-core/src/main/java/com/jme3/scene/mesh/VirtualIndexBuffer.java
  91. 16
      jme3-core/src/main/java/com/jme3/scene/shape/Curve.java
  92. 3
      jme3-core/src/main/java/com/jme3/scene/shape/Line.java
  93. 4
      jme3-core/src/main/java/com/jme3/scene/shape/PQTorus.java
  94. 6
      jme3-core/src/main/java/com/jme3/shader/ShaderNode.java
  95. 10
      jme3-core/src/main/java/com/jme3/shader/ShaderNodeDefinition.java
  96. 2
      jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java
  97. 4
      jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java
  98. 10
      jme3-core/src/main/java/com/jme3/system/AppSettings.java
  99. 4
      jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java
  100. 273
      jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,5 +1,5 @@
######################################################################################
# JME CI/CD
# JME CI/CD
######################################################################################
# Quick overview of what is going on in this script:
# - Build natives for android
@ -10,7 +10,7 @@
# - (only when building a release) Deploy everything else to github releases, github packet registry and bintray
# - (only when building a release) Update javadoc.jmonkeyengine.org
# Note:
# All the actions/upload-artifact and actions/download-artifact steps are used to pass
# All the actions/upload-artifact and actions/download-artifact steps are used to pass
# stuff between jobs, github actions has some sort of storage that is local to the
# running workflow, we use it to store the result of each job since the filesystem
# is not maintained between jobs.
@ -23,7 +23,7 @@
# BINTRAY_APIKEY=XXXXXX
# BINTRAY_LICENSE="BSD 3-Clause"
# >> Configure PACKAGE REGISTRY RELEASE
# Nothing to do here, everything is autoconfigured to work with the account/org that
# Nothing to do here, everything is autoconfigured to work with the account/org that
# is running the build.
# >> Configure JAVADOC
# JAVADOC_GHPAGES_REPO="riccardoblsandbox/javadoc.jmonkeyengine.org.git"
@ -31,7 +31,7 @@
# ssh-keygen -t rsa -b 4096 -C "actions@users.noreply.github.com" -f javadoc_deploy
# Set
# JAVADOC_GHPAGES_DEPLOY_PRIVKEY="......."
# In github repo -> Settings, use javadoc_deploy.pub as Deploy key with write access
# In github repo -> Settings, use javadoc_deploy.pub as Deploy key with write access
######################################################################################
# Resources:
# - Github actions docs: https://help.github.com/en/articles/about-github-actions
@ -48,41 +48,43 @@ on:
branches:
- master
- newbuild
- v3.3
- v3.3.*
- v3.2
- v3.2.*
pull_request:
release:
types: [published]
jobs:
# Builds the natives on linux arm
BuildLinuxArmNatives:
name: Build natives for linux (arm)
runs-on: ubuntu-18.04
container:
image: riccardoblb/buildenv-jme3:linuxArm
steps:
- name: Clone the repo
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Build
- name: Validate the Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build
run: |
# Build
# Note: since this is crossbuild we use the buildForPlatforms filter to tell
# the buildscript wich platforms it should build for.
gradle -PuseCommitHashAsVersionName=true --no-daemon -PbuildForPlatforms=LinuxArm,LinuxArmHF,LinuxArm64 -PbuildNativeProjects=true \
:jme3-bullet-native:assemble
:jme3-bullet-native:assemble
- name: Upload natives
uses: actions/upload-artifact@master
with:
name: linuxarm-natives
path: build/native
path: build/native
# Build the natives on android
BuildAndroidNatives:
@ -90,19 +92,20 @@ jobs:
runs-on: ubuntu-18.04
container:
image: riccardoblb/buildenv-jme3:android
steps:
- name: Clone the repo
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Build
run: |
gradle -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true \
- name: Validate the Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build
run: |
./gradlew -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true \
:jme3-android-native:assemble \
:jme3-bullet-native-android:assemble
:jme3-bullet-native-android:assemble
- name: Upload natives
uses: actions/upload-artifact@master
with:
@ -114,7 +117,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [ubuntu-18.04,windows-2019,macOS-latest]
os: [ubuntu-18.04,windows-2019,macOS-latest]
jdk: [8.x.x]
include:
- os: ubuntu-18.04
@ -123,22 +126,23 @@ jobs:
osName: windows
- os: macOS-latest
osName: mac
name: Build natives for ${{ matrix.osName }}
runs-on: ${{ matrix.os }}
steps:
runs-on: ${{ matrix.os }}
steps:
- name: Clone the repo
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Prepare java environment
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
architecture: x64
architecture: x64
- name: Validate the Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build Natives
shell: bash
env:
@ -147,8 +151,8 @@ jobs:
# Install dependencies
if [ "$OS_NAME" = "mac" ];
then
echo "Prepare mac"
echo "Prepare mac"
elif [ "$OS_NAME" = "linux" ];
then
echo "Prepare linux"
@ -157,25 +161,25 @@ jobs:
else
echo "Prepare windows"
fi
# Build
gradle -PuseCommitHashAsVersionName=true --no-daemon -PbuildNativeProjects=true -Dmaven.repo.local="$PWD/dist/maven" \
build \
:jme3-bullet-native:build
# Upload natives to be used later by the BuildJMonkey job
- name: Upload natives
uses: actions/upload-artifact@master
with:
name: ${{ matrix.osName }}-natives
path: build/native
# Build the engine, we only deploy from ubuntu-18.04 jdk8
BuildJMonkey:
BuildJMonkey:
needs: [BuildNatives,BuildAndroidNatives]
name: Build on ${{ matrix.osName }} jdk${{ matrix.jdk }}
runs-on: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
@ -188,21 +192,21 @@ jobs:
- os: windows-2019
osName: windows
- os: macOS-latest
osName: mac
osName: mac
- jdk: 11.x.x
deploy: false
deploy: false
steps:
steps:
- name: Clone the repo
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Setup the java environment
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
architecture: x64
architecture: x64
- name: Download natives for linux
uses: actions/download-artifact@master
@ -215,7 +219,7 @@ jobs:
with:
name: windows-natives
path: build/native
- name: Download natives for mac
uses: actions/download-artifact@master
with:
@ -233,26 +237,27 @@ jobs:
with:
name: linuxarm-natives
path: build/native
- name: Validate the Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build Engine
shell: bash
run: |
# Build
gradle -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true build
if [ "${{ matrix.deploy }}" = "true" ];
then
then
# We are going to need "zip"
sudo apt-get update
sudo apt-get install -y zip
# Create the zip release and the javadoc
gradle -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true mergedJavadoc createZipDistribution
# We prepare the release for deploy
mkdir -p ./dist/release/
mv build/distributions/*.zip dist/release/
# Create the maven artifacts
mkdir -p ./dist/maven/
gradle -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true install -Dmaven.repo.local="$PWD/dist/maven"
@ -261,10 +266,10 @@ jobs:
echo "Create native zip"
cdir="$PWD"
cd "build/native"
zip -r "$cdir/dist/jme3-natives.zip" *
zip -r "$cdir/dist/jme3-natives.zip" *
cd "$cdir"
echo "Done"
fi
fi
# Used later by DeploySnapshot
- name: Upload merged natives
@ -273,29 +278,29 @@ jobs:
with:
name: natives
path: dist/jme3-natives.zip
# Upload maven artifacts to be used later by the deploy job
- name: Upload maven artifacts
if: matrix.deploy==true
uses: actions/upload-artifact@master
with:
name: maven
path: dist/maven
path: dist/maven
- name: Upload javadoc
if: matrix.deploy==true
uses: actions/upload-artifact@master
with:
name: javadoc
path: dist/javadoc
# Upload release archive to be used later by the deploy job
path: dist/javadoc
# Upload release archive to be used later by the deploy job
- name: Upload release
if: github.event_name == 'release' && matrix.deploy==true
uses: actions/upload-artifact@master
with:
name: release
path: dist/release
path: dist/release
# This job deploys the native snapshot.
# The snapshot is downloaded when people build the engine without setting buildNativeProject
@ -316,7 +321,7 @@ jobs:
then
git clone --single-branch --branch "$branch" https://github.com/${GITHUB_REPOSITORY}.git .
fi
- name: Download merged natives
uses: actions/download-artifact@master
with:
@ -334,7 +339,7 @@ jobs:
then
nativeSnapshot=`cat "natives-snapshot.properties"`
nativeSnapshot="${nativeSnapshot#*=}"
# We deploy ONLY if GITHUB_SHA (the current commit hash) is newer than $nativeSnapshot
if [ "`git rev-list --count $nativeSnapshot..$GITHUB_SHA`" = "0" ];
then
@ -355,9 +360,9 @@ jobs:
echo "No changes, skip."
else
if [ "${{ secrets.BINTRAY_GENERIC_REPO }}" = "" ];
then
then
echo "Configure the following secrets to enable native snapshot deployment"
echo "BINTRAY_GENERIC_REPO, BINTRAY_USER, BINTRAY_APIKEY"
echo "BINTRAY_GENERIC_REPO, BINTRAY_USER, BINTRAY_APIKEY"
else
# Deploy snapshot
bintray_uploadFile dist/jme3-natives.zip \
@ -368,17 +373,17 @@ jobs:
"https://github.com/${GITHUB_REPOSITORY}" \
"${{ secrets.BINTRAY_LICENSE }}" "true"
# We reference the snapshot by writing its commit hash in natives-snapshot.properties
# We reference the snapshot by writing its commit hash in natives-snapshot.properties
echo "natives.snapshot=$GITHUB_SHA" > natives-snapshot.properties
# We commit the updated natives-snapshot.properties
git config --global user.name "Github Actions"
git config --global user.email "actions@users.noreply.github.com"
git add natives-snapshot.properties
git commit -m "[skip ci] update natives snapshot"
# Pull rebase from the remote repo, just in case there was a push in the meantime
git pull -q --rebase
@ -387,39 +392,39 @@ jobs:
# Push
(git -c http.extraheader="AUTHORIZATION: basic $header" push origin "$branch" || true)
fi
fi
fi
# This job deploys the release
DeployRelease:
DeployRelease:
needs: [BuildJMonkey]
name: Deploy Release
runs-on: ubuntu-18.04
if: github.event_name == 'release'
steps:
steps:
# We need to clone everything again for uploadToMaven.sh ...
- name: Clone the repo
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1
# Download all the stuff...
- name: Download maven artifacts
uses: actions/download-artifact@master
with:
name: maven
path: dist/maven
- name: Download release
uses: actions/download-artifact@master
with:
name: release
path: dist/release
- name: Deploy to github releases
path: dist/release
- name: Deploy to github releases
run: |
# We need to get the release id (yeah, it's not the same as the tag)
echo "${GITHUB_EVENT_PATH}"
@ -436,7 +441,7 @@ jobs:
-H "Content-Type: application/zip" \
--data-binary @"$filename" \
"$url"
- name: Deploy to bintray
run: |
source .github/actions/tools/uploadToMaven.sh
@ -447,22 +452,22 @@ jobs:
else
uploadAllToMaven dist/maven/ https://api.bintray.com/maven/${{ secrets.BINTRAY_MAVEN_REPO }} ${{ secrets.BINTRAY_USER }} ${{ secrets.BINTRAY_APIKEY }} "https://github.com/${GITHUB_REPOSITORY}" "${{ secrets.BINTRAY_LICENSE }}"
fi
# - name: Deploy to github package registry
# run: |
# source .github/actions/tools/uploadToMaven.sh
# registry="https://maven.pkg.github.com/$GITHUB_REPOSITORY"
# echo "Deploy to github package registry $registry"
# uploadAllToMaven dist/maven/ $registry "token" ${{ secrets.GITHUB_TOKEN }}
# Deploy the javadoc
DeployJavaDoc:
DeployJavaDoc:
needs: [BuildJMonkey]
name: Deploy Javadoc
runs-on: ubuntu-18.04
if: github.event_name == 'release'
steps:
steps:
# We are going to need a deploy key for this, since we need
# to push to a different repo
- name: Set ssh key
@ -477,16 +482,16 @@ jobs:
branch="gh-pages"
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $HOME/.ssh/deploy.key"
git clone --single-branch --branch "$branch" git@github.com:${{ secrets.JAVADOC_GHPAGES_REPO }} .
# Download the javadoc in the new directory "newdoc"
- name: Download javadoc
uses: actions/download-artifact@master
with:
name: javadoc
path: newdoc
# The actual deploy
- name: Deploy to github pages
- name: Deploy to github pages
run: |
set -f
IFS=$'\n'
@ -508,10 +513,10 @@ jobs:
# if there isn't an index.txt we create one (we need this to list the versions)
if [ ! -f "index.txt" ]; then echo "" > index.txt ; fi
index="`cat index.txt`"
# Check if this version is already in index.txt
addNew=true
for v in $index;
for v in $index;
do
if [ "$v" = "$version" ];
then
@ -538,11 +543,11 @@ jobs:
# Commit the changes
git config --global user.name "Github Actions"
git config --global user.email "actions@users.noreply.github.com"
git add .
git commit -m "$version"
branch="gh-pages"
git push origin "$branch" --force
branch="gh-pages"
git push origin "$branch" --force
fi

@ -158,29 +158,29 @@ task configureAndroidNDK {
gradle.rootProject.ext.set("usePrebuildNatives", buildNativeProjects!="true");
if(skipPrebuildLibraries!="true"&&buildNativeProjects!="true"){
if (skipPrebuildLibraries != "true" && buildNativeProjects != "true") {
String rootPath = rootProject.projectDir.absolutePath
Properties nativesSnasphotProp = new Properties()
File nativesSnasphotPropF=new File("${rootPath}/natives-snapshot.properties");
if(nativesSnasphotPropF.exists()){
File nativesSnasphotPropF = new File("${rootPath}/natives-snapshot.properties");
if (nativesSnasphotPropF.exists()) {
nativesSnasphotPropF.withInputStream { nativesSnasphotProp.load(it) }
String nativesSnasphot=nativesSnasphotProp.getProperty("natives.snapshot");
String nativesUrl=PREBUILD_NATIVES_URL.replace('${natives.snapshot}',nativesSnasphot)
println "Use natives snapshot: "+nativesUrl
String nativesSnasphot = nativesSnasphotProp.getProperty("natives.snapshot");
String nativesUrl = PREBUILD_NATIVES_URL.replace('${natives.snapshot}', nativesSnasphot)
println "Use natives snapshot: " + nativesUrl
String nativesZipFile="${rootPath}" + File.separator + "build"+ File.separator +nativesSnasphot+"-natives.zip"
String nativesPath="${rootPath}" + File.separator + "build"+ File.separator +"native"
String nativesZipFile = "${rootPath}" + File.separator + "build" + File.separator + nativesSnasphot + "-natives.zip"
String nativesPath = "${rootPath}" + File.separator + "build" + File.separator + "native"
task getNativesZipFile {
outputs.file nativesZipFile
doFirst {
File target = file(nativesZipFile);
println("Download natives from "+nativesUrl+" to "+nativesZipFile);
println("Download natives from " + nativesUrl + " to " + nativesZipFile);
target.getParentFile().mkdirs();
ant.get(src: nativesUrl, dest: target);
}
@ -192,28 +192,26 @@ if(skipPrebuildLibraries!="true"&&buildNativeProjects!="true"){
dependsOn getNativesZipFile
doFirst {
for(File src : zipTree(nativesZipFile)){
String srcRel=src.getAbsolutePath().substring((int)(nativesZipFile.length()+1));
srcRel=srcRel.substring(srcRel.indexOf( File.separator)+1);
for (File src : zipTree(nativesZipFile)) {
String srcRel = src.getAbsolutePath().substring((int) (nativesZipFile.length() + 1));
srcRel = srcRel.substring(srcRel.indexOf(File.separator) + 1);
File dest=new File(nativesPath+File.separator+srcRel);
File dest = new File(nativesPath + File.separator + srcRel);
boolean doCopy = !(dest.exists() && dest.lastModified() > src.lastModified())
if (doCopy) {
println("Copy "+src+" "+dest);
println("Copy " + src + " " + dest);
dest.getParentFile().mkdirs();
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
build.dependsOn extractPrebuiltNatives
assemble.dependsOn extractPrebuiltNatives
}
}
//class IncrementalReverseTask extends DefaultTask {
// @InputDirectory
// def File inputDir

@ -1,5 +1,5 @@
# Version number: Major.Minor.SubMinor (e.g. 3.3.0)
jmeVersion = 3.3.0
jmeVersion = 3.3.1
# Leave empty to autogenerate
# (use -PjmeVersionName="myVersion" from commandline to specify a custom version name )
@ -8,6 +8,10 @@ jmeVersionName =
# If true, the version name will contain the commit hash
useCommitHashAsVersionName = false
# Set to true if a non-master branch name should be included in the automatically
# generated version.
includeBranchInVersion = false
# specify if JavaDoc should be built
buildJavaDoc = true

@ -286,7 +286,7 @@ public class MainActivity extends AppCompatActivity implements OnItemClickListen
private boolean checkClassType(String className) {
boolean include = true;
try {
Class<?> clazz = (Class<?>) Class.forName(className);
Class<?> clazz = Class.forName(className);
if (Application.class.isAssignableFrom(clazz)) {
Log.d(TAG, "Class " + className + " is a jME Application");
} else {

@ -1,5 +1,5 @@
String tremorZipFile = "TremorAndroid.zip"
String stbiUrl = 'https://raw.githubusercontent.com/nothings/stb/master/stb_image.h'
String stbiUrl = 'https://raw.githubusercontent.com/jMonkeyEngine/stb/0224a44a10564a214595797b4c88323f79a5f934/stb_image.h'
// Working directories for the ndk build.
String decodeBuildDir = "${buildDir}" + File.separator + 'decode'

@ -1,11 +1,11 @@
// OpenAL Soft r1.16
String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/e5016f814a265ed592a88acea95cf912c4bfdf12.zip'
String openALSoftUrl = 'https://github.com/jMonkeyEngine/openal-soft/archive/e5016f814a265ed592a88acea95cf912c4bfdf12.zip'
String openALSoftZipFile = 'OpenALSoft.zip'
// OpenAL Soft directory the download is extracted into
// Typically, the downloaded OpenAL Soft zip file will extract to a directory
// called "openal-soft"
String openALSoftFolder = 'openal-soft-e5016f8'
String openALSoftFolder = 'openal-soft-e5016f814a265ed592a88acea95cf912c4bfdf12'
//Working directories for the ndk build.
String openalsoftBuildDir = "${buildDir}" + File.separator + 'openalsoft'

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -684,10 +684,10 @@ public class AndroidHarnessFragment extends Fragment implements
if (viewWidth > viewHeight && viewWidth > maxResolutionDimension) {
// landscape
fixedSizeWidth = maxResolutionDimension;
fixedSizeHeight = (int)(maxResolutionDimension * ((float)viewHeight / (float)viewWidth));
fixedSizeHeight = (int)(maxResolutionDimension * (viewHeight / (float)viewWidth));
} else if (viewHeight > viewWidth && viewHeight > maxResolutionDimension) {
// portrait
fixedSizeWidth = (int)(maxResolutionDimension * ((float)viewWidth / (float)viewHeight));
fixedSizeWidth = (int)(maxResolutionDimension * (viewWidth / (float)viewHeight));
fixedSizeHeight = maxResolutionDimension;
} else if (viewWidth == viewHeight && viewWidth > maxResolutionDimension) {
fixedSizeWidth = maxResolutionDimension;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -478,7 +478,7 @@ public class MjpegFileWriter {
baos.write(fcc);
baos.write(intBytes(swapInt(cb)));
for (int i = 0; i < ind.size(); i++) {
AVIIndex in = (AVIIndex) ind.get(i);
AVIIndex in = ind.get(i);
baos.write(in.toBytes());
}

@ -345,7 +345,7 @@ public class VideoRecorderAppState extends AbstractAppState {
}
public float getTimePerFrame() {
return (float) (1.0f / this.framerate);
return 1.0f / this.framerate;
}
public void update() {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -561,7 +561,7 @@ public class AndroidSensorJoyInput implements SensorEventListener {
}
}
}
} else if (sensorData != null) {
} else {
if (!sensorData.haveData) {
sensorData.haveData = true;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -131,8 +131,8 @@ public class AndroidTouchInput implements TouchInput {
// view width and height are 0 until the view is displayed on the screen
if (androidInput.getView().getWidth() != 0 && androidInput.getView().getHeight() != 0) {
scaleX = (float)settings.getWidth() / (float)androidInput.getView().getWidth();
scaleY = (float)settings.getHeight() / (float)androidInput.getView().getHeight();
scaleX = settings.getWidth() / (float)androidInput.getView().getWidth();
scaleY = settings.getHeight() / (float)androidInput.getView().getHeight();
}
logger.log(Level.FINE, "Setting input scaling, scaleX: {0}, scaleY: {1}",
new Object[]{scaleX, scaleY});

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -87,7 +87,7 @@ public class TouchEventPool {
TouchEvent evt = null;
int curSize = eventPool.size();
while (curSize > 0) {
evt = (TouchEvent)eventPool.pop();
evt = eventPool.pop();
if (evt.isConsumed()) {
break;
} else {

@ -52,13 +52,7 @@ import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.AndroidGL;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GLES_30;
import com.jme3.renderer.opengl.GLDebugES;
import com.jme3.renderer.opengl.GLExt;
import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
import com.jme3.renderer.opengl.GLTracer;
import com.jme3.renderer.opengl.*;
import com.jme3.system.*;
import com.jme3.util.AndroidBufferAllocator;
import com.jme3.util.BufferAllocatorFactory;
@ -208,14 +202,14 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
});
timer = new NanoTimer();
Object gl = new AndroidGL();
GL gl = new AndroidGL();
if (settings.getBoolean("GraphicsDebug")) {
gl = new GLDebugES((GL) gl, (GLExt) gl, (GLFbo) gl);
gl = (GL) GLDebug.createProxy(gl, gl, GL.class, GL2.class, GLES_30.class, GLFbo.class, GLExt.class);
}
if (settings.getBoolean("GraphicsTrace")) {
gl = GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class);
gl = (GL)GLTracer.createGlesTracer(gl, GL.class, GLES_30.class, GLFbo.class, GLExt.class);
}
renderer = new GLRenderer((GL)gl, (GLExt)gl, (GLFbo)gl);
renderer = new GLRenderer(gl, (GLExt)gl, (GLFbo)gl);
renderer.initialize();
JmeSystem.setSoftTextDialogInput(this);
@ -254,7 +248,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
}
if (settings.getFrameRate() > 0) {
minFrameDuration = (long)(1000d / (double)settings.getFrameRate()); // ms
minFrameDuration = (long)(1000d / settings.getFrameRate()); // ms
logger.log(Level.FINE, "Setting min tpf: {0}ms", minFrameDuration);
} else {
minFrameDuration = 0;

@ -30,7 +30,7 @@ public class AndroidNativeImageLoader implements AssetLoader {
InputStream in = null;
try {
in = info.openStream();
return load(info.openStream(), flip, tmpArray);
return load(in, flip, tmpArray);
} finally {
if (in != null){
in.close();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -252,7 +252,7 @@ public class Structure implements Cloneable {
Object fieldValue = this.getFieldValue("ID");
if (fieldValue instanceof Structure) {
Structure id = (Structure) fieldValue;
return id == null ? null : id.getFieldValue("name").toString().substring(2);// blender adds 2-charactes as a name prefix
return id.getFieldValue("name").toString().substring(2);// blender adds 2-charactes as a name prefix
}
Object name = this.getFieldValue("name", null);
return name == null ? null : name.toString().substring(2);

@ -251,7 +251,7 @@ import com.jme3.util.BufferUtils;
}
}
if (vertexGroups != null && vertexGroups.size() > 0) {
if (vertexGroups.size() > 0) {
Map<Float, Integer> group = vertexGroups.get(i);
maximumWeightsPerVertex = Math.max(maximumWeightsPerVertex, group.size());
boneWeightAndIndexes.add(new TreeMap<Float, Integer>(group));

@ -464,7 +464,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
sum += t * amp;
}
sum *= (float) (1 << noiseDepth) / (float) ((1 << noiseDepth + 1) - 1);
sum *= (1 << noiseDepth) / (float) ((1 << noiseDepth + 1) - 1);
return sum;
}

@ -409,7 +409,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
while (it.hasNext()) {
boneName = it.next();
bone = (Bone) boneLinks.get(boneName).bone;
bone = boneLinks.get(boneName).bone;
if (!bone.hasUserControl()) {
Logger.getLogger(KinematicRagdollControl.class.getSimpleName()).log(Level.FINE, "{0} doesn't have user control", boneName);
continue;
@ -421,7 +421,7 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
}
int depth = 0;
int maxDepth = ikChainDepth.get(bone.getName());
updateBone(boneLinks.get(bone.getName()), tpf * (float) FastMath.sqrt(distance), vars, tmpRot1, tmpRot2, bone, ikTargets.get(boneName), depth, maxDepth);
updateBone(boneLinks.get(bone.getName()), tpf * FastMath.sqrt(distance), vars, tmpRot1, tmpRot2, bone, ikTargets.get(boneName), depth, maxDepth);
Vector3f position = vars.vect1;
@ -693,10 +693,10 @@ public class KinematicRagdollControl extends AbstractPhysicsControl implements P
shape = RagdollUtils.makeShapeFromVerticeWeights(model, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition(), weightThreshold);
}
PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / (float) reccount);
PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / reccount);
shapeNode.setKinematic(mode == Mode.Kinematic);
totalMass += rootMass / (float) reccount;
totalMass += rootMass / reccount;
link.rigidBody = shapeNode;
link.initalWorldRotation = bone.getModelSpaceRotation().clone();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -229,7 +229,7 @@ public class CollisionShapeFactory {
*/
public static CollisionShape createBoxShape(Spatial spatial) {
if (spatial instanceof Geometry) {
return createSingleBoxShape((Geometry) spatial, spatial);
return createSingleBoxShape(spatial, spatial);
} else if (spatial instanceof Node) {
return createBoxCompoundShape((Node) spatial);
} else {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -539,7 +539,7 @@ public class PhysicsSpace {
Spatial node = (Spatial) obj;
for (int i = 0; i < node.getNumControls(); i++) {
if (node.getControl(i) instanceof PhysicsControl) {
add(((PhysicsControl) node.getControl(i)));
add(node.getControl(i));
}
}
} else if (obj instanceof PhysicsCollisionObject) {
@ -581,7 +581,7 @@ public class PhysicsSpace {
Spatial node = (Spatial) obj;
for (int i = 0; i < node.getNumControls(); i++) {
if (node.getControl(i) instanceof PhysicsControl) {
remove(((PhysicsControl) node.getControl(i)));
remove(node.getControl(i));
}
}
} else if (obj instanceof PhysicsCollisionObject) {
@ -1129,7 +1129,7 @@ public class PhysicsSpace {
public List<PhysicsSweepTestResult> sweepTest(CollisionShape shape, Transform start, Transform end) {
List results = new LinkedList();
sweepTest(shape, start, end , results);
return (List<PhysicsSweepTestResult>) results;
return results;
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -65,8 +65,10 @@ public class MorphTrack implements AnimTrack<float[]> {
/**
* Creates a morph track with the given Geometry as a target
*
* @param times a float array with the time of each frame
* @param weights the morphs for each frames
* @param times a float array with the time of each frame (alias created
* -- do not modify after passing it to this constructor)
* @param weights the morphs for each frames (alias created -- do not
* modify after passing it to this constructor)
*/
public MorphTrack(Geometry target, float[] times, float[] weights, int nbMorphTargets) {
this.target = target;
@ -77,7 +79,7 @@ public class MorphTrack implements AnimTrack<float[]> {
/**
* return the array of weights of this track
*
* @return the pre-existing array
* @return the pre-existing array -- do not modify
*/
public float[] getWeights() {
return weights;
@ -86,7 +88,7 @@ public class MorphTrack implements AnimTrack<float[]> {
/**
* returns the arrays of time for this track
*
* @return the pre-existing array
* @return the pre-existing array -- do not modify
*/
public float[] getTimes() {
return times;
@ -95,7 +97,8 @@ public class MorphTrack implements AnimTrack<float[]> {
/**
* Sets the keyframes times for this Joint track
*
* @param times the keyframes times
* @param times the keyframes times (alias created -- do not modify after
* passing it to this setter)
*/
public void setTimes(float[] times) {
if (times.length == 0) {
@ -109,9 +112,10 @@ public class MorphTrack implements AnimTrack<float[]> {
/**
* Set the weight for this morph track
*
* @param times a float array with the time of each frame
* @param weights the weights of the morphs for each frame
* @param times a float array with the time of each frame (alias created
* -- do not modify after passing it to this setter)
* @param weights the weights of the morphs for each frame (alias created
* -- do not modify after passing it to this setter)
*/
public void setKeyframes(float[] times, float[] weights) {
setTimes(times);
@ -122,7 +126,7 @@ public class MorphTrack implements AnimTrack<float[]> {
this.weights = weights;
assert times != null && times.length == weights.length;
assert times.length == weights.length;
}
}
@ -211,6 +215,7 @@ public class MorphTrack implements AnimTrack<float[]> {
@Override
public void cloneFields(Cloner cloner, Object original) {
this.target = cloner.clone(target);
// Note: interpolator, times, and weights are not cloned
}

@ -17,7 +17,7 @@ public class LinearBlendSpace implements BlendSpace {
public void setBlendAction(BlendAction action) {
this.action = action;
Action[] actions = action.getActions();
step = (maxValue - minValue) / (float) (actions.length - 1);
step = (maxValue - minValue) / (actions.length - 1);
}
@Override

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2019 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -102,7 +102,9 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
}
/**
* Serialization only. Do not use.
* Instantiate an animation control with no skeleton, suitable only for
* animations that don't contain any bone tracks. Also used for
* serialization.
*/
public AnimControl() {
}
@ -144,6 +146,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Retrieve an animation from the list of animations.
*
* @param name The name of the animation to retrieve.
* @return The animation corresponding to the given name, or null, if no
* such named animation exists.
@ -155,6 +158,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Adds an animation to be available for playing to this
* <code>AnimControl</code>.
*
* @param anim The animation to add.
*/
public void addAnim(Animation anim) {
@ -163,6 +167,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Remove an animation so that it is no longer available for playing.
*
* @param anim The animation to remove.
*/
public void removeAnim(Animation anim) {
@ -231,6 +236,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Adds a new listener to receive animation related events.
*
* @param listener The listener to add.
*/
public void addListener(AnimEventListener listener) {
@ -244,6 +250,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Removes the given listener from listening to events.
*
* @param listener
* @see AnimControl#addListener(com.jme3.animation.AnimEventListener)
*/
@ -308,6 +315,7 @@ public final class AnimControl extends AbstractControl implements Cloneable, Jme
/**
* Returns the length of the given named animation.
*
* @param name The name of the animation
* @return The length of time, in seconds, of the named animation.
*/

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -287,12 +287,12 @@ public class AnimationFactory {
//frames delta
int dF = keyFrameIndex - prev;
//angle per frame for x,y ,z
float dXAngle = (x - prevRot.eulerAngles.x) / (float) dF;
float dYAngle = (y - prevRot.eulerAngles.y) / (float) dF;
float dZAngle = (z - prevRot.eulerAngles.z) / (float) dF;
float dXAngle = (x - prevRot.eulerAngles.x) / dF;
float dYAngle = (y - prevRot.eulerAngles.y) / dF;
float dZAngle = (z - prevRot.eulerAngles.z) / dF;
// the keyFrame step
int keyStep = (int) (((float) (dF)) / delta * (float) EULER_STEP);
int keyStep = (int) (dF / delta * EULER_STEP);
// the current keyFrame
int cursor = prev + keyStep;
while (cursor < keyFrameIndex) {
@ -425,7 +425,7 @@ public class AnimationFactory {
//interating over the frames
for (int j = i; j <= key; j++) {
// computing interpolation value
float val = (float) (j - i) / (float) span;
float val = (j - i) / (float) span;
//interpolationg depending on the transform type
switch (type) {
case Translation:
@ -451,7 +451,7 @@ public class AnimationFactory {
translations[j] = ((Vector3f) keyFrames[i]).clone();
break;
case Rotation:
rotations[j] = ((Quaternion) ((Rotation) keyFrames[i]).rotation).clone();
rotations[j] = ((Rotation) keyFrames[i]).rotation.clone();
break;
case Scale:
scales[j] = ((Vector3f) keyFrames[i]).clone();

@ -89,7 +89,7 @@ public final class BoneTrack implements JmeCloneable, Track {
* @param scales the scale of the bone for each frame
*/
public BoneTrack(int targetBoneIndex, float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) {
this.targetBoneIndex = targetBoneIndex;
this.targetBoneIndex = targetBoneIndex;
this.setKeyframes(times, translations, rotations, scales);
}

@ -38,6 +38,7 @@ public class DetailedProfiler implements AppProfiler {
@Override
public void appStep(AppStep step) {
curAppPath = step.name();
if (step == AppStep.BeginFrame) {
@ -102,7 +103,10 @@ public class DetailedProfiler implements AppProfiler {
private void closeFrame() {
//close frame
if (data != null) {
if (ongoingGpuProfiling && renderer != null) {
renderer.stopProfiling();
ongoingGpuProfiling = false;
}
prevPath = null;
for (StatLine statLine : data.values()) {
@ -284,7 +288,7 @@ public class DetailedProfiler implements AppProfiler {
if (nbFramesCpu == 0) {
return 0;
}
return (double) cpuSum / (double) Math.min(nbFramesCpu, MAX_FRAMES);
return cpuSum / (double) Math.min(nbFramesCpu, MAX_FRAMES);
}
public double getAverageGpu() {
@ -292,7 +296,7 @@ public class DetailedProfiler implements AppProfiler {
return 0;
}
return (double) gpuSum / (double) Math.min(nbFramesGpu, MAX_FRAMES);
return gpuSum / (double) Math.min(nbFramesGpu, MAX_FRAMES);
}
}

@ -695,7 +695,7 @@ public class LegacyApplication implements Application, SystemListener {
* Runs tasks enqueued via {@link #enqueue(Callable)}
*/
protected void runQueuedTasks() {
AppTask<?> task;
AppTask<?> task;
while( (task = taskQueue.poll()) != null ) {
if (!task.isCancelled()) {
task.invoke();

@ -388,11 +388,11 @@ public class DesktopAssetManager implements AssetManager {
}
public Texture loadTexture(TextureKey key){
return (Texture) loadAsset(key);
return loadAsset(key);
}
public Material loadMaterial(String name){
return (Material) loadAsset(new MaterialKey(name));
return loadAsset(new MaterialKey(name));
}
public Texture loadTexture(String name){
@ -402,7 +402,7 @@ public class DesktopAssetManager implements AssetManager {
}
public AudioData loadAudio(AudioKey key){
return (AudioData) loadAsset(key);
return loadAsset(key);
}
public AudioData loadAudio(String name){
@ -414,7 +414,7 @@ public class DesktopAssetManager implements AssetManager {
}
public Spatial loadModel(ModelKey key){
return (Spatial) loadAsset(key);
return loadAsset(key);
}
public Spatial loadModel(String name){
@ -422,7 +422,7 @@ public class DesktopAssetManager implements AssetManager {
}
public FilterPostProcessor loadFilter(FilterKey key){
return (FilterPostProcessor) loadAsset(key);
return loadAsset(key);
}
public FilterPostProcessor loadFilter(String name){

@ -31,9 +31,9 @@
*/
package com.jme3.audio;
import com.jme3.audio.AudioData.DataType;
import com.jme3.util.BufferUtils;
import com.jme3.util.NativeObject;
import java.nio.ByteBuffer;
/**
@ -85,8 +85,14 @@ public class AudioBuffer extends AudioData {
/**
* Update the data in the buffer with new data.
* @param data
* @throws IllegalArgumentException if the provided buffer is not a direct buffer
*/
public void updateData(ByteBuffer data){
if (!data.isDirect()) {
throw new IllegalArgumentException(
"Currently only direct buffers are allowed");
}
this.audioData = data;
updateNeeded = true;
}

@ -161,7 +161,7 @@ public class AudioNode extends Node implements AudioSource {
@Deprecated
public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
this.audioKey = new AudioKey(name, stream, streamCache);
this.data = (AudioData) assetManager.loadAsset(audioKey);
this.data = assetManager.loadAsset(audioKey);
}
/**

@ -821,7 +821,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
al.alSourcei(sourceId, EFX.AL_DIRECT_FILTER, EFX.AL_FILTER_NULL);
}
if (src.isPositional()) {
AudioSource pas = (AudioSource) src;
AudioSource pas = src;
if (pas.isReverbEnabled() && supportEfx) {
al.alSource3i(sourceId, EFX.AL_AUXILIARY_SEND_FILTER, 0, 0, EFX.AL_FILTER_NULL);
}

@ -68,7 +68,7 @@ public class BoundingBox extends BoundingVolume {
* the Z-extent of the box (>=0, may be +Infinity)
*/
float zExtent;
/**
* Instantiate a <code>BoundingBox</code> without initializing it.
*/
@ -113,7 +113,7 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>computeFromPoints</code> creates a new Bounding Box from a given
* set of points. It uses the <code>containAABB</code> method as default.
*
*
* @param points
* the points to contain.
*/
@ -124,7 +124,7 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>computeFromTris</code> creates a new Bounding Box from a given
* set of triangles. It is used in OBBTree calculations.
*
*
* @param tris
* @param start
* @param end
@ -136,8 +136,10 @@ public class BoundingBox extends BoundingVolume {
TempVars vars = TempVars.get();
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
Vector3f min = vars.vect1.set(new Vector3f(Float.POSITIVE_INFINITY,
Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY));
Vector3f max = vars.vect2.set(new Vector3f(Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
Vector3f point;
for (int i = start; i < end; i++) {
@ -219,7 +221,7 @@ public class BoundingBox extends BoundingVolume {
* <code>containAABB</code> creates a minimum-volume axis-aligned bounding
* box of the points, then selects the smallest enclosing sphere of the box
* with the sphere centered at the boxes center.
*
*
* @param points
* the list of points.
*/
@ -235,12 +237,16 @@ public class BoundingBox extends BoundingVolume {
}
TempVars vars = TempVars.get();
float[] tmpArray = vars.skinPositions;
float minX = Float.POSITIVE_INFINITY, minY = Float.POSITIVE_INFINITY, minZ = Float.POSITIVE_INFINITY;
float maxX = Float.NEGATIVE_INFINITY, maxY = Float.NEGATIVE_INFINITY, maxZ = Float.NEGATIVE_INFINITY;
float minX = Float.POSITIVE_INFINITY,
minY = Float.POSITIVE_INFINITY,
minZ = Float.POSITIVE_INFINITY;
float maxX = Float.NEGATIVE_INFINITY,
maxY = Float.NEGATIVE_INFINITY,
maxZ = Float.NEGATIVE_INFINITY;
int iterations = (int) FastMath.ceil(points.limit() / ((float) tmpArray.length));
for (int i = iterations - 1; i >= 0; i--) {
int bufLength = Math.min(tmpArray.length, points.remaining());
@ -248,9 +254,9 @@ public class BoundingBox extends BoundingVolume {
for (int j = 0; j < bufLength; j += 3) {
vars.vect1.x = tmpArray[j];
vars.vect1.y = tmpArray[j+1];
vars.vect1.z = tmpArray[j+2];
vars.vect1.y = tmpArray[j + 1];
vars.vect1.z = tmpArray[j + 2];
if (vars.vect1.x < minX) {
minX = vars.vect1.x;
}
@ -287,8 +293,8 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>transform</code> modifies the center of the box to reflect the
* change made via a rotation, translation and scale.
*
* @param trans
*
* @param trans
* the transform to apply
* @param store
* box to store result in
@ -314,7 +320,9 @@ public class BoundingBox extends BoundingVolume {
transMatrix.absoluteLocal();
Vector3f scale = trans.getScale();
vars.vect1.set(xExtent * FastMath.abs(scale.x), yExtent * FastMath.abs(scale.y), zExtent * FastMath.abs(scale.z));
vars.vect1.set(xExtent * FastMath.abs(scale.x),
yExtent * FastMath.abs(scale.y),
zExtent * FastMath.abs(scale.z));
transMatrix.mult(vars.vect1, vars.vect2);
// Assign the biggest rotations after scales.
box.xExtent = FastMath.abs(vars.vect2.getX());
@ -335,7 +343,6 @@ public class BoundingBox extends BoundingVolume {
}
TempVars vars = TempVars.get();
float w = trans.multProj(center, box.center);
box.center.divideLocal(w);
@ -361,7 +368,7 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>whichSide</code> takes a plane (typically provided by a view
* frustum) to determine which side this bound is on.
*
*
* @param plane
* the plane to check against.
*/
@ -425,15 +432,14 @@ public class BoundingBox extends BoundingVolume {
// case OBB: {
// return mergeOBB((OrientedBoundingBox) volume);
// }
default:
return null;
}
}
/**
/*
* Merges this AABB with the given OBB.
*
*
* @param volume
* the OBB to merge this AABB with.
* @return This AABB extended to fit the given OBB.
@ -474,6 +480,7 @@ public class BoundingBox extends BoundingVolume {
// zExtent = max.z - center.z;
// return this;
// }
/**
* <code>mergeLocal</code> combines this bounding box locally with a second
* bounding box described by its center and extents.
@ -542,7 +549,7 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>clone</code> creates a new BoundingBox object containing the same
* data as this one.
*
*
* @param store
* where to store the cloned information. if null or wrong class,
* a new store is created.
@ -581,8 +588,8 @@ public class BoundingBox extends BoundingVolume {
/**
* intersects determines if this Bounding Box intersects with another given
* bounding volume. If so, true is returned, otherwise, false is returned.
*
* @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume)
*
* @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume)
*/
public boolean intersects(BoundingVolume bv) {
return bv.intersectsBoundingBox(this);
@ -590,7 +597,7 @@ public class BoundingBox extends BoundingVolume {
/**
* determines if this bounding box intersects a given bounding sphere.
*
*
* @see BoundingVolume#intersectsSphere(com.jme3.bounding.BoundingSphere)
*/
public boolean intersectsSphere(BoundingSphere bs) {
@ -601,7 +608,7 @@ public class BoundingBox extends BoundingVolume {
* determines if this bounding box intersects a given bounding box. If the
* two boxes intersect in any way, true is returned. Otherwise, false is
* returned.
*
*
* @see BoundingVolume#intersectsBoundingBox(com.jme3.bounding.BoundingBox)
*/
public boolean intersectsBoundingBox(BoundingBox bb) {
@ -621,10 +628,10 @@ public class BoundingBox extends BoundingVolume {
}
}
/**
/*
* determines if this bounding box intersects with a given oriented bounding
* box.
*
*
* @see com.jme.bounding.BoundingVolume#intersectsOrientedBoundingBox(com.jme.bounding.OrientedBoundingBox)
*/
// public boolean intersectsOrientedBoundingBox(OrientedBoundingBox obb) {
@ -633,8 +640,8 @@ public class BoundingBox extends BoundingVolume {
/**
* determines if this bounding box intersects with a given ray object. If an
* intersection has occurred, true is returned, otherwise false is returned.
*
* @see BoundingVolume#intersects(com.jme3.math.Ray)
*
* @see BoundingVolume#intersects(com.jme3.math.Ray)
*/
public boolean intersects(Ray ray) {
assert Vector3f.isValidVector(center);
@ -710,14 +717,14 @@ public class BoundingBox extends BoundingVolume {
*/
private int collideWithRay(Ray ray, CollisionResults results) {
TempVars vars = TempVars.get();
try {
try {
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
Vector3f direction = vars.vect2.set(ray.direction);
//float[] t = {0f, Float.POSITIVE_INFINITY};
float[] t = vars.fWdU; // use one of the tempvars arrays
t[0] = 0;
t[1] = Float.POSITIVE_INFINITY;
t[1] = Float.POSITIVE_INFINITY;
float saveT0 = t[0], saveT1 = t[1];
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
@ -732,14 +739,14 @@ public class BoundingBox extends BoundingVolume {
float[] distances = t;
Vector3f point0 = new Vector3f(ray.direction).multLocal(distances[0]).addLocal(ray.origin);
Vector3f point1 = new Vector3f(ray.direction).multLocal(distances[1]).addLocal(ray.origin);
CollisionResult result = new CollisionResult(point0, distances[0]);
results.addCollision(result);
result = new CollisionResult(point1, distances[1]);
results.addCollision(result);
return 2;
}
Vector3f point = new Vector3f(ray.direction).multLocal(t[0]).addLocal(ray.origin);
CollisionResult result = new CollisionResult(point, t[0]);
results.addCollision(result);
@ -753,14 +760,14 @@ public class BoundingBox extends BoundingVolume {
private int collideWithRay(Ray ray) {
TempVars vars = TempVars.get();
try {
try {
Vector3f diff = vars.vect1.set(ray.origin).subtractLocal(center);
Vector3f direction = vars.vect2.set(ray.direction);
//float[] t = {0f, Float.POSITIVE_INFINITY};
float[] t = vars.fWdU; // use one of the tempvars arrays
t[0] = 0;
t[1] = Float.POSITIVE_INFINITY;
t[1] = Float.POSITIVE_INFINITY;
float saveT0 = t[0], saveT1 = t[1];
boolean notEntirelyClipped = clip(+direction.x, -diff.x - xExtent, t)
@ -771,15 +778,18 @@ public class BoundingBox extends BoundingVolume {
&& clip(-direction.z, +diff.z - zExtent, t);
if (notEntirelyClipped && (t[0] != saveT0 || t[1] != saveT1)) {
if (t[1] > t[0]) return 2;
else return 1;
if (t[1] > t[0]) {
return 2;
} else {
return 1;
}
}
return 0;
} finally {
vars.release();
}
}
@Override
public int collideWith(Collidable other, CollisionResults results) {
if (other instanceof Ray) {
@ -801,12 +811,12 @@ public class BoundingBox extends BoundingVolume {
}
return 0;
} else if (other instanceof Spatial) {
return ((Spatial)other).collideWith(this, results);
return other.collideWith(this, results);
} else {
throw new UnsupportedCollisionException("With: " + other.getClass().getSimpleName());
}
}
@Override
public int collideWith(Collidable other) {
if (other instanceof Ray) {
@ -855,10 +865,10 @@ public class BoundingBox extends BoundingVolume {
public float distanceToEdge(Vector3f point) {
// compute coordinates of point in box coordinate system
TempVars vars= TempVars.get();
TempVars vars = TempVars.get();
Vector3f closest = vars.vect1;
point.subtract(center,closest);
point.subtract(center, closest);
// project test point onto box
float sqrDistance = 0.0f;
@ -893,7 +903,7 @@ public class BoundingBox extends BoundingVolume {
sqrDistance += delta * delta;
closest.z = zExtent;
}
vars.release();
return FastMath.sqrt(sqrDistance);
}
@ -901,7 +911,7 @@ public class BoundingBox extends BoundingVolume {
/**
* <code>clip</code> determines if a line segment intersects the current
* test plane.
*
*
* @param denom
* the denominator of the line segment.
* @param numer
@ -923,26 +933,26 @@ public class BoundingBox extends BoundingVolume {
// 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.
// 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.
// 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
// 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
// Many Bothans died bring you this fix.
// -pspeed
float newT = numer / denom;
if (newT > t[1]) {
return false;
@ -959,7 +969,7 @@ public class BoundingBox extends BoundingVolume {
// 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]) {
if (newT < t[0]) {
return false;
}
if (newT < t[1]) {
@ -973,7 +983,7 @@ public class BoundingBox extends BoundingVolume {
/**
* Query extent.
*
*
* @param store
* where extent gets stored - null to return a new vector
* @return store / new vector

@ -148,24 +148,24 @@ public class BoundingSphere extends BoundingVolume {
// * <code>computeFromTris</code> creates a new Bounding Box from a given
// * set of triangles. It is used in OBBTree calculations.
// *
// * @param indices
// * @param mesh
// * @param indices
// * @param mesh
// * @param start
// * @param end
// */
// public void computeFromTris(int[] indices, Mesh mesh, int start, int end) {
// if (end - start <= 0) {
// if (end - start <= 0) {
// return;
// }
//
// Vector3f[] vertList = new Vector3f[(end - start) * 3];
// Vector3f[] vertList = new Vector3f[(end - start) * 3];
//
// int count = 0;
// for (int i = start; i < end; i++) {
// mesh.getTriangle(indices[i], verts);
// vertList[count++] = new Vector3f(verts[0]);
// vertList[count++] = new Vector3f(verts[1]);
// vertList[count++] = new Vector3f(verts[2]);
// mesh.getTriangle(indices[i], verts);
// vertList[count++] = new Vector3f(verts[0]);
// vertList[count++] = new Vector3f(verts[1]);
// vertList[count++] = new Vector3f(verts[2]);
// }
//
// averagePoints(vertList);
@ -486,7 +486,7 @@ public class BoundingSphere extends BoundingVolume {
}
// case OBB: {
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
// OrientedBoundingBox box = (OrientedBoundingBox) volume;
// BoundingSphere rVal = (BoundingSphere) this.clone(null);
// return rVal.mergeOBB(box);
// }
@ -532,7 +532,7 @@ public class BoundingSphere extends BoundingVolume {
}
// case OBB: {
// return mergeOBB((OrientedBoundingBox) volume);
// return mergeOBB((OrientedBoundingBox) volume);
// }
default:
@ -1003,7 +1003,7 @@ public class BoundingSphere extends BoundingVolume {
}
return 0;
} else if (other instanceof Spatial) {
return ((Spatial)other).collideWith(this, results);
return other.collideWith(this, results);
} else {
throw new UnsupportedCollisionException();
}

@ -44,12 +44,11 @@ import java.nio.FloatBuffer;
/**
* <code>BoundingVolume</code> defines an interface for dealing with
* containment of a collection of points.
*
*
* @author Mark Powell
* @version $Id: BoundingVolume.java,v 1.24 2007/09/21 15:45:32 nca Exp $
*/
public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* The type of bounding volume being used.
*/
@ -57,13 +56,11 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* {@link BoundingSphere}
*/
Sphere,
Sphere,
/**
* {@link BoundingBox}.
*/
AABB,
AABB,
/**
* Currently unsupported by jME3.
*/
@ -82,7 +79,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* Grabs the checkplane we should check first.
*
*/
public int getCheckPlane() {
return checkPlane;
@ -103,7 +99,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract Type getType();
/**
*
* <code>transform</code> alters the location of the bounding volume by a
* rotation, translation and a scalar.
*
@ -116,7 +111,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
}
/**
*
* <code>transform</code> alters the location of the bounding volume by a
* rotation, translation and a scalar.
*
@ -131,7 +125,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract BoundingVolume transform(Matrix4f trans, BoundingVolume store);
/**
*
* <code>whichSide</code> returns the side on which the bounding volume
* lies on a plane. Possible values are POSITIVE_SIDE, NEGATIVE_SIDE, and
* NO_SIDE.
@ -143,7 +136,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public abstract Plane.Side whichSide(Plane plane);
/**
*
* <code>computeFromPoints</code> generates a bounding volume that
* encompasses a collection of points.
*
@ -204,7 +196,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* Find the distance from the center of this Bounding Volume to the given
* point.
*
*
* @param point
* The point to get the distance to
* @return distance
@ -216,7 +208,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* Find the squared distance from the center of this Bounding Volume to the
* given point.
*
*
* @param point
* The point to get the distance to
* @return distance
@ -228,7 +220,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* Find the distance from the nearest edge of this Bounding Volume to the given
* point.
*
*
* @param point
* The point to get the distance to
* @return distance
@ -255,7 +247,6 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
*/
public abstract boolean intersects(Ray ray);
/**
* determines if this bounding volume and a given bounding sphere are
* intersecting.
@ -276,7 +267,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
*/
public abstract boolean intersectsBoundingBox(BoundingBox bb);
/**
/*
* determines if this bounding volume and a given bounding box are
* intersecting.
*
@ -284,13 +275,12 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
* the bounding box to test against.
* @return true if this volume intersects the given bounding box.
*/
// public abstract boolean intersectsOrientedBoundingBox(OrientedBoundingBox bb);
// public abstract boolean intersectsOrientedBoundingBox(OrientedBoundingBox bb);
/**
*
* determines if a given point is contained within this bounding volume.
* If the point is on the edge of the bounding volume, this method will
* return false. Use intersects(Vector3f) to check for edge intersection.
*
*
* @param point
* the point to check
* @return true if the point lies within this bounding volume.
@ -299,6 +289,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
/**
* Determines if a given point intersects (touches or is inside) this bounding volume.
*
* @param point the point to check
* @return true if the point lies within this bounding volume.
*/
@ -308,11 +299,11 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
@Override
public BoundingVolume clone() {
try{
try {
BoundingVolume clone = (BoundingVolume) super.clone();
clone.center = center.clone();
return clone;
}catch (CloneNotSupportedException ex){
} catch (CloneNotSupportedException ex) {
throw new AssertionError();
}
}
@ -324,7 +315,7 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
public void read(JmeImporter e) throws IOException {
center = (Vector3f) e.getCapsule(this).readSavable("center", Vector3f.ZERO.clone());
}
public int collideWith(Collidable other) {
TempVars tempVars = TempVars.get();
try {
@ -336,4 +327,3 @@ public abstract class BoundingVolume implements Savable, Cloneable, Collidable {
}
}
}

@ -121,8 +121,8 @@ public final class Intersection {
// private boolean axisTestX01(float a, float b, float fa, float fb,
// Vector3f center, Vector3f ext,
// Vector3f v1, Vector3f v2, Vector3f v3){
// float p0 = a * v0.y - b * v0.z;
// float p2 = a * v2.y - b * v2.z;
// float p0 = a * v0.y - b * v0.z;
// float p2 = a * v2.y - b * v2.z;
// if(p0 < p2){
// min = p0;
// max = p2;
@ -130,8 +130,8 @@ public final class Intersection {
// min = p2;
// max = p0;
// }
// float rad = fa * boxhalfsize.y + fb * boxhalfsize.z;
// if(min > rad || max < -rad)
// float rad = fa * boxhalfsize.y + fb * boxhalfsize.z;
// if(min > rad || max < -rad)
// return false;
// }
public static boolean intersect(BoundingBox bbox, Vector3f v1, Vector3f v2, Vector3f v3) {

@ -506,7 +506,7 @@ package com.jme3.bounding;
//// Vector3f max = _compVect2.set(new Vector3f(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY));
//// Vector3f point;
//// for (int i = start; i < end; i++) {
//// mesh.getTriangle(indices[i], verts);
//// mesh.getTriangle(indices[i], verts);
//// point = verts[0];
//// if (point.x < min.x)
//// min.x = point.x;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -192,7 +192,7 @@ public class MotionPath implements Savable {
int i = 0;
for (Float len : spline.getSegmentsLength()) {
if (sum + len >= distance) {
return new Vector2f((float) i, (distance - sum) / len);
return new Vector2f(i, (distance - sum) / len);
}
sum += len;
i++;

@ -93,7 +93,7 @@ public class TimeLine extends HashMap<Integer, KeyFrame> implements Savable {
}
public float getKeyFrameTime(KeyFrame keyFrame) {
return (float)keyFrame.getIndex()/(float)keyFramesPerSeconds;
return keyFrame.getIndex()/(float)keyFramesPerSeconds;
}
public Collection<KeyFrame> getAllKeyFrames() {

@ -72,7 +72,7 @@ public class DefaultParticleInfluencer implements ParticleInfluencer {
* the particle to be affected
*/
protected void applyVelocityVariation(Particle particle) {
particle.velocity.set(initialVelocity);
particle.velocity.set(initialVelocity);
temp.set(FastMath.nextRandomFloat(), FastMath.nextRandomFloat(), FastMath.nextRandomFloat());
temp.multLocal(2f);
temp.subtractLocal(1f, 1f, 1f);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -211,7 +211,7 @@ public class PrefilteredEnvMapFaceGenerator extends RunnableWithProgress {
nbRotations = numSamples == 1 ? 1 : 18;
}
float rad = 2f * FastMath.PI / (float) nbRotations;
float rad = 2f * FastMath.PI / nbRotations;
// offset rotation to avoid sampling pattern
float gi = (float) (FastMath.abs(N.z + N.x) * 256.0);
float offset = rad * (FastMath.cos((gi * 0.5f) % (2f * FastMath.PI)) * 0.5f + 0.5f);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -66,7 +66,7 @@ public abstract class RunnableWithProgress implements Runnable {
* @return fraction (&ge;0, &le;1)
*/
public double getProgress() {
return (double) progress / (double) end;
return progress / (double) end;
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -148,7 +148,7 @@ public class CubeMapWrapper {
store = new ColorRGBA();
}
raster.setSlice(face);
return raster.getPixel((int) x, (int) y, store);
return raster.getPixel(x, y, store);
}
/**
@ -170,7 +170,7 @@ public class CubeMapWrapper {
}
mipMapRaster.setSlice(face);
mipMapRaster.setMipLevel(mipLevel);
return mipMapRaster.getPixel((int) x, (int) y, store);
return mipMapRaster.getPixel(x, y, store);
}
/**
@ -209,7 +209,7 @@ public class CubeMapWrapper {
*/
public void setPixel(int x, int y, int face, ColorRGBA color) {
raster.setSlice(face);
raster.setPixel((int) x, (int) y, color);
raster.setPixel(x, y, color);
}
/**
@ -227,7 +227,7 @@ public class CubeMapWrapper {
mipMapRaster.setSlice(face);
mipMapRaster.setMipLevel(mipLevel);
mipMapRaster.setPixel((int) x, (int) y, color);
mipMapRaster.setPixel(x, y, color);
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -194,8 +194,8 @@ public class EnvMapUtils {
/* transform from [0..res - 1] to [- (1 - 1 / res) .. (1 - 1 / res)]
(+ 0.5f is for texel center addressing) */
float u = (2.0f * ((float) x + 0.5f) / (float) mapSize) - 1.0f;
float v = (2.0f * ((float) y + 0.5f) / (float) mapSize) - 1.0f;
float u = (2.0f * (x + 0.5f) / mapSize) - 1.0f;
float v = (2.0f * (y + 0.5f) / mapSize) - 1.0f;
getVectorFromCubemapFaceTexCoord(x, y, mapSize, face, store, fixSeamsMethod);
@ -203,7 +203,7 @@ public class EnvMapUtils {
* U and V are the -1..1 texture coordinate on the current face.
* Get projected area for this texel */
float x0, y0, x1, y1;
float invRes = 1.0f / (float) mapSize;
float invRes = 1.0f / mapSize;
x0 = u - invRes;
y0 = v - invRes;
x1 = u + invRes;
@ -246,19 +246,19 @@ public class EnvMapUtils {
if (fixSeamsMethod == FixSeamsMethod.Stretch) {
/* Code from Nvtt : https://github.com/castano/nvidia-texture-tools/blob/master/src/nvtt/CubeSurface.cpp#L77
* transform from [0..res - 1] to [-1 .. 1], match up edges exactly. */
u = (2.0f * (float) x / ((float) mapSize - 1.0f)) - 1.0f;
v = (2.0f * (float) y / ((float) mapSize - 1.0f)) - 1.0f;
u = (2.0f * x / (mapSize - 1.0f)) - 1.0f;
v = (2.0f * y / (mapSize - 1.0f)) - 1.0f;
} else {
//Done if any other fix method or no fix method is set
/* transform from [0..res - 1] to [- (1 - 1 / res) .. (1 - 1 / res)]
* (+ 0.5f is for texel center addressing) */
u = (2.0f * ((float) x + 0.5f) / (float) (mapSize)) - 1.0f;
v = (2.0f * ((float) y + 0.5f) / (float) (mapSize)) - 1.0f;
u = (2.0f * (x + 0.5f) / mapSize) - 1.0f;
v = (2.0f * (y + 0.5f) / mapSize) - 1.0f;
}
if (fixSeamsMethod == FixSeamsMethod.Wrap) {
// Warp texel centers in the proximity of the edges.
float a = pow((float) mapSize, 2.0f) / pow(((float) mapSize - 1f), 3.0f);
float a = pow(mapSize, 2.0f) / pow(mapSize - 1f, 3.0f);
u = a * pow(u, 3f) + u;
v = a * pow(v, 3f) + v;
}
@ -317,7 +317,7 @@ public class EnvMapUtils {
}
//compute vector depending on the face
// Code from Nvtt : http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvtt/CubeSurface.cpp
// Code from Nvtt : http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvtt/CubeSurface.cpp
switch (face) {
case 0:
//store.set(1f, -v, -u, 0);
@ -360,16 +360,16 @@ public class EnvMapUtils {
v *= bias;
if (fixSeamsMethod == FixSeamsMethod.Stretch) {
/* Code from Nvtt : http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvtt/CubeSurface.cpp
/* Code from Nvtt : http://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvtt/CubeSurface.cpp
* transform from [0..res - 1] to [-1 .. 1], match up edges exactly. */
u = Math.round((u + 1.0f) * ((float) mapSize - 1.0f) * 0.5f);
v = Math.round((v + 1.0f) * ((float) mapSize - 1.0f) * 0.5f);
u = Math.round((u + 1.0f) * (mapSize - 1.0f) * 0.5f);
v = Math.round((v + 1.0f) * (mapSize - 1.0f) * 0.5f);
} else {
//Done if any other fix method or no fix method is set
/* transform from [0..res - 1] to [- (1 - 1 / res) .. (1 - 1 / res)]
* (+ 0.5f is for texel center addressing) */
u = Math.round((u + 1.0f) * ((float) mapSize) * 0.5f - 0.5f);
v = Math.round((v + 1.0f) * ((float) mapSize) * 0.5f - 0.5f);
u = Math.round((u + 1.0f) * mapSize * 0.5f - 0.5f);
v = Math.round((v + 1.0f) * mapSize * 0.5f - 0.5f);
}
@ -533,7 +533,7 @@ public class EnvMapUtils {
}
float phi;
long ui = i;
store.setX((float) i / (float) nbrSample);
store.setX(i / (float) nbrSample);
/* From http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
* Radical Inverse : Van der Corput */
@ -544,7 +544,7 @@ public class EnvMapUtils {
ui = ((ui & 0x00FF00FF) << 8) | ((ui & 0xFF00FF00) >>> 8);
ui = ui & 0xffffffff;
store.setY(2.3283064365386963e-10f * (float) (ui)); /* 0x100000000 */
store.setY(2.3283064365386963e-10f * ui); /* 0x100000000 */
phi = 2.0f * PI * store.y;
store.setZ(cos(phi));
@ -611,7 +611,7 @@ public class EnvMapUtils {
int size = cubeMap.getImage().getWidth();
Picture[] pics = new Picture[6];
float ratio = 128f / (float) size;
float ratio = 128f / size;
for (int i = 0; i < 6; i++) {
pics[i] = new Picture("bla");

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -215,7 +215,7 @@ public class BitmapFont implements Savable {
firstCharOfLine = true;
continue;
}
BitmapCharacter c = charSet.getCharacter((int) theChar);
BitmapCharacter c = charSet.getCharacter(theChar);
if (c != null){
if (theChar == '\\' && i<text.length()-1 && text.charAt(i+1)=='#'){
if (i+5<text.length() && text.charAt(i+5)=='#'){

@ -46,7 +46,7 @@ import java.util.regex.Pattern;
*/
class ColorTags {
private static final Pattern colorPattern = Pattern.compile("\\\\#([0-9a-fA-F]{8})#|\\\\#([0-9a-fA-F]{6})#|" +
"\\\\#([0-9a-fA-F]{4})#|\\\\#([0-9a-fA-F]{3})#");
"\\\\#([0-9a-fA-F]{4})#|\\\\#([0-9a-fA-F]{3})#");
private LinkedList<Range> colors = new LinkedList<Range>();
private String text;
private String original;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -178,7 +178,7 @@ public class InputManager implements RawInputListener {
if (safeMode || frameDelta == 0) {
return 1f;
} else {
return FastMath.clamp((float) timeDelta / (float) frameDelta, 0, 1);
return FastMath.clamp(timeDelta / (float) frameDelta, 0, 1);
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -206,7 +206,7 @@ public class LightProbe extends Light implements Savable {
*/
@Deprecated
public BoundingVolume getBounds() {
return new BoundingSphere(((SphereProbeArea)area).getRadius(), ((SphereProbeArea)area).getCenter());
return new BoundingSphere(area.getRadius(), ((SphereProbeArea)area).getCenter());
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -104,6 +104,6 @@ public class MatParamTexture extends MatParam {
super.read(im);
InputCapsule ic = im.getCapsule(this);
texture = (Texture) value;
colorSpace = (ColorSpace) ic.readEnum("colorSpace", ColorSpace.class, null);
colorSpace = ic.readEnum("colorSpace", ColorSpace.class, null);
}
}

@ -379,7 +379,7 @@ public final class ColorRGBA implements Savable, Cloneable, java.io.Serializable
/**
* <code>toString</code> returns the string representation of this <code>ColorRGBA</code>.
* The format of the string is:<br>
* <Class Name>: [R=RR.RRRR, G=GG.GGGG, B=BB.BBBB, A=AA.AAAA]
* Color[R.RRRR, G.GGGG, B.BBBB, A.AAAA]
* @return The string representation of this <code>ColorRGBA</code>.
*/
@Override

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,130 +36,129 @@ import java.util.List;
/**
* This class offers methods to help with curves and surfaces calculations.
*
* @author Marcin Roguski (Kealthas)
*/
public class CurveAndSurfaceMath {
private static final float KNOTS_MINIMUM_DELTA = 0.0001f;
private static final float KNOTS_MINIMUM_DELTA = 0.0001f;
/**
* A private constructor is defined to avoid instantiation of this class.
*/
private CurveAndSurfaceMath() {
}
/**
* A private constructor is defined to avoid instantiation of this
* class.
*/
private CurveAndSurfaceMath() {}
/**
* This method interpolates the data for the nurbs curve.
* @param u
* the u value
* @param nurbSpline
* the nurbs spline definition
* @param store
* the resulting point in 3D space
*/
public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) {
if (nurbSpline.getType() != SplineType.Nurb) {
throw new IllegalArgumentException("Given spline is not of a NURB type!");
}
List<Vector3f> controlPoints = nurbSpline.getControlPoints();
float[] weights = nurbSpline.getWeights();
List<Float> knots = nurbSpline.getKnots();
int controlPointAmount = controlPoints.size();
/**
* This method interpolates the data for the nurbs curve.
*
* @param u the u value
* @param nurbSpline
* the nurbs spline definition
* @param store
* the resulting point in 3D space
*/
public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) {
if (nurbSpline.getType() != SplineType.Nurb) {
throw new IllegalArgumentException("Given spline is not of a NURB type!");
}
List<Vector3f> controlPoints = nurbSpline.getControlPoints();
float[] weights = nurbSpline.getWeights();
List<Float> knots = nurbSpline.getKnots();
int controlPointAmount = controlPoints.size();
store.set(Vector3f.ZERO);
float delimeter = 0;
for (int i = 0; i < controlPointAmount; ++i) {
float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots);
store.addLocal(nurbSpline.getControlPoints().get(i)
.mult(val));
delimeter += val;
}
store.divideLocal(delimeter);
}
store.set(Vector3f.ZERO);
float delimeter = 0;
for (int i = 0; i < controlPointAmount; ++i) {
float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots);
store.addLocal(nurbSpline.getControlPoints().get(i)
.mult(val));
delimeter += val;
}
store.divideLocal(delimeter);
}
/**
* This method interpolates the data for the nurbs surface.
*
* @param u the u value
* @param v the v value
* @param controlPoints
* the nurbs' control points
* @param knots
* the nurbs' knots
* @param basisUFunctionDegree
* the degree of basis U function
* @param basisVFunctionDegree
* the degree of basis V function
* @param store
* the resulting point in 3D space
*/
public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots,
int basisUFunctionDegree, int basisVFunctionDegree, Vector3f store) {
store.set(Vector3f.ZERO);
float delimeter = 0;
int vControlPointsAmount = controlPoints.size();
int uControlPointsAmount = controlPoints.get(0).size();
for (int i = 0; i < vControlPointsAmount; ++i) {
for (int j = 0; j < uControlPointsAmount; ++j) {
Vector4f controlPoint = controlPoints.get(i).get(j);
float val = controlPoint.w
* CurveAndSurfaceMath.computeBaseFunctionValue(i, basisVFunctionDegree, v, knots[1])
* CurveAndSurfaceMath.computeBaseFunctionValue(j, basisUFunctionDegree, u, knots[0]);
store.addLocal(controlPoint.x * val, controlPoint.y * val, controlPoint.z * val);
delimeter += val;
}
}
store.divideLocal(delimeter);
}
/**
* This method interpolates the data for the nurbs surface.
*
* @param u
* the u value
* @param v
* the v value
* @param controlPoints
* the nurbs' control points
* @param knots
* the nurbs' knots
* @param basisUFunctionDegree
* the degree of basis U function
* @param basisVFunctionDegree
* the degree of basis V function
* @param store
* the resulting point in 3D space
*/
public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots,
int basisUFunctionDegree, int basisVFunctionDegree, Vector3f store) {
store.set(Vector3f.ZERO);
float delimeter = 0;
int vControlPointsAmount = controlPoints.size();
int uControlPointsAmount = controlPoints.get(0).size();
for (int i = 0; i < vControlPointsAmount; ++i) {
for (int j = 0; j < uControlPointsAmount; ++j) {
Vector4f controlPoint = controlPoints.get(i).get(j);
float val = controlPoint.w
* CurveAndSurfaceMath.computeBaseFunctionValue(i, basisVFunctionDegree, v, knots[1])
* CurveAndSurfaceMath.computeBaseFunctionValue(j, basisUFunctionDegree, u, knots[0]);
store.addLocal(controlPoint.x * val, controlPoint.y * val, controlPoint.z * val);
delimeter += val;
}
}
store.divideLocal(delimeter);
}
/**
* This method prepares the knots to be used. If the knots represent
* non-uniform B-splines (first and last knot values are being repeated) it
* leads to NaN results during calculations. This method adds a small number
* to each of such knots to avoid NaN's.
*
* @param knots
* the knots to be prepared to use
* @param basisFunctionDegree
* the degree of basis function
*/
// TODO: improve this; constant delta may lead to errors if the difference between tha last repeated
// point and the following one is lower than it
public static void prepareNurbsKnots(List<Float> knots, int basisFunctionDegree) {
float delta = KNOTS_MINIMUM_DELTA;
float prevValue = knots.get(0).floatValue();
for (int i = 1; i < knots.size(); ++i) {
float value = knots.get(i).floatValue();
if (value <= prevValue) {
value += delta;
knots.set(i, Float.valueOf(value));
delta += KNOTS_MINIMUM_DELTA;
} else {
delta = KNOTS_MINIMUM_DELTA;//reset the delta's value
}
/**
* This method prepares the knots to be used. If the knots represent non-uniform B-splines (first and last knot values are being
* repeated) it leads to NaN results during calculations. This method adds a small number to each of such knots to avoid NaN's.
* @param knots
* the knots to be prepared to use
* @param basisFunctionDegree
* the degree of basis function
*/
// TODO: improve this; constant delta may lead to errors if the difference between tha last repeated
// point and the following one is lower than it
public static void prepareNurbsKnots(List<Float> knots, int basisFunctionDegree) {
float delta = KNOTS_MINIMUM_DELTA;
float prevValue = knots.get(0).floatValue();
for(int i=1;i<knots.size();++i) {
float value = knots.get(i).floatValue();
if(value<=prevValue) {
value += delta;
knots.set(i, Float.valueOf(value));
delta += KNOTS_MINIMUM_DELTA;
} else {
delta = KNOTS_MINIMUM_DELTA;//reset the delta's value
}
prevValue = value;
}
}
prevValue = value;
}
}
/**
* This method computes the base function value for the NURB curve.
* @param i
* the knot index
* @param k
* the base function degree
* @param t
* the knot value
* @param knots
* the knots' values
* @return the base function value
*/
private static float computeBaseFunctionValue(int i, int k, float t, List<Float> knots) {
if (k == 1) {
return knots.get(i) <= t && t < knots.get(i + 1) ? 1.0f : 0.0f;
} else {
return (t - knots.get(i)) / (knots.get(i + k - 1) - knots.get(i)) *
CurveAndSurfaceMath.computeBaseFunctionValue(i, k - 1, t, knots)
+ (knots.get(i + k) - t) / (knots.get(i + k) - knots.get(i + 1)) *
CurveAndSurfaceMath.computeBaseFunctionValue(i + 1, k - 1, t, knots);
}
}
/**
* This method computes the base function value for the NURB curve.
*
* @param i the knot index
* @param k the base function degree
* @param t the knot value
* @param knots
* the knots' values
* @return the base function value
*/
private static float computeBaseFunctionValue(int i, int k, float t, List<Float> knots) {
if (k == 1) {
return knots.get(i) <= t && t < knots.get(i + 1) ? 1.0f : 0.0f;
} else {
return (t - knots.get(i)) / (knots.get(i + k - 1) - knots.get(i))
* CurveAndSurfaceMath.computeBaseFunctionValue(i, k - 1, t, knots)
+ (knots.get(i + k) - t) / (knots.get(i + k) - knots.get(i + 1))
* CurveAndSurfaceMath.computeBaseFunctionValue(i + 1, k - 1, t, knots);
}
}
}

@ -49,15 +49,15 @@ public class Eigen3f implements java.io.Serializable {
public Eigen3f() {
}
public Eigen3f(Matrix3f data) {
calculateEigen(data);
}
public void calculateEigen(Matrix3f data) {
// prep work...
public void calculateEigen(Matrix3f data) {
// prep work...
eigenVectors[0] = new Vector3f();
eigenVectors[1] = new Vector3f();
eigenVectors[2] = new Vector3f();
@ -134,7 +134,7 @@ public class Eigen3f implements java.io.Serializable {
eigenValues[i] *= maxMagnitude;
}
}
}
}
/**
* Scale the matrix so its entries are in [-1,1]. The scaling is applied

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -41,44 +41,67 @@ import java.util.Random;
* @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $
*/
final public class FastMath {
private FastMath() {
}
/** A "close to zero" double epsilon value for use*/
/**
* A "close to zero" double epsilon value for use
*/
public static final double DBL_EPSILON = 2.220446049250313E-16d;
/** A "close to zero" float epsilon value for use*/
/**
* A "close to zero" float epsilon value for use
*/
public static final float FLT_EPSILON = 1.1920928955078125E-7f;
/** A "close to zero" float epsilon value for use*/
/**
* A "close to zero" float epsilon value for use
*/
public static final float ZERO_TOLERANCE = 0.0001f;
public static final float ONE_THIRD = 1f / 3f;
/** The value PI as a float. (180 degrees) */
/**
* The value PI as a float. (180 degrees)
*/
public static final float PI = (float) Math.PI;
/** The value 2PI as a float. (360 degrees) */
/**
* The value 2PI as a float. (360 degrees)
*/
public static final float TWO_PI = 2.0f * PI;
/** The value PI/2 as a float. (90 degrees) */
/**
* The value PI/2 as a float. (90 degrees)
*/
public static final float HALF_PI = 0.5f * PI;
/** The value PI/4 as a float. (45 degrees) */
/**
* The value PI/4 as a float. (45 degrees)
*/
public static final float QUARTER_PI = 0.25f * PI;
/** The value 1/PI as a float. */
/**
* The value 1/PI as a float.
*/
public static final float INV_PI = 1.0f / PI;
/** The value 1/(2PI) as a float. */
/**
* The value 1/(2PI) as a float.
*/
public static final float INV_TWO_PI = 1.0f / TWO_PI;
/** A value to multiply a degree value by, to convert it to radians. */
/**
* A value to multiply a degree value by, to convert it to radians.
*/
public static final float DEG_TO_RAD = PI / 180.0f;
/** A value to multiply a radian value by, to convert it to degrees. */
/**
* A value to multiply a radian value by, to convert it to degrees.
*/
public static final float RAD_TO_DEG = 180.0f / PI;
/** A precreated random object for random numbers. */
/**
* A precreated random object for random numbers.
*/
public static final Random rand = new Random(System.currentTimeMillis());
/**
* Returns true if the number is a power of 2 (2,4,8,16...)
*
*
* A good implementation found on the Java boards. note: a number is a power
* of two if and only if it is the smallest number with that number of
* significant bits. Therefore, if you subtract 1, you know that the new
* number will have fewer bits, so ANDing the original number with anything
* less than it will give 0.
*
*
* @param number
* The number to test.
* @return True if it is a power of two.
@ -89,10 +112,10 @@ final public class FastMath {
/**
* Get the next power of two of the given number.
*
*
* E.g. for an input 100, this returns 128.
* Returns 1 for all numbers less than or equal to 1.
*
*
* @param number The number to obtain the POT for.
* @return The next power of two.
*/
@ -111,7 +134,7 @@ final public class FastMath {
/**
* Linear interpolation from startValue to endValue by the given percent.
* Basically: ((1 - percent) * startValue) + (percent * endValue)
*
*
* @param scale
* scale value to use. if 1, use endValue, if 0, use startValue.
* @param startValue
@ -146,7 +169,8 @@ final public class FastMath {
* @param store a vector3f to store the result
* @return The interpolated value between startValue and endValue.
*/
public static Vector3f interpolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) {
public static Vector3f interpolateLinear(float scale, Vector3f startValue,
Vector3f endValue, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
@ -177,6 +201,7 @@ final public class FastMath {
* if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1)
@ -193,14 +218,16 @@ final public class FastMath {
* Linear extrapolation from startValue to endValue by the given scale.
* if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1.
* Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1)
* @param store an initialized vector to store the return value
* @return an extrapolation for the given parameters
*/
public static Vector3f extrapolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) {
public static Vector3f extrapolateLinear(float scale, Vector3f startValue,
Vector3f endValue, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
@ -218,6 +245,7 @@ final public class FastMath {
* if scale is between 0 and 1 this method returns the same result as interpolateLinear
* if the scale is over 1 the value is linearly extrapolated.
* Note that the end value is the value for a scale of 1.
*
* @param scale the scale for extrapolation
* @param startValue the starting value (scale = 0)
* @param endValue the end value (scale = 1)
@ -227,7 +255,8 @@ final public class FastMath {
return extrapolateLinear(scale, startValue, endValue, null);
}
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
/**
* Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
* here is the interpolation matrix
* m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ]
@ -250,10 +279,11 @@ final public class FastMath {
c3 = 2 * T * p0 + (T - 3) * p1 + (3 - 2 * T) * p2 + -T * p3;
c4 = -T * p0 + (2 - T) * p1 + (T - 2) * p2 + T * p3;
return (float) (((c4 * u + c3) * u + c2) * u + c1);
return ((c4 * u + c3) * u + c2) * u + c1;
}
/**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
/**
* Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
* here is the interpolation matrix
* m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ]
@ -270,7 +300,8 @@ final public class FastMath {
* @param store a Vector3f to store the result
* @return CatmullRom interpolation
*/
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0,
Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
@ -282,7 +313,7 @@ final public class FastMath {
/**
* Interpolate a spline between at least 4 control points using the
* Catmull-Rom equation. Here is the interpolation matrix:
* Catmull-Rom equation. Here is the interpolation matrix:
* m = [ 0.0 1.0 0.0 0.0 ]
* [-T 0.0 T 0.0 ]
* [ 2T T-3 3-2T -T ]
@ -297,7 +328,8 @@ final public class FastMath {
* @param p3 control point 3
* @return CatmullRom interpolation
*/
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) {
public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0,
Vector3f p1, Vector3f p2, Vector3f p3) {
return interpolateCatmullRom(u, T, p0, p1, p2, p3, null);
}
@ -326,7 +358,8 @@ final public class FastMath {
+ p3 * u2 * u;
}
/**Interpolate a spline between at least 4 control points following the Bezier equation.
/**
* Interpolate a spline between at least 4 control points following the Bezier equation.
* here is the interpolation matrix
* m = [ -1.0 3.0 -3.0 1.0 ]
* [ 3.0 -6.0 3.0 0.0 ]
@ -342,7 +375,8 @@ final public class FastMath {
* @param store a Vector3f to store the result
* @return Bezier interpolation
*/
public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1,
Vector3f p2, Vector3f p3, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
@ -352,7 +386,8 @@ final public class FastMath {
return store;
}
/**Interpolate a spline between at least 4 control points following the Bezier equation.
/**
* Interpolate a spline between at least 4 control points following the Bezier equation.
* here is the interpolation matrix
* m = [ -1.0 3.0 -3.0 1.0 ]
* [ 3.0 -6.0 3.0 0.0 ]
@ -373,6 +408,7 @@ final public class FastMath {
/**
* Compute the length of a CatmullRom spline between control points 1 and 2
*
* @param p0 control point 0
* @param p1 control point 1
* @param p2 control point 2
@ -382,7 +418,8 @@ final public class FastMath {
* @param curveTension the curve tension
* @return the length of the segment
*/
public static float getCatmullRomP1toP2Length(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, float startRange, float endRange, float curveTension) {
public static float getCatmullRomP1toP2Length(Vector3f p0, Vector3f p1,
Vector3f p2, Vector3f p3, float startRange, float endRange, float curveTension) {
float epsilon = 0.001f;
float middleValue = (startRange + endRange) * 0.5f;
@ -409,6 +446,7 @@ final public class FastMath {
/**
* Compute the length on a Bezier spline between control points 1 and 2.
*
* @param p0 control point 0
* @param p1 control point 1
* @param p2 control point 2
@ -432,6 +470,7 @@ final public class FastMath {
* Special cases:
* <ul><li>If fValue is smaller than -1, then the result is PI.
* <li>If the argument is greater than 1, then the result is 0.</ul>
*
* @param fValue The value to arc cosine.
* @return The angle, in radians.
* @see java.lang.Math#acos(double)
@ -453,6 +492,7 @@ final public class FastMath {
* Special cases:
* <ul><li>If fValue is smaller than -1, then the result is -HALF_PI.
* <li>If the argument is greater than 1, then the result is HALF_PI.</ul>
*
* @param fValue The value to arc sine.
* @return the angle in radians.
* @see java.lang.Math#asin(double)
@ -471,6 +511,7 @@ final public class FastMath {
/**
* Returns the arc tangent of an angle given in radians.<br>
*
* @param fValue The angle, in radians.
* @return fValue's atan
* @see java.lang.Math#atan(double)
@ -481,6 +522,7 @@ final public class FastMath {
/**
* A direct call to Math.atan2.
*
* @param fY
* @param fX
* @return Math.atan2(fY,fX)
@ -491,7 +533,8 @@ final public class FastMath {
}
/**
* Rounds a fValue up. A call to Math.ceil
* Rounds a fValue up. A call to Math.ceil
*
* @param fValue The value.
* @return The fValue rounded up
* @see java.lang.Math#ceil(double)
@ -502,9 +545,10 @@ final public class FastMath {
/**
* Returns cosine of an angle. Direct call to java.lang.Math
* @see Math#cos(double)
*
* @see Math#cos(double)
* @param v The angle to cosine.
* @return the cosine of the angle.
* @return the cosine of the angle.
*/
public static float cos(float v) {
return (float) Math.cos(v);
@ -512,7 +556,8 @@ final public class FastMath {
/**
* Returns the sine of an angle. Direct call to java.lang.Math
* @see Math#sin(double)
*
* @see Math#sin(double)
* @param v The angle to sine.
* @return the sine of the angle.
*/
@ -522,6 +567,7 @@ final public class FastMath {
/**
* Returns E^fValue
*
* @param fValue Value to raise to a power.
* @return The value E^fValue
* @see java.lang.Math#exp(double)
@ -532,6 +578,7 @@ final public class FastMath {
/**
* Returns Absolute value of a float.
*
* @param fValue The value to abs.
* @return The abs of the value.
* @see java.lang.Math#abs(float)
@ -545,6 +592,7 @@ final public class FastMath {
/**
* Returns a number rounded down.
*
* @param fValue The value to round
* @return The given number rounded down
* @see java.lang.Math#floor(double)
@ -555,6 +603,7 @@ final public class FastMath {
/**
* Returns 1/sqrt(fValue)
*
* @param fValue The value to process.
* @return 1/sqrt(fValue)
* @see java.lang.Math#sqrt(double)
@ -574,6 +623,7 @@ final public class FastMath {
/**
* Returns the log base E of a value.
*
* @param fValue The value to log.
* @return The log of fValue base E
* @see java.lang.Math#log(double)
@ -583,8 +633,9 @@ final public class FastMath {
}
/**
* Returns the logarithm of value with given base, calculated as log(value)/log(base),
* Returns the logarithm of value with given base, calculated as log(value)/log(base),
* so that pow(base, return)==value (contributed by vear)
*
* @param value The value to log.
* @param base Base of logarithm.
* @return The logarithm of value with given base
@ -594,7 +645,8 @@ final public class FastMath {
}
/**
* Returns a number raised to an exponent power. fBase^fExponent
* Returns a number raised to an exponent power. fBase^fExponent
*
* @param fBase The base value (IE 2)
* @param fExponent The exponent value (IE 3)
* @return base raised to exponent (IE 8)
@ -605,7 +657,8 @@ final public class FastMath {
}
/**
* Returns the value squared. fValue ^ 2
* Returns the value squared. fValue ^ 2
*
* @param fValue The value to square.
* @return The square of the given value.
*/
@ -615,6 +668,7 @@ final public class FastMath {
/**
* Returns the square root of a given value.
*
* @param fValue The value to sqrt.
* @return The square root of the given value.
* @see java.lang.Math#sqrt(double)
@ -624,8 +678,8 @@ final public class FastMath {
}
/**
* Returns the tangent of a value. If USE_FAST_TRIG is enabled, an approximate value
* is returned. Otherwise, a direct value is used.
* Returns the tangent of the specified angle.
*
* @param fValue The value to tangent, in radians.
* @return The tangent of fValue.
* @see java.lang.Math#tan(double)
@ -636,6 +690,7 @@ final public class FastMath {
/**
* Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
*
* @param iValue The integer to examine.
* @return The integer's sign.
*/
@ -651,6 +706,7 @@ final public class FastMath {
/**
* Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
*
* @param fValue The float to examine.
* @return The float's sign.
*/
@ -661,6 +717,7 @@ final public class FastMath {
/**
* Given 3 points in a 2d plane, this function computes if the points going from A-B-C
* are moving counter clock wise.
*
* @param p0 Point 0.
* @param p1 Point 1.
* @param p2 Point 2.
@ -690,6 +747,7 @@ final public class FastMath {
/**
* Test if a point is inside a triangle. 1 if the point is on the ccw side,
* -1 if the point is on the cw side, and 0 if it is on neither.
*
* @param t0 First point of the triangle.
* @param t1 Second point of the triangle.
* @param t2 Third point of the triangle.
@ -720,6 +778,7 @@ final public class FastMath {
/**
* A method that computes normal for a triangle defined by three vertices.
*
* @param v1 first vertex
* @param v2 second vertex
* @param v3 third vertex
@ -733,6 +792,24 @@ final public class FastMath {
/**
* Returns the determinant of a 4x4 matrix.
*
* @param m00 the element in row 0, column 0 of the matrix
* @param m01 the element in row 0, column 1 of the matrix
* @param m02 the element in row 0, column 2 of the matrix
* @param m03 the element in row 0, column 3 of the matrix
* @param m10 the element in row 1, column 0 of the matrix
* @param m11 the element in row 1, column 1 of the matrix
* @param m12 the element in row 1, column 2 of the matrix
* @param m13 the element in row 1, column 3 of the matrix
* @param m20 the element in row 2, column 0 of the matrix
* @param m21 the element in row 2, column 1 of the matrix
* @param m22 the element in row 2, column 2 of the matrix
* @param m23 the element in row 2, column 3 of the matrix
* @param m30 the element in row 3, column 0 of the matrix
* @param m31 the element in row 3, column 1 of the matrix
* @param m32 the element in row 3, column 2 of the matrix
* @param m33 the element in row 3, column 3 of the matrix
* @return the determinant
*/
public static float determinant(double m00, double m01, double m02,
double m03, double m10, double m11, double m12, double m13,
@ -753,9 +830,9 @@ final public class FastMath {
/**
* Returns a random float between 0 and 1.
*
*
* @return A random float between <tt>0.0f</tt> (inclusive) to
* <tt>1.0f</tt> (exclusive).
* <tt>1.0f</tt> (exclusive).
*/
public static float nextRandomFloat() {
return rand.nextFloat();
@ -763,9 +840,11 @@ final public class FastMath {
/**
* Returns a random integer between min and max.
*
*
* @param min the desired minimum value
* @param max the desired maximum value
* @return A random int between <tt>min</tt> (inclusive) to
* <tt>max</tt> (inclusive).
* <tt>max</tt> (inclusive).
*/
public static int nextRandomInt(int min, int max) {
return (int) (nextRandomFloat() * (max - min + 1)) + min;
@ -778,6 +857,12 @@ final public class FastMath {
/**
* Converts a point from Spherical coordinates to Cartesian (using positive
* Y as up) and stores the results in the store var.
*
* @param sphereCoords the input spherical coordinates: x=distance from
* origin, y=longitude in radians, z=latitude in radians (not null,
* unaffected)
* @param store storage for the result (modified if not null)
* @return the Cartesian coordinates (either store or a new vector)
*/
public static Vector3f sphericalToCartesian(Vector3f sphereCoords,
Vector3f store) {
@ -796,6 +881,11 @@ final public class FastMath {
* Converts a point from Cartesian coordinates (using positive Y as up) to
* Spherical and stores the results in the store var. (Radius, Azimuth,
* Polar)
*
* @param cartCoords the input Cartesian coordinates (not null, unaffected)
* @param store storage for the result (modified if not null)
* @return the Cartesian coordinates: x=distance from origin, y=longitude in
* radians, z=latitude in radians (either store or a new vector)
*/
public static Vector3f cartesianToSpherical(Vector3f cartCoords,
Vector3f store) {
@ -820,6 +910,12 @@ final public class FastMath {
/**
* Converts a point from Spherical coordinates to Cartesian (using positive
* Z as up) and stores the results in the store var.
*
* @param sphereCoords the input spherical coordinates: x=distance from
* origin, y=longitude in radians, z=latitude in radians (not null,
* unaffected)
* @param store storage for the result (modified if not null)
* @return the Cartesian coordinates (either store or a new vector)
*/
public static Vector3f sphericalToCartesianZ(Vector3f sphereCoords,
Vector3f store) {
@ -838,6 +934,11 @@ final public class FastMath {
* Converts a point from Cartesian coordinates (using positive Z as up) to
* Spherical and stores the results in the store var. (Radius, Azimuth,
* Polar)
*
* @param cartCoords the input Cartesian coordinates (not null, unaffected)
* @param store storage for the result (modified if not null)
* @return the Cartesian coordinates: x=distance from origin, y=latitude in
* radians, z=longitude in radians (either store or a new vector)
*/
public static Vector3f cartesianZToSpherical(Vector3f cartCoords,
Vector3f store) {
@ -861,9 +962,13 @@ final public class FastMath {
/**
* Takes a value and expresses it in terms of min to max.
*
*
* @param val -
* the angle to normalize (in radians)
* @param min
* the lower limit of the range
* @param max
* the upper limit of the range
* @return the normalized angle (also in radians)
*/
public static float normalize(float val, float min, float max) {
@ -899,7 +1004,7 @@ final public class FastMath {
/**
* Take a float input and clamp it between min and max.
*
*
* @param input
* @param min
* @param max
@ -923,9 +1028,9 @@ final public class FastMath {
* Determine if two floats are approximately equal.
* This takes into account the magnitude of the floats, since
* large numbers will have larger differences be close to each other.
*
*
* Should return true for a=100000, b=100001, but false for a=10000, b=10001.
*
*
* @param a The first float to compare
* @param b The second float to compare
* @return True if a and b are approximately equal, false otherwise.
@ -937,7 +1042,7 @@ final public class FastMath {
return (abs(a - b) / Math.max(abs(a), abs(b))) <= 0.00001f;
}
}
/**
* Converts a single precision (32 bit) floating point value
* into half precision (16 bit).
@ -996,6 +1101,7 @@ final public class FastMath {
/**
* Converts a range of min/max to a 0-1 range.
*
* @param value the value between min-max (inclusive).
* @param min the minimum of the range.
* @param max the maximum of the range.
@ -1004,5 +1110,4 @@ final public class FastMath {
public static float unInterpolateLinear(float value, float min, float max) {
return (value - min) / (max - min);
}
}

@ -150,7 +150,7 @@ public class Line implements Savable, Cloneable, java.io.Serializable {
origin.addLocal(compVec1);
}
origin.multLocal(1f / (float) length);
origin.multLocal(1f / length);
// compute sums of products
float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f;

@ -71,6 +71,11 @@ public class LineSegment implements Cloneable, Savable, java.io.Serializable {
/**
* <p>Creates a new LineSegment with the given origin, direction and extent.</p>
* <p>Note that the origin is not one of the ends of the LineSegment, but its center.</p>
*
* @param origin the location of the desired midpoint (alias created)
* @param direction the desired direction vector (alias created)
* @param extent the extent: 1/2 of the desired length, assuming direction
* is a unit vector
*/
public LineSegment(Vector3f origin, Vector3f direction, float extent) {
this.origin = origin;
@ -81,6 +86,9 @@ public class LineSegment implements Cloneable, Savable, java.io.Serializable {
/**
* <p>Creates a new LineSegment with a given origin and end. This constructor will calculate the
* center, the direction and the extent.</p>
*
* @param start location of the negative endpoint (not null, unaffected)
* @param end location of the negative endpoint (not null, unaffected)
*/
public LineSegment(Vector3f start, Vector3f end) {
this.origin = new Vector3f(0.5f * (start.x + end.x), 0.5f * (start.y + end.y), 0.5f * (start.z + end.z));
@ -604,6 +612,9 @@ public class LineSegment implements Cloneable, Savable, java.io.Serializable {
/**
* <p>Evaluates whether a given point is contained within the axis aligned bounding box
* that contains this LineSegment.</p><p>This function is float error aware.</p>
*
* @param point the location of the input point (not null, unaffected)
* @return true if contained in the box, otherwise false
*/
public boolean isPointInsideBounds(Vector3f point) {
return isPointInsideBounds(point, Float.MIN_VALUE);
@ -613,6 +624,10 @@ public class LineSegment implements Cloneable, Savable, java.io.Serializable {
* <p>Evaluates whether a given point is contained within the axis aligned bounding box
* that contains this LineSegment.</p><p>This function accepts an error parameter, which
* is added to the extent of the bounding box.</p>
*
* @param point the location of the input point (not null, unaffected)
* @param error the desired margin for error
* @return true if contained in the box, otherwise false
*/
public boolean isPointInsideBounds(Vector3f point, float error) {

@ -43,7 +43,7 @@ import java.util.logging.Logger;
* internally and is accessible via the get and set methods. Convenience methods
* are used for matrix operations as well as generating a matrix from a given
* set of values.
*
*
* @author Mark Powell
* @author Joshua Slack
*/
@ -61,7 +61,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Constructor instantiates a new <code>Matrix3f</code> object. The
* initial values for the matrix is that of the identity matrix.
*
*/
public Matrix3f() {
loadIdentity();
@ -69,25 +68,16 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* constructs a matrix with the given values.
*
* @param m00
* 0x0 in the matrix.
* @param m01
* 0x1 in the matrix.
* @param m02
* 0x2 in the matrix.
* @param m10
* 1x0 in the matrix.
* @param m11
* 1x1 in the matrix.
* @param m12
* 1x2 in the matrix.
* @param m20
* 2x0 in the matrix.
* @param m21
* 2x1 in the matrix.
* @param m22
* 2x2 in the matrix.
*
* @param m00 0x0 in the matrix.
* @param m01 0x1 in the matrix.
* @param m02 0x2 in the matrix.
* @param m10 1x0 in the matrix.
* @param m11 1x1 in the matrix.
* @param m12 1x2 in the matrix.
* @param m20 2x0 in the matrix.
* @param m21 2x1 in the matrix.
* @param m22 2x2 in the matrix.
*/
public Matrix3f(float m00, float m01, float m02, float m10, float m11,
float m12, float m20, float m21, float m22) {
@ -106,7 +96,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Copy constructor that creates a new <code>Matrix3f</code> object that
* is the same as the provided matrix.
*
*
* @param mat
* the matrix to copy.
*/
@ -133,7 +123,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>copy</code> transfers the contents of a given matrix to this
* matrix. If a null matrix is supplied, this matrix is set to the identity
* matrix.
*
*
* @param matrix
* the matrix to copy.
* @return this
@ -156,15 +146,12 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
* <code>get</code> retrieves a value from the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is
* thrown.
*
* @param i
* the row index.
* @param j
* the colum index.
* <code>get</code> retrieves a value from the matrix at the given position.
*
* @param i the row index.
* @param j the column index.
* @return the value at (i, j).
* @throws IllegalArgumentException if either index is invalid
*/
@SuppressWarnings("fallthrough")
public float get(int i, int j) {
@ -261,11 +248,11 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
throw new IndexOutOfBoundsException("Array size must be 9 or 16 in Matrix3f.get().");
}
}
/**
* Normalize this matrix and store the result in the store parameter that is
* returned.
*
*
* Note that the original matrix is not altered.
*
* @param store the matrix to store the result of the normalization. If this
@ -303,6 +290,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Normalize this matrix
*
* @return this matrix once normalized.
*/
public Matrix3f normalizeLocal() {
@ -312,7 +300,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a <code>Vector3f</code> object.
*
*
* @param i
* the column to retrieve. Must be between 0 and 2.
* @return the column specified by the index.
@ -324,7 +312,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a <code>Vector3f</code> object.
*
*
* @param i
* the column to retrieve. Must be between 0 and 2.
* @param store
@ -362,7 +350,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getColumn</code> returns one of three rows as specified by the
* parameter. This row is returned as a <code>Vector3f</code> object.
*
*
* @param i
* the row to retrieve. Must be between 0 and 2.
* @return the row specified by the index.
@ -374,7 +362,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getRow</code> returns one of three rows as specified by the
* parameter. This row is returned as a <code>Vector3f</code> object.
*
*
* @param i
* the row to retrieve. Must be between 0 and 2.
* @param store
@ -412,7 +400,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains
* the matrix data.
*
*
* @return matrix data as a FloatBuffer.
*/
public FloatBuffer toFloatBuffer() {
@ -428,10 +416,12 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
* data.
*
*
* @param fb
* the buffer to fill, starting at current position. Must have
* room for 9 more floats.
* @param columnMajor
* true &rarr; column-major order, false &rarr; row-major order
* @return matrix data as a FloatBuffer. (position is advanced by 9 and any
* limit set is not changed).
*/
@ -448,7 +438,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
TempVars vars = TempVars.get();
fillFloatArray(vars.matrixWrite, columnMajor);
fb.put(vars.matrixWrite, 0, 9);
@ -459,33 +448,32 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
public void fillFloatArray(float[] f, boolean columnMajor) {
if (columnMajor) {
f[ 0] = m00;
f[ 1] = m10;
f[ 2] = m20;
f[ 3] = m01;
f[ 4] = m11;
f[ 5] = m21;
f[ 6] = m02;
f[ 7] = m12;
f[ 8] = m22;
f[0] = m00;
f[1] = m10;
f[2] = m20;
f[3] = m01;
f[4] = m11;
f[5] = m21;
f[6] = m02;
f[7] = m12;
f[8] = m22;
} else {
f[ 0] = m00;
f[ 1] = m01;
f[ 2] = m02;
f[ 3] = m10;
f[ 4] = m11;
f[ 5] = m12;
f[ 6] = m20;
f[ 7] = m21;
f[ 8] = m22;
f[0] = m00;
f[1] = m01;
f[2] = m02;
f[3] = m10;
f[4] = m11;
f[5] = m12;
f[6] = m20;
f[7] = m21;
f[8] = m22;
}
}
/**
*
* <code>setColumn</code> sets a particular column of this matrix to that
* represented by the provided vector.
*
*
* @param i
* the column to set.
* @param column
@ -522,10 +510,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>setRow</code> sets a particular row of this matrix to that
* represented by the provided vector.
*
*
* @param i
* the row to set.
* @param row
@ -563,16 +550,16 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> places a given value into the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is
* thrown.
*
* position.
*
* @param i
* the row index.
* @param j
* the colum index.
* the column index.
* @param value
* the value for (i, j).
* @return this
* @throws IllegalArgumentException if either index is invalid
*/
@SuppressWarnings("fallthrough")
public Matrix3f set(int i, int j, float value) {
@ -620,14 +607,12 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>set</code> sets the values of the matrix to those supplied by the
* 3x3 two dimenion array.
*
*
* @param matrix
* the new values of the matrix.
* @throws JmeException
* if the array is not of size 9.
* @throws IllegalArgumentException if the matrix is not 3x3
* @return this
*/
public Matrix3f set(float[][] matrix) {
@ -651,13 +636,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Recreate Matrix using the provided axis.
*
* @param uAxis
* Vector3f
* @param vAxis
* Vector3f
* @param wAxis
* Vector3f
*
* @param uAxis Vector3f
* @param vAxis Vector3f
* @param wAxis Vector3f
*/
public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) {
m00 = uAxis.x;
@ -676,7 +658,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> sets the values of this matrix from an array of
* values assuming that the data is rowMajor order;
*
*
* @param matrix
* the matrix to set the value to.
* @return this
@ -688,7 +670,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> sets the values of this matrix from an array of
* values;
*
*
* @param matrix
* the matrix to set the value to.
* @param rowMajor
@ -726,11 +708,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>set</code> defines the values of the matrix based on a supplied
* <code>Quaternion</code>. It should be noted that all previous values
* will be overridden.
*
*
* @param quaternion
* the quaternion to create a rotational matrix from.
* @return this
@ -742,7 +723,6 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>loadIdentity</code> sets this matrix to the identity matrix.
* Where all values are zero except those along the diagonal which are one.
*
*/
public void loadIdentity() {
m01 = m02 = m10 = m12 = m20 = m21 = 0;
@ -762,7 +742,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>fromAngleAxis</code> sets this matrix4f to the values specified
* by an angle and an axis of rotation. This method creates an object, so
* use fromAngleNormalAxis if your axis is already normalized.
*
*
* @param angle
* the angle to rotate (in radians).
* @param axis
@ -776,7 +756,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>fromAngleNormalAxis</code> sets this matrix4f to the values
* specified by an angle and a normalized axis of rotation.
*
*
* @param angle
* the angle to rotate (in radians).
* @param axis
@ -811,7 +791,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix by a given matrix. The result
* matrix is returned as a new object. If the given matrix is null, a null
* matrix is returned.
*
*
* @param mat
* the matrix to multiply this matrix by.
* @return the result matrix.
@ -823,7 +803,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies this matrix by a given matrix. The result
* matrix is returned as a new object.
*
*
* @param mat
* the matrix to multiply this matrix by.
* @param product
@ -867,7 +847,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix by a given
* <code>Vector3f</code> object. The result vector is returned. If the
* given vector is null, null will be returned.
*
*
* @param vec
* the vector to multiply this matrix by.
* @return the result vector.
@ -879,7 +859,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in
* product.
*
*
* @param vec
* The Vector3f to multiply.
* @param product
@ -904,9 +884,9 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
* <code>multLocal</code> multiplies this matrix internally by
* <code>multLocal</code> multiplies this matrix internally by
* a given float scale factor.
*
*
* @param scale
* the value to scale by.
* @return this Matrix3f
@ -929,7 +909,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* <code>Vector3f</code> object. The result vector is stored inside the
* passed vector, then returned . If the given vector is null, null will be
* returned.
*
*
* @param vec
* the vector to multiply this matrix by.
* @return The passed vector after multiplication
@ -951,7 +931,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* matrix is saved in the current matrix. If the given matrix is null,
* nothing happens. The current matrix is returned. This is equivalent to
* this*=mat
*
*
* @param mat
* the matrix to multiply this matrix by.
* @return This matrix, after the multiplication
@ -962,7 +942,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Transposes this matrix in place. Returns this matrix for chaining
*
*
* @return This matrix after transpose
*/
public Matrix3f transposeLocal() {
@ -987,7 +967,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix as a new Matrix3f.
*
*
* @return The new inverse matrix
*/
public Matrix3f invert() {
@ -996,7 +976,8 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix and stores it in the given store.
*
*
* @param store storage for the result (modified if not null)
* @return The store
*/
public Matrix3f invert(Matrix3f store) {
@ -1025,7 +1006,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix locally.
*
*
* @return this
*/
public Matrix3f invertLocal() {
@ -1060,7 +1041,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Returns a new matrix representing the adjoint of this matrix.
*
*
* @return The adjoint matrix
*/
public Matrix3f adjoint() {
@ -1069,7 +1050,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Places the adjoint of this matrix in store (creates store if null.)
*
*
* @param store
* The matrix to store the result in. If null, a new matrix is created.
* @return store
@ -1094,7 +1075,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>determinant</code> generates the determinant of this matrix.
*
*
* @return the determinant
*/
public float determinant() {
@ -1107,7 +1088,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* Sets all of the values in this matrix to zero.
*
*
* @return this matrix
*/
public Matrix3f zero() {
@ -1120,7 +1101,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* This is inconsistent with general value vs local semantics, but is
* preserved for backwards compatibility. Use transposeNew() to transpose
* to a new object (value).
*
*
* @return this object for chaining.
*/
public Matrix3f transpose() {
@ -1144,7 +1125,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
* 1.0 0.0 0.0 <br>
* 0.0 1.0 0.0 <br>
* 0.0 0.0 1.0 <br>]<br>
*
*
* @return the string representation of this object.
*/
@Override
@ -1175,11 +1156,10 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc.
*
*
* @return the hashcode for this instance of Matrix4f.
* @see java.lang.Object#hashCode()
*/
@ -1210,7 +1190,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof Matrix3f) || o == null) {
if (!(o instanceof Matrix3f)) {
return false;
}
@ -1281,7 +1261,7 @@ public final class Matrix3f implements Savable, Cloneable, java.io.Serializable
/**
* A function for creating a rotation matrix that rotates a vector called
* "start" into another vector called "end".
*
*
* @param start
* normalized non-zero starting vector
* @param end

@ -41,10 +41,10 @@ import java.util.logging.Logger;
/**
* <code>Matrix4f</code> defines and maintains a 4x4 matrix in row major order.
* This matrix is intended for use in a translation and rotational capacity.
* It provides convenience methods for creating the matrix from a multitude
* This matrix is intended for use in a translation and rotational capacity.
* It provides convenience methods for creating the matrix from a multitude
* of sources.
*
*
* Matrices are stored assuming column vectors on the right, with the translation
* in the rightmost column. Element numbering is row,column, so m03 is the zeroth
* row, third column, which is the "x" translation part. This means that the implicit
@ -69,7 +69,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Constructor instantiates a new <code>Matrix</code> that is set to the
* identity matrix.
*
*/
public Matrix4f() {
loadIdentity();
@ -77,6 +76,23 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* constructs a matrix with the given values.
*
* @param m00 the desired value for row 0, column 0
* @param m01 the desired value for row 0, column 1
* @param m02 the desired value for row 0, column 2
* @param m03 the desired value for row 0, column 3
* @param m10 the desired value for row 1, column 0
* @param m11 the desired value for row 1, column 1
* @param m12 the desired value for row 1, column 2
* @param m13 the desired value for row 1, column 3
* @param m20 the desired value for row 2, column 0
* @param m21 the desired value for row 2, column 1
* @param m22 the desired value for row 2, column 2
* @param m23 the desired value for row 2, column 3
* @param m30 the desired value for row 3, column 0
* @param m31 the desired value for row 3, column 1
* @param m32 the desired value for row 3, column 2
* @param m33 the desired value for row 3, column 3
*/
public Matrix4f(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
@ -105,7 +121,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* Create a new Matrix4f, given data in column-major format.
*
* @param array
* An array of 16 floats in column-major format (translation in elements 12, 13 and 14).
* An array of 16 floats in column-major format (translation in elements 12, 13 and 14).
*/
public Matrix4f(float[] array) {
set(array, false);
@ -115,7 +131,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* Constructor instantiates a new <code>Matrix</code> that is set to the
* provided matrix. This constructor copies a given Matrix. If the provided
* matrix is null, the constructor sets the matrix to the identity.
*
*
* @param mat
* the matrix to copy.
*/
@ -127,7 +143,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>copy</code> transfers the contents of a given matrix to this
* matrix. If a null matrix is supplied, this matrix is set to the identity
* matrix.
*
*
* @param matrix
* the matrix to copy.
*/
@ -188,7 +204,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>get</code> retrieves the values of this object into
* a float array in row-major order.
*
*
* @param matrix
* the matrix to set the values into.
*/
@ -199,7 +215,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> retrieves the values of this object into
* a float array.
*
*
* @param matrix
* the matrix to set the values into.
* @param rowMajor
@ -250,14 +266,13 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>get</code> retrieves a value from the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is
* thrown.
*
* @param i
* the row index.
* @param j
* the colum index.
* position.
*
* @param i the row index.
* @param j the column index.
* @return the value at (i, j).
* @throws IllegalArgumentException
* if either index is invalid
*/
@SuppressWarnings("fallthrough")
public float get(int i, int j) {
@ -315,9 +330,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a float array of length 4.
*
* @param i
* the column to retrieve. Must be between 0 and 3.
*
* @param i the column to retrieve. Must be between 0 and 3.
* @return the column specified by the index.
*/
public float[] getColumn(int i) {
@ -327,9 +341,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>getColumn</code> returns one of three columns specified by the
* parameter. This column is returned as a float[4].
*
* @param i
* the column to retrieve. Must be between 0 and 3.
*
* @param i the column to retrieve. Must be between 0 and 3.
* @param store
* the float array to store the result in. if null, a new one
* is created.
@ -372,12 +385,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>setColumn</code> sets a particular column of this matrix to that
* represented by the provided vector.
*
* @param i
* the column to set.
*
* @param i the column to set.
* @param column
* the data to set.
*/
@ -420,15 +431,14 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> places a given value into the matrix at the given
* position. If the position is invalid a <code>JmeException</code> is
* thrown.
*
* @param i
* the row index.
* @param j
* the colum index.
* position.
*
* @param i the row index.
* @param j the column index.
* @param value
* the value for (i, j).
* @throws IllegalArgumentException
* if either index is invalid
*/
@SuppressWarnings("fallthrough")
public void set(int i, int j, float value) {
@ -502,11 +512,11 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> sets the values of this matrix from an array of
* values.
*
*
* @param matrix
* the matrix to set the value to.
* @throws JmeException
* if the array is not of size 16.
* @throws IllegalArgumentException
* if the array isn't 4x4
*/
public void set(float[][] matrix) {
if (matrix.length != 4 || matrix[0].length != 4) {
@ -531,10 +541,26 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
m32 = matrix[3][2];
m33 = matrix[3][3];
}
/**
* Sets the values of this matrix
*
* @param m00 the desired value for row 0, column 0
* @param m01 the desired value for row 0, column 1
* @param m02 the desired value for row 0, column 2
* @param m03 the desired value for row 0, column 3
* @param m10 the desired value for row 1, column 0
* @param m11 the desired value for row 1, column 1
* @param m12 the desired value for row 1, column 2
* @param m13 the desired value for row 1, column 3
* @param m20 the desired value for row 2, column 0
* @param m21 the desired value for row 2, column 1
* @param m22 the desired value for row 2, column 2
* @param m23 the desired value for row 2, column 3
* @param m30 the desired value for row 3, column 0
* @param m31 the desired value for row 3, column 1
* @param m32 the desired value for row 3, column 2
* @param m33 the desired value for row 3, column 3
*/
public void set(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
@ -564,6 +590,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
*
* @param matrix
* the matrix to read the value from.
* @return this
*/
public Matrix4f set(Matrix4f matrix) {
m00 = matrix.m00;
@ -588,7 +615,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> sets the values of this matrix from an array of
* values assuming that the data is rowMajor order;
*
*
* @param matrix
* the matrix to set the value to.
*/
@ -599,7 +626,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>set</code> sets the values of this matrix from an array of
* values;
*
*
* @param matrix
* the matrix to set the value to.
* @param rowMajor
@ -657,7 +684,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>transpose</code> locally transposes this Matrix.
*
*
* @return this object for chaining.
*/
public Matrix4f transposeLocal() {
@ -691,7 +718,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains
* the matrix data.
*
*
* @return matrix data as a FloatBuffer.
*/
public FloatBuffer toFloatBuffer() {
@ -701,7 +728,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains the
* matrix data.
*
*
* @param columnMajor
* if true, this buffer should be filled with column major data,
* otherwise it will be filled row major.
@ -718,6 +745,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with
* the matrix data.
*
* @param fb the buffer to fill, must be correct size
* @return matrix data as a FloatBuffer.
*/
@ -728,7 +756,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
* data.
*
*
* @param fb
* the buffer to fill, starting at current position. Must have
* room for 16 more floats.
@ -753,7 +781,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
TempVars vars = TempVars.get();
fillFloatArray(vars.matrixWrite, columnMajor);
fb.put(vars.matrixWrite, 0, 16);
@ -764,16 +791,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
public void fillFloatArray(float[] f, boolean columnMajor) {
if (columnMajor) {
f[ 0] = m00;
f[ 1] = m10;
f[ 2] = m20;
f[ 3] = m30;
f[ 4] = m01;
f[ 5] = m11;
f[ 6] = m21;
f[ 7] = m31;
f[ 8] = m02;
f[ 9] = m12;
f[0] = m00;
f[1] = m10;
f[2] = m20;
f[3] = m30;
f[4] = m01;
f[5] = m11;
f[6] = m21;
f[7] = m31;
f[8] = m02;
f[9] = m12;
f[10] = m22;
f[11] = m32;
f[12] = m03;
@ -781,16 +808,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
f[14] = m23;
f[15] = m33;
} else {
f[ 0] = m00;
f[ 1] = m01;
f[ 2] = m02;
f[ 3] = m03;
f[ 4] = m10;
f[ 5] = m11;
f[ 6] = m12;
f[ 7] = m13;
f[ 8] = m20;
f[ 9] = m21;
f[0] = m00;
f[1] = m01;
f[2] = m02;
f[3] = m03;
f[4] = m10;
f[5] = m11;
f[6] = m12;
f[7] = m13;
f[8] = m20;
f[9] = m21;
f[10] = m22;
f[11] = m23;
f[12] = m30;
@ -802,6 +829,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer.
*
* @param fb the buffer to read from, must be correct size
* @return this data as a FloatBuffer.
*/
@ -811,9 +839,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>readFloatBuffer</code> reads value for this matrix from a FloatBuffer.
*
* @param fb the buffer to read from, must be correct size
* @param columnMajor if true, this buffer should be filled with column
* major data, otherwise it will be filled row major.
* major data, otherwise it will be filled row major.
* @return this data as a FloatBuffer.
*/
public Matrix4f readFloatBuffer(FloatBuffer fb, boolean columnMajor) {
@ -859,7 +888,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>loadIdentity</code> sets this matrix to the identity matrix,
* namely all zeros with ones along the diagonal.
*
*/
public void loadIdentity() {
m01 = m02 = m03 = 0.0f;
@ -869,7 +897,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
m00 = m11 = m22 = m33 = 1.0f;
}
public void fromFrustum(float near, float far, float left, float right, float top, float bottom, boolean parallel) {
public void fromFrustum(float near, float far, float left, float right,
float top, float bottom, boolean parallel) {
loadIdentity();
if (parallel) {
// scale
@ -893,7 +922,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
// A
m02 = (right + left) / (right - left);
// B
// B
m12 = (top + bottom) / (top - bottom);
// C
@ -908,7 +937,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>fromAngleAxis</code> sets this matrix4f to the values specified
* by an angle and an axis of rotation. This method creates an object, so
* use fromAngleNormalAxis if your axis is already normalized.
*
*
* @param angle
* the angle to rotate (in radians).
* @param axis
@ -922,7 +951,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>fromAngleNormalAxis</code> sets this matrix4f to the values
* specified by an angle and a normalized axis of rotation.
*
*
* @param angle
* the angle to rotate (in radians).
* @param axis
@ -958,7 +987,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies this matrix by a scalar.
*
*
* @param scalar
* the scalar to multiply this matrix by.
*/
@ -998,7 +1027,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix with another matrix. The
* result matrix will then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right.
*
*
* @param in2
* the matrix to multiply this matrix by.
* @return the resultant matrix
@ -1011,7 +1040,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies this matrix with another matrix. The
* result matrix will then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right.
*
*
* @param in2
* the matrix to multiply this matrix by.
* @param store
@ -1095,7 +1124,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
+ m32 * in2.m23
+ m33 * in2.m33;
store.m00 = m[0];
store.m01 = m[1];
store.m02 = m[2];
@ -1118,10 +1146,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies this matrix with another matrix. The
* results are stored internally and a handle to this matrix will
* results are stored internally and a handle to this matrix will
* then be returned. This matrix will be on the left hand
* side, while the parameter matrix will be on the right.
*
*
* @param in2
* the matrix to multiply this matrix by.
* @return the resultant matrix
@ -1133,7 +1161,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies a vector about a rotation matrix. The
* resulting vector is returned as a new Vector3f.
*
*
* @param vec
* vec to multiply against.
* @return the rotated vector.
@ -1145,7 +1173,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies a vector about a rotation matrix and adds
* translation. The resulting vector is returned.
*
*
* @param vec
* vec to multiply against.
* @param store
@ -1211,7 +1239,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
*
* @param vec
* vec to multiply against.
*
* @return the rotated vector.
*/
public Vector4f multAcross(Vector4f vec) {
@ -1296,11 +1323,11 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* <code>mult</code> multiplies a vector about a rotation matrix and adds
* translation. The w value is returned as a result of
* multiplying the last column of the matrix by 1.0
*
*
* @param vec
* vec to multiply against.
* @param store
* a vector to store the result in.
* a vector to store the result in.
* @return the W value
*/
public float multProj(Vector3f vec, Vector3f store) {
@ -1314,7 +1341,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>mult</code> multiplies a vector about a rotation matrix. The
* resulting vector is returned.
*
*
* @param vec
* vec to multiply against.
* @param store
@ -1371,9 +1398,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
* <code>mult</code> multiplies an array of 4 floats against this rotation
* <code>mult</code> multiplies an array of 4 floats against this rotation
* matrix. The results are stored directly in the array. (vec4f x mat4f)
*
*
* @param vec4f
* float array (size 4) to multiply against the matrix.
* @return the vec4f for chaining.
@ -1395,9 +1422,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
* <code>mult</code> multiplies an array of 4 floats against this rotation
* <code>mult</code> multiplies an array of 4 floats against this rotation
* matrix. The results are stored directly in the array. (vec4f x mat4f)
*
*
* @param vec4f
* float array (size 4) to multiply against the matrix.
* @return the vec4f for chaining.
@ -1420,7 +1447,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix as a new Matrix4f.
*
*
* @return The new inverse matrix
*/
public Matrix4f invert() {
@ -1429,7 +1456,8 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix and stores it in the given store.
*
*
* @param store storage for the result (modified if not null)
* @return The store
*/
public Matrix4f invert(Matrix4f store) {
@ -1480,7 +1508,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Inverts this matrix locally.
*
*
* @return this
*/
public Matrix4f invertLocal() {
@ -1545,7 +1573,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Returns a new matrix representing the adjoint of this matrix.
*
*
* @return The adjoint matrix
*/
public Matrix4f adjoint() {
@ -1581,7 +1609,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Places the adjoint of this matrix in store (creates store if null.)
*
*
* @param store
* The matrix to store the result in. If null, a new matrix is created.
* @return store
@ -1626,7 +1654,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>determinant</code> generates the determinate of this matrix.
*
*
* @return the determinate
*/
public float determinant() {
@ -1648,7 +1676,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Sets all of the values in this matrix to zero.
*
*
* @return this matrix
*/
public Matrix4f zero() {
@ -1682,7 +1710,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>add</code> adds the values of a parameter matrix to this matrix.
*
*
* @param mat
* the matrix to add to this.
*/
@ -1738,18 +1766,18 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
mat.m20 = m20;
mat.m21 = m21;
mat.m22 = m22;
}
}
/**
* Retrieves the scale vector from the matrix.
*
* @return the scale vector
*/
public Vector3f toScaleVector() {
Vector3f result = new Vector3f();
this.toScaleVector(result);
return result;
}
/**
* Retrieves the scale vector from the matrix.
*
* @return the scale vector
*/
public Vector3f toScaleVector() {
Vector3f result = new Vector3f();
this.toScaleVector(result);
return result;
}
/**
* Retrieves the scale vector from the matrix and stores it into a given
@ -1759,16 +1787,16 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* @return the store vector
*/
public Vector3f toScaleVector(Vector3f store) {
float scaleX = (float) Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20);
float scaleY = (float) Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21);
float scaleZ = (float) Math.sqrt(m02 * m02 + m12 * m12 + m22 * m22);
float scaleX = (float) Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20);
float scaleY = (float) Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21);
float scaleZ = (float) Math.sqrt(m02 * m02 + m12 * m12 + m22 * m22);
store.set(scaleX, scaleY, scaleZ);
return store;
}
/**
* Sets the scale.
*
*
* @param x
* the X scale
* @param y
@ -1805,7 +1833,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Sets the scale.
*
*
* @param scale
* the scale vector to set
*/
@ -1815,10 +1843,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setTranslation</code> will set the matrix's translation values.
*
*
* @param translation
* the new values for the translation.
* @throws JmeException
* @throws IllegalArgumentException
* if translation is not size 3.
*/
public void setTranslation(float[] translation) {
@ -1833,13 +1861,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setTranslation</code> will set the matrix's translation values.
*
* @param x
* value of the translation on the x axis
* @param y
* value of the translation on the y axis
* @param z
* value of the translation on the z axis
*
* @param x value of the translation on the x axis
* @param y value of the translation on the y axis
* @param z value of the translation on the z axis
*/
public void setTranslation(float x, float y, float z) {
m03 = x;
@ -1862,10 +1887,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setInverseTranslation</code> will set the matrix's inverse
* translation values.
*
*
* @param translation
* the new values for the inverse translation.
* @throws JmeException
* @throws IllegalArgumentException
* if translation is not size 3.
*/
public void setInverseTranslation(float[] translation) {
@ -1883,7 +1908,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* three axes (x, y, z). Where each axis has a specified rotation in
* degrees. These rotations are expressed in a single <code>Vector3f</code>
* object.
*
*
* @param angles
* the angles to rotate.
*/
@ -1919,7 +1944,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setRotationQuaternion</code> builds a rotation from a
* <code>Quaternion</code>.
*
*
* @param quat
* the quaternion to build the rotation from.
* @throws NullPointerException
@ -1932,10 +1957,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setInverseRotationRadians</code> builds an inverted rotation from
* Euler angles that are in radians.
*
*
* @param angles
* the Euler angles in radians.
* @throws JmeException
* @throws IllegalArgumentException
* if angles is not size 3.
*/
public void setInverseRotationRadians(float[] angles) {
@ -1969,10 +1994,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>setInverseRotationDegrees</code> builds an inverted rotation from
* Euler angles that are in degrees.
*
*
* @param angles
* the Euler angles in degrees.
* @throws JmeException
* @throws IllegalArgumentException
* if angles is not size 3.
*/
public void setInverseRotationDegrees(float[] angles) {
@ -1988,13 +2013,12 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix.
*
*
* @param vec
* the Vector3f data to be translated.
* @throws JmeException
* @throws IllegalArgumentException
* if the size of the Vector3f is not 3.
*/
public void inverseTranslateVect(float[] vec) {
@ -2009,13 +2033,12 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix.
*
*
* @param data
* the Vector3f to be translated.
* @throws JmeException
* @throws IllegalArgumentException
* if the size of the Vector3f is not 3.
*/
public void inverseTranslateVect(Vector3f data) {
@ -2025,13 +2048,12 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>inverseTranslateVect</code> translates a given Vector3f by the
* translation part of this matrix.
*
*
* @param data
* the Vector3f to be translated.
* @throws JmeException
* @throws IllegalArgumentException
* if the size of the Vector3f is not 3.
*/
public void translateVect(Vector3f data) {
@ -2041,10 +2063,9 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>inverseRotateVect</code> rotates a given Vector3f by the rotation
* part of this matrix.
*
*
* @param vec
* the Vector3f to be rotated.
*/
@ -2072,7 +2093,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
* 0.0 1.0 0.0 0.0 <br>
* 0.0 0.0 1.0 0.0 <br>
* 0.0 0.0 0.0 1.0 <br>]<br>
*
*
* @return the string representation of this object.
*/
@Override
@ -2118,11 +2139,10 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc.
*
*
* @return the hashcode for this instance of Matrix4f.
* @see java.lang.Object#hashCode()
*/
@ -2161,7 +2181,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof Matrix4f) || o == null) {
if (!(o instanceof Matrix4f)) {
return false;
}
@ -2277,7 +2297,7 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
/**
* Apply a scale to this matrix.
*
*
* @param scale
* the scale to apply
*/

@ -40,7 +40,7 @@ import java.util.logging.Logger;
* This provides methods for calculating a "distance" of a point from this
* plane. The distance is pseudo due to the fact that it can be negative if the
* point is on the non-normal side of the plane.
*
*
* @author Mark Powell
* @author Joshua Slack
* @author Ian McClean
@ -58,12 +58,12 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
Negative
}
/**
/**
* Vector normal to the plane.
*/
protected Vector3f normal = new Vector3f();
/**
/**
* Constant of the plane. See formula in class definition.
*/
protected float constant;
@ -78,7 +78,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/**
* Constructor instantiates a new <code>Plane</code> object. The normal
* and constant values are set at creation.
*
*
* @param normal
* the normal of the plane.
* @param constant
@ -105,7 +105,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/**
* <code>setNormal</code> sets the normal of the plane.
*
*
* @param normal
* the new normal of the plane.
*/
@ -119,14 +119,17 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/**
* <code>setNormal</code> sets the normal of the plane.
*
* @param x the desired X component for the normal vector
* @param y the desired Y component for the normal vector
* @param z the desired Z component for the normal vector
*/
public void setNormal(float x, float y, float z) {
this.normal.set(x,y,z);
this.normal.set(x, y, z);
}
/**
* <code>getNormal</code> retrieves the normal of the plane.
*
*
* @return the normal of the plane.
*/
public Vector3f getNormal() {
@ -136,7 +139,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/**
* <code>setConstant</code> sets the constant value that helps define the
* plane.
*
*
* @param constant
* the new constant value.
*/
@ -146,27 +149,28 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
/**
* <code>getConstant</code> returns the constant of the plane.
*
*
* @return the constant of the plane.
*/
public float getConstant() {
return constant;
}
public Vector3f getClosestPoint(Vector3f point, Vector3f store){
public Vector3f getClosestPoint(Vector3f point, Vector3f store) {
// float t = constant - normal.dot(point);
// return store.set(normal).multLocal(t).addLocal(point);
float t = (constant - normal.dot(point)) / normal.dot(normal);
return store.set(normal).multLocal(t).addLocal(point);
}
public Vector3f getClosestPoint(Vector3f point){
public Vector3f getClosestPoint(Vector3f point) {
return getClosestPoint(point, new Vector3f());
}
public Vector3f reflect(Vector3f point, Vector3f store){
if (store == null)
public Vector3f reflect(Vector3f point, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
float d = pseudoDistance(point);
store.set(normal).negateLocal().multLocal(d * 2f);
@ -179,7 +183,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* a provided point. If the point is on the negative side of the plane the
* distance returned is negative, otherwise it is positive. If the point is
* on the plane, it is zero.
*
*
* @param point
* the point to check.
* @return the signed distance from the plane to a point.
@ -192,7 +196,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* <code>whichSide</code> returns the side at which a point lies on the
* plane. The positive values returned are: NEGATIVE_SIDE, POSITIVE_SIDE and
* NO_SIDE.
*
*
* @param point
* the point to check.
* @return the side at which the point lies.
@ -208,19 +212,19 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
}
}
public boolean isOnPlane(Vector3f point){
public boolean isOnPlane(Vector3f point) {
float dist = pseudoDistance(point);
if (dist < FastMath.FLT_EPSILON && dist > -FastMath.FLT_EPSILON)
if (dist < FastMath.FLT_EPSILON && dist > -FastMath.FLT_EPSILON) {
return true;
else
} else {
return false;
}
}
/**
* Initialize this plane using the three points of the given triangle.
*
* @param t
* the triangle
*
* @param t the triangle
*/
public void setPlanePoints(AbstractTriangle t) {
setPlanePoints(t.get1(), t.get2(), t.get3());
@ -232,14 +236,14 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* @param origin
* @param normal
*/
public void setOriginNormal(Vector3f origin, Vector3f normal){
public void setOriginNormal(Vector3f origin, Vector3f normal) {
this.normal.set(normal);
this.constant = normal.x * origin.x + normal.y * origin.y + normal.z * origin.z;
}
/**
* Initialize the Plane using the given 3 points as coplanar.
*
*
* @param v1
* the first point
* @param v2
@ -260,7 +264,7 @@ public class Plane implements Savable, Cloneable, java.io.Serializable {
* <code>Vector3f</code> object, so the format is the following:
* com.jme.math.Plane [Normal: org.jme.math.Vector3f [X=XX.XXXX, Y=YY.YYYY,
* Z=ZZ.ZZZZ] - Constant: CC.CCCCC]
*
*
* @return the string representation of this plane.
*/
@Override

@ -42,10 +42,9 @@ import java.util.logging.Logger;
* hypercomplex numbers. Quaternions extends a rotation in three dimensions to a
* rotation in four dimensions. This avoids "gimbal lock" and allows for smooth
* continuous rotation.
*
* <code>Quaternion</code> is defined by four floating point numbers: {x y z
* w}.
*
*
* <code>Quaternion</code> is defined by four floating point numbers: {x y z w}.
*
* @author Mark Powell
* @author Joshua Slack
*/
@ -60,7 +59,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
public static final Quaternion IDENTITY = new Quaternion();
public static final Quaternion DIRECTION_Z = new Quaternion();
public static final Quaternion ZERO = new Quaternion(0, 0, 0, 0);
static {
DIRECTION_Z.fromAxes(Vector3f.UNIT_X, Vector3f.UNIT_Y, Vector3f.UNIT_Z);
}
@ -82,14 +81,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* Constructor instantiates a new <code>Quaternion</code> object from the
* given list of parameters.
*
* @param x
* the x value of the quaternion.
* @param y
* the y value of the quaternion.
* @param z
* the z value of the quaternion.
* @param w
* the w value of the quaternion.
* @param x the x value of the quaternion.
* @param y the y value of the quaternion.
* @param z the z value of the quaternion.
* @param w the w value of the quaternion.
*/
public Quaternion(float x, float y, float z, float w) {
this.x = x;
@ -115,17 +110,13 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
* sets the data in a <code>Quaternion</code> object from the given list
* of parameters.
* sets the data in a <code>Quaternion</code> object from the given list of
* parameters.
*
* @param x
* the x value of the quaternion.
* @param y
* the y value of the quaternion.
* @param z
* the z value of the quaternion.
* @param w
* the w value of the quaternion.
* @param x the x value of the quaternion.
* @param y the y value of the quaternion.
* @param z the z value of the quaternion.
* @param w the w value of the quaternion.
* @return this
*/
public Quaternion set(float x, float y, float z, float w) {
@ -141,8 +132,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* passed <code>Quaternion</code> object. The values are copied producing
* a new object.
*
* @param q
* The Quaternion to copy values from.
* @param q The Quaternion to copy values from.
* @return this
*/
public Quaternion set(Quaternion q) {
@ -184,8 +174,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* Constructor instantiates a new <code>Quaternion</code> object from an
* existing quaternion, creating a copy.
*
* @param q
* the quaternion to copy.
* @param q the quaternion to copy.
*/
public Quaternion(Quaternion q) {
this.x = q.x;
@ -195,7 +184,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
* Sets this Quaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1).
* Sets this Quaternion to {0, 0, 0, 1}. Same as calling set(0,0,0,1).
*/
public void loadIdentity() {
x = y = z = 0;
@ -219,6 +208,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
*
* @param angles
* the Euler angles of rotation (in radians).
* @return this
*/
public Quaternion fromAngles(float[] angles) {
if (angles.length != 3) {
@ -231,10 +221,12 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>fromAngles</code> builds a Quaternion from the Euler rotation
* angles (x,y,z) aka (pitch, yaw, roll)). Note that we are applying in order: (y, z, x) aka (yaw, roll, pitch) but
* we've ordered them in x, y, and z for convenience.
* angles (x,y,z) aka (pitch, yaw, roll)).
* Note that we are applying in order: (y, z, x) aka (yaw, roll, pitch)
* but we've ordered them in x, y, and z for convenience.
*
* @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm</a>
*
*
* @param xAngle
* the Euler pitch of rotation (in radians). (aka Attitude, often rot
* around x)
@ -244,6 +236,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* @param zAngle
* the Euler roll of rotation (in radians). (aka Bank, often
* rot around z)
* @return this
*/
public Quaternion fromAngles(float xAngle, float yAngle, float zAngle) {
float angle;
@ -275,10 +268,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>toAngles</code> returns this quaternion converted to Euler rotation
* angles (x,y,z) aka (pitch, yaw, roll).<br/>
* angles (x,y,z) aka (pitch, yaw, roll).<br/>
* Note that the result is not always 100% accurate due to the implications of euler angles.
* @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm</a>
*
*
* @param angles
* the float[] in which the angles should be stored, or null if
* you want a new float[] to be created
@ -307,7 +300,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
angles[2] = -FastMath.HALF_PI;
angles[0] = 0;
} else {
angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw or heading
angles[1] = FastMath.atan2(2 * y * w - 2 * x * z, sqx - sqy - sqz + sqw); // yaw or heading
angles[2] = FastMath.asin(2 * test / unit); // roll or bank
angles[0] = FastMath.atan2(2 * x * w - 2 * y * z, -sqx + sqy - sqz + sqw); // pitch or attitude
}
@ -315,12 +308,12 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
*
* <code>fromRotationMatrix</code> generates a quaternion from a supplied
* matrix. This matrix is assumed to be a rotational matrix.
*
*
* @param matrix
* the matrix that defines the rotation.
* @return this
*/
public Quaternion fromRotationMatrix(Matrix3f matrix) {
return fromRotationMatrix(matrix.m00, matrix.m01, matrix.m02, matrix.m10,
@ -353,7 +346,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
m22 *= lengthSquared;
}
// Use the Graphics Gems code, from
// Use the Graphics Gems code, from
// ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.Z
// *NOT* the "Matrix and Quaternions FAQ", which has errors!
@ -398,7 +391,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>toRotationMatrix</code> converts this quaternion to a rotational
* matrix. Note: the result is created from a normalized version of this quat.
*
*
* @return the rotation matrix representation of this quaternion.
*/
public Matrix3f toRotationMatrix() {
@ -409,7 +402,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>toRotationMatrix</code> converts this quaternion to a rotational
* matrix. The result is stored in result.
*
*
* @param result
* The Matrix3f to store the result in.
* @return the rotation matrix representation of this quaternion.
@ -642,6 +635,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* the angle to rotate (in radians).
* @param axis
* the axis of rotation (already normalized).
* @return this
*/
public Quaternion fromAngleNormalAxis(float angle, Vector3f axis) {
if (axis.x == 0 && axis.y == 0 && axis.z == 0) {
@ -700,6 +694,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* the second quaternion.
* @param t
* the amount to interpolate between the two quaternions.
* @return this
*/
public Quaternion slerp(Quaternion q1, Quaternion q2, float t) {
// Create a local quaternion to store the interpolated quaternion
@ -805,6 +800,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* Sets the values of this quaternion to the nlerp from itself to q2 by blend.
*
* @param q2
* @param blend
*/
@ -829,8 +825,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>add</code> adds the values of this quaternion to those of the
* parameter quaternion. The result is returned as a new quaternion.
*
* @param q
* the quaternion to add to this.
* @param q the quaternion to add to this.
* @return the new quaternion.
*/
public Quaternion add(Quaternion q) {
@ -841,8 +836,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>add</code> adds the values of this quaternion to those of the
* parameter quaternion. The result is stored in this Quaternion.
*
* @param q
* the quaternion to add to this.
* @param q the quaternion to add to this.
* @return This Quaternion after addition.
*/
public Quaternion addLocal(Quaternion q) {
@ -858,8 +852,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* from those of this quaternion. The result is returned as a new
* quaternion.
*
* @param q
* the quaternion to subtract from this.
* @param q the quaternion to subtract from this.
* @return the new quaternion.
*/
public Quaternion subtract(Quaternion q) {
@ -870,8 +863,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>subtract</code> subtracts the values of the parameter quaternion
* from those of this quaternion. The result is stored in this Quaternion.
*
* @param q
* the quaternion to subtract from this.
* @param q the quaternion to subtract from this.
* @return This Quaternion after subtraction.
*/
public Quaternion subtractLocal(Quaternion q) {
@ -903,8 +895,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* It IS safe for q and res to be the same object.
* It IS NOT safe for this and res to be the same object.
*
* @param q
* the quaternion to multiply this quaternion by.
* @param q the quaternion to multiply this quaternion by.
* @param res
* the quaternion to store the result in.
* @return the new quaternion.
@ -950,6 +941,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* @param axis
* the array containing the three vectors representing the
* coordinate system.
* @return this
*/
public Quaternion fromAxes(Vector3f[] axis) {
if (axis.length != 3) {
@ -970,6 +962,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* @param xAxis vector representing the x-axis of the coordinate system.
* @param yAxis vector representing the y-axis of the coordinate system.
* @param zAxis vector representing the z-axis of the coordinate system.
* @return this
*/
public Quaternion fromAxes(Vector3f xAxis, Vector3f yAxis, Vector3f zAxis) {
return fromRotationMatrix(xAxis.x, yAxis.x, zAxis.x, xAxis.y, yAxis.y,
@ -982,8 +975,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* corresponds to an axis of the coordinate system defined by the quaternion
* rotation.
*
* @param axis
* the array of vectors to be filled.
* @param axis the array of vectors to be filled.
*/
public void toAxes(Vector3f axis[]) {
Matrix3f tempMat = toRotationMatrix();
@ -996,8 +988,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is returned as a new vector.
*
* @param v
* the vector to multiply this quaternion by.
* @param v the vector to multiply this quaternion by.
* @return the new vector.
*/
public Vector3f mult(Vector3f v) {
@ -1008,8 +999,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is stored in the supplied vector
*
* @param v
* the vector to multiply this quaternion by.
* @param v the vector to multiply this quaternion by.
* @return v
*/
public Vector3f multLocal(Vector3f v) {
@ -1031,8 +1021,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* stored in this Quaternion, which is also returned for chaining. Similar
* to this *= q.
*
* @param q
* The Quaternion to multiply this one by.
* @param q The Quaternion to multiply this one by.
* @return This Quaternion, after multiplication.
*/
public Quaternion multLocal(Quaternion q) {
@ -1051,14 +1040,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* stored in this Quaternion, which is also returned for chaining. Similar
* to this *= q.
*
* @param qx -
* quat x value
* @param qy -
* quat y value
* @param qz -
* quat z value
* @param qw -
* quat w value
* @param qx quat x value
* @param qy quat y value
* @param qz quat z value
* @param qw quat w value
*
* @return This Quaternion, after multiplication.
*/
@ -1076,7 +1061,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>mult</code> multiplies this quaternion by a parameter vector. The
* result is returned as a new vector.
*
*
* @param v
* the vector to multiply this quaternion by.
* @param store
@ -1172,6 +1157,8 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
/**
* <code>normalize</code> normalizes the current <code>Quaternion</code>.
* The result is stored internally.
*
* @return this
*/
public Quaternion normalizeLocal() {
float n = FastMath.invSqrt(norm());
@ -1221,8 +1208,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
* <code>negate</code> inverts the values of the quaternion.
*
* Flip the signs of all components of this Quaternion.
*/
public void negate() {
x *= -1;
@ -1232,11 +1218,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
* <code>toString</code> returns a string representation of this
* <code>Quaternion</code>. The format is:
*
* <code>toString</code> creates the string representation of this
* <code>Quaternion</code>. The values of the quaternion are displaced (x,
* y, z, w), in the following manner: <br>
* (x, y, z, w)
* (X.XXXX, Y.YYYY, Z.ZZZZ, W.WWWW)
*
* @return the string representation of this object.
* @see java.lang.Object#toString()
@ -1279,10 +1264,14 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
return true;
}
/**
* Returns true if this quaternion is similar to the specified quaternion
* within some value of epsilon.
*
* @param other the Quaternion to compare with (not null, unaffected)
* @param epsilon the error tolerance for each component
* @return true if all 4 components are within tolerance, otherwise false
*/
public boolean isSimilar(Quaternion other, float epsilon) {
if (other == null) {
@ -1304,11 +1293,10 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
}
/**
*
* <code>hashCode</code> returns the hash code value as an integer and is
* supported for the benefit of hashing based collection classes such as
* Hashtable, HashMap, HashSet etc.
*
*
* @return the hashcode for this instance of Quaternion.
* @see java.lang.Object#hashCode()
*/
@ -1327,7 +1315,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>readExternal</code> builds a quaternion from an
* <code>ObjectInput</code> object. <br>
* NOTE: Used with serialization. Not to be called manually.
*
*
* @param in
* the ObjectInput value to read from.
* @throws IOException
@ -1345,7 +1333,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* <code>writeExternal</code> writes this quaternion out to a
* <code>ObjectOutput</code> object. NOTE: Used with serialization. Not to
* be called manually.
*
*
* @param out
* the object to write to.
* @throws IOException
@ -1370,6 +1358,7 @@ public final class Quaternion implements Savable, Cloneable, java.io.Serializabl
* @param up
* a vector indicating the local up direction.
* (typically {0, 1, 0} in jME.)
* @return this
*/
public Quaternion lookAt(Vector3f direction, Vector3f up) {
TempVars vars = TempVars.get();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -49,11 +49,11 @@ public class Spline implements Savable {
Bezier,
Nurb
}
private List<Vector3f> controlPoints = new ArrayList<Vector3f>();
private List<Float> knots; //knots of NURBS spline
private float[] weights; //weights of NURBS spline
private int basisFunctionDegree; //degree of NURBS spline basis function (computed automatically)
private List<Float> knots; //knots of NURBS spline
private float[] weights; //weights of NURBS spline
private int basisFunctionDegree; //degree of NURBS spline basis function (computed automatically)
private boolean cycle;
private List<Float> segmentsLength;
private float totalLength;
@ -66,6 +66,7 @@ public class Spline implements Savable {
/**
* Create a spline
*
* @param splineType the type of the spline @see {SplineType}
* @param controlPoints an array of vector to use as control points of the spline
* If the type of the curve is Bezier curve the control points should be provided
@ -74,15 +75,15 @@ public class Spline implements Savable {
* for the border points of the curve, who should have only one handle point.
* The pattern should be as follows:
* P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn
*
*
* n is the amount of 'P' - points.
* @param curveTension the tension of the spline
* @param cycle true if the spline cycle.
*/
public Spline(SplineType splineType, Vector3f[] controlPoints, float curveTension, boolean cycle) {
if(splineType==SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
}
if (splineType == SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
}
for (int i = 0; i < controlPoints.length; i++) {
Vector3f vector3f = controlPoints[i];
this.controlPoints.add(vector3f);
@ -95,6 +96,7 @@ public class Spline implements Savable {
/**
* Create a spline
*
* @param splineType the type of the spline @see {SplineType}
* @param controlPoints a list of vector to use as control points of the spline
* If the type of the curve is Bezier curve the control points should be provided
@ -103,45 +105,46 @@ public class Spline implements Savable {
* for the border points of the curve, who should have only one handle point.
* The pattern should be as follows:
* P0 - H0 : H1 - P1 - H1 : ... : Hn - Pn
*
*
* n is the amount of 'P' - points.
* @param curveTension the tension of the spline
* @param cycle true if the spline cycle.
*/
public Spline(SplineType splineType, List<Vector3f> controlPoints, float curveTension, boolean cycle) {
if(splineType==SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
}
if (splineType == SplineType.Nurb) {
throw new IllegalArgumentException("To create NURBS spline use: 'public Spline(Vector3f[] controlPoints, float[] weights, float[] nurbKnots)' constructor!");
}
type = splineType;
this.controlPoints.addAll(controlPoints);
this.curveTension = curveTension;
this.cycle = cycle;
this.computeTotalLength();
}
/**
* Create a NURBS spline. A spline type is automatically set to SplineType.Nurb.
* The cycle is set to <b>false</b> by default.
*
* @param controlPoints a list of vector to use as control points of the spline
* @param nurbKnots the nurb's spline knots
* @param nurbKnots the nurb's spline knots
*/
public Spline(List<Vector4f> controlPoints, List<Float> nurbKnots) {
//input data control
for(int i=0;i<nurbKnots.size()-1;++i) {
if(nurbKnots.get(i)>nurbKnots.get(i+1)) {
throw new IllegalArgumentException("The knots values cannot decrease!");
}
}
//storing the data
//input data control
for (int i = 0; i < nurbKnots.size() - 1; ++i) {
if (nurbKnots.get(i) > nurbKnots.get(i + 1)) {
throw new IllegalArgumentException("The knots values cannot decrease!");
}
}
//storing the data
type = SplineType.Nurb;
this.weights = new float[controlPoints.size()];
this.knots = nurbKnots;
this.basisFunctionDegree = nurbKnots.size() - weights.length;
for(int i=0;i<controlPoints.size();++i) {
Vector4f controlPoint = controlPoints.get(i);
this.controlPoints.add(new Vector3f(controlPoint.x, controlPoint.y, controlPoint.z));
this.weights[i] = controlPoint.w;
for (int i = 0; i < controlPoints.size(); ++i) {
Vector4f controlPoint = controlPoints.get(i);
this.controlPoints.add(new Vector3f(controlPoint.x, controlPoint.y, controlPoint.z));
this.weights[i] = controlPoint.w;
}
CurveAndSurfaceMath.prepareNurbsKnots(knots, basisFunctionDegree);
this.computeTotalLength();
@ -175,6 +178,7 @@ public class Spline implements Savable {
/**
* Adds a controlPoint to the spline
*
* @param controlPoint a position in world space
*/
public void addControlPoint(Vector3f controlPoint) {
@ -192,6 +196,7 @@ public class Spline implements Savable {
/**
* remove the controlPoint from the spline
*
* @param controlPoint the controlPoint to remove
*/
public void removeControlPoint(Vector3f controlPoint) {
@ -200,8 +205,8 @@ public class Spline implements Savable {
this.computeTotalLength();
}
}
public void clearControlPoints(){
public void clearControlPoints() {
controlPoints.clear();
totalLength = 0;
}
@ -225,10 +230,10 @@ public class Spline implements Savable {
totalLength += l;
}
}
} else if(type == SplineType.Bezier) {
this.computeBezierLength();
} else if(type == SplineType.Nurb) {
this.computeNurbLength();
} else if (type == SplineType.Bezier) {
this.computeBezierLength();
} else if (type == SplineType.Nurb) {
this.computeNurbLength();
} else {
this.initCatmullRomWayPoints(controlPoints);
this.computeCatmulLength();
@ -249,34 +254,37 @@ public class Spline implements Savable {
}
}
}
/**
* This method calculates the Bezier curve length.
*/
private void computeBezierLength() {
float l = 0;
float l = 0;
if (controlPoints.size() > 1) {
for (int i = 0; i < controlPoints.size() - 1; i+=3) {
for (int i = 0; i < controlPoints.size() - 1; i += 3) {
l = FastMath.getBezierP1toP2Length(controlPoints.get(i),
controlPoints.get(i + 1), controlPoints.get(i + 2), controlPoints.get(i + 3));
controlPoints.get(i + 1), controlPoints.get(i + 2), controlPoints.get(i + 3));
segmentsLength.add(l);
totalLength += l;
}
}
}
/**
* This method calculates the NURB curve length.
*/
private void computeNurbLength() {
//TODO: implement
//TODO: implement
}
/**
* Interpolate a position on the spline
* @param value a value from 0 to 1 that represent the position between the current control point and the next one
*
* @param value a value from 0 to 1 that represent the position between the
* current control point and the next one
* @param currentControlPoint the current control point
* @param store a vector to store the result (use null to create a new one that will be returned by the method)
* @param store a vector to store the result (use null to create a new one
* that will be returned by the method)
* @return the position
*/
public Vector3f interpolate(float value, int currentControlPoint, Vector3f store) {
@ -291,11 +299,11 @@ public class Spline implements Savable {
FastMath.interpolateLinear(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), store);
break;
case Bezier:
FastMath.interpolateBezier(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), controlPoints.get(currentControlPoint + 2), controlPoints.get(currentControlPoint + 3), store);
break;
FastMath.interpolateBezier(value, controlPoints.get(currentControlPoint), controlPoints.get(currentControlPoint + 1), controlPoints.get(currentControlPoint + 2), controlPoints.get(currentControlPoint + 3), store);
break;
case Nurb:
CurveAndSurfaceMath.interpolateNurbs(value, this, store);
break;
CurveAndSurfaceMath.interpolateNurbs(value, this, store);
break;
default:
break;
}
@ -304,6 +312,8 @@ public class Spline implements Savable {
/**
* returns the curve tension
*
* @return the value of the tension parameter
*/
public float getCurveTension() {
return curveTension;
@ -316,13 +326,13 @@ public class Spline implements Savable {
*/
public void setCurveTension(float curveTension) {
this.curveTension = curveTension;
if(type==SplineType.CatmullRom && !getControlPoints().isEmpty()) {
this.computeTotalLength();
if (type == SplineType.CatmullRom && !getControlPoints().isEmpty()) {
this.computeTotalLength();
}
}
/**
* returns true if the spline cycle
* @return true if the spline cycles
*/
public boolean isCycle() {
return cycle;
@ -330,27 +340,28 @@ public class Spline implements Savable {
/**
* set to true to make the spline cycle
*
* @param cycle
*/
public void setCycle(boolean cycle) {
if(type!=SplineType.Nurb) {
if (controlPoints.size() >= 2) {
if (this.cycle && !cycle) {
controlPoints.remove(controlPoints.size() - 1);
}
if (!this.cycle && cycle) {
controlPoints.add(controlPoints.get(0));
}
this.cycle = cycle;
this.computeTotalLength();
} else {
this.cycle = cycle;
}
}
if (type != SplineType.Nurb) {
if (controlPoints.size() >= 2) {
if (this.cycle && !cycle) {
controlPoints.remove(controlPoints.size() - 1);
}
if (!this.cycle && cycle) {
controlPoints.add(controlPoints.get(0));
}
this.cycle = cycle;
this.computeTotalLength();
} else {
this.cycle = cycle;
}
}
}
/**
* return the total length of the spline
* @return the total length of the spline
*/
public float getTotalLength() {
return totalLength;
@ -358,6 +369,8 @@ public class Spline implements Savable {
/**
* return the type of the spline
*
* @return the enum value
*/
public SplineType getType() {
return type;
@ -365,6 +378,7 @@ public class Spline implements Savable {
/**
* Sets the type of the spline
*
* @param type
*/
public void setType(SplineType type) {
@ -374,6 +388,8 @@ public class Spline implements Savable {
/**
* returns this spline control points
*
* @return the pre-existing list
*/
public List<Vector3f> getControlPoints() {
return controlPoints;
@ -381,61 +397,69 @@ public class Spline implements Savable {
/**
* returns a list of float representing the segments length
*
* @return the pre-existing list
*/
public List<Float> getSegmentsLength() {
return segmentsLength;
}
//////////// NURBS getters /////////////////////
/**
* This method returns the minimum nurb curve knot value. Check the nurb type before calling this method. It the curve is not of a Nurb
* type - NPE will be thrown.
* @return the minimum nurb curve knot value
*/
/**
* This method returns the minimum nurb curve knot value. Check the nurb
* type before calling this method. It the curve is not of a Nurb type - NPE
* will be thrown.
*
* @return the minimum nurb curve knot value
*/
public float getMinNurbKnot() {
return knots.get(basisFunctionDegree - 1);
return knots.get(basisFunctionDegree - 1);
}
/**
* This method returns the maximum nurb curve knot value. Check the nurb type before calling this method. It the curve is not of a Nurb
* type - NPE will be thrown.
* @return the maximum nurb curve knot value
*/
* This method returns the maximum nurb curve knot value. Check the nurb
* type before calling this method. It the curve is not of a Nurb type - NPE
* will be thrown.
*
* @return the maximum nurb curve knot value
*/
public float getMaxNurbKnot() {
return knots.get(weights.length);
return knots.get(weights.length);
}
/**
* This method returns NURBS' spline knots.
*
* @return NURBS' spline knots
*/
public List<Float> getKnots() {
return knots;
}
return knots;
}
/**
* This method returns NURBS' spline weights.
*
* @return NURBS' spline weights
*/
public float[] getWeights() {
return weights;
}
return weights;
}
/**
* This method returns NURBS' spline basis function degree.
*
* @return NURBS' spline basis function degree
*/
public int getBasisFunctionDegree() {
return basisFunctionDegree;
}
return basisFunctionDegree;
}
@Override
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this);
oc.writeSavableArrayList((ArrayList) controlPoints, "controlPoints", null);
oc.write(type, "type", SplineType.CatmullRom);
float list[] = null;
if (segmentsLength != null) {
list = new float[segmentsLength.size()];
@ -449,7 +473,7 @@ public class Spline implements Savable {
oc.writeSavableArrayList((ArrayList) CRcontrolPoints, "CRControlPoints", null);
oc.write(curveTension, "curveTension", 0.5f);
oc.write(cycle, "cycle", false);
oc.writeSavableArrayList((ArrayList<Float>)knots, "knots", null);
oc.writeSavableArrayList((ArrayList<Float>) knots, "knots", null);
oc.write(weights, "weights", null);
oc.write(basisFunctionDegree, "basisFunctionDegree", 0);
}
@ -458,7 +482,8 @@ public class Spline implements Savable {
public void read(JmeImporter im) throws IOException {
InputCapsule in = im.getCapsule(this);
controlPoints = (ArrayList<Vector3f>) in.readSavableArrayList("controlPoints", new ArrayList<Vector3f>()); /* Empty List as default, prevents null pointers */
controlPoints = in.readSavableArrayList("controlPoints", new ArrayList<>());
/* Empty List as default, prevents null pointers */
float list[] = in.readFloatArray("segmentsLength", null);
if (list != null) {
segmentsLength = new ArrayList<Float>();
@ -468,7 +493,7 @@ public class Spline implements Savable {
}
type = in.readEnum("pathSplineType", SplineType.class, SplineType.CatmullRom);
totalLength = in.readFloat("totalLength", 0);
CRcontrolPoints = (ArrayList<Vector3f>) in.readSavableArrayList("CRControlPoints", null);
CRcontrolPoints = in.readSavableArrayList("CRControlPoints", null);
curveTension = in.readFloat("curveTension", 0.5f);
cycle = in.readBoolean("cycle", false);
knots = in.readSavableArrayList("knots", null);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,7 +39,7 @@ import java.io.IOException;
/**
* Started Date: Jul 16, 2004<br><br>
* Represents a translation, rotation and scale in one object.
*
*
* @author Jack Lindamood
* @author Joshua Slack
*/
@ -53,31 +53,32 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
private Vector3f translation = new Vector3f();
private Vector3f scale = new Vector3f(1, 1, 1);
public Transform(Vector3f translation, Quaternion rot){
public Transform(Vector3f translation, Quaternion rot) {
this.translation.set(translation);
this.rot.set(rot);
}
public Transform(Vector3f translation, Quaternion rot, Vector3f scale){
public Transform(Vector3f translation, Quaternion rot, Vector3f scale) {
this(translation, rot);
this.scale.set(scale);
}
public Transform(Vector3f translation){
public Transform(Vector3f translation) {
this(translation, Quaternion.IDENTITY);
}
public Transform(Quaternion rot){
public Transform(Quaternion rot) {
this(Vector3f.ZERO, rot);
}
public Transform(){
public Transform() {
this(Vector3f.ZERO, Quaternion.IDENTITY);
}
/**
* Sets this rotation to the given Quaternion value.
* @param rot The new rotation for this matrix.
*
* @param rot The new rotation for this Transform.
* @return this
*/
public Transform setRotation(Quaternion rot) {
@ -87,7 +88,8 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/**
* Sets this translation to the given value.
* @param trans The new translation for this matrix.
*
* @param trans The new translation for this Transform.
* @return this
*/
public Transform setTranslation(Vector3f trans) {
@ -96,7 +98,8 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
}
/**
* Return the translation vector in this matrix.
* Return the translation vector in this Transform.
*
* @return translation vector.
*/
public Vector3f getTranslation() {
@ -105,7 +108,8 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/**
* Sets this scale to the given value.
* @param scale The new scale for this matrix.
*
* @param scale The new scale for this Transform.
* @return this
*/
public Transform setScale(Vector3f scale) {
@ -115,7 +119,8 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
/**
* Sets this scale to the given value.
* @param scale The new scale for this matrix.
*
* @param scale The new scale for this Transform.
* @return this
*/
public Transform setScale(float scale) {
@ -124,7 +129,8 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
}
/**
* Return the scale vector in this matrix.
* Return the scale vector in this Transform.
*
* @return scale vector.
*/
public Vector3f getScale() {
@ -132,66 +138,84 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
}
/**
* Stores this translation value into the given vector3f. If trans is null, a new vector3f is created to
* hold the value. The value, once stored, is returned.
* @param trans The store location for this matrix's translation.
* @return The value of this matrix's translation.
* Stores this translation value into the given vector3f. If trans is null,
* a new vector3f is created to hold the value. The value, once stored, is
* returned.
*
* @param trans The store location for this transform's translation.
* @return The value of this transform's translation.
*/
public Vector3f getTranslation(Vector3f trans) {
if (trans==null) trans=new Vector3f();
if (trans == null) {
trans = new Vector3f();
}
trans.set(this.translation);
return trans;
}
/**
* Stores this rotation value into the given Quaternion. If quat is null, a new Quaternion is created to
* hold the value. The value, once stored, is returned.
* @param quat The store location for this matrix's rotation.
* @return The value of this matrix's rotation.
* Stores this rotation value into the given Quaternion. If quat is null, a
* new Quaternion is created to hold the value. The value, once stored, is
* returned.
*
* @param quat The store location for this transform's rotation.
* @return The value of this transform's rotation.
*/
public Quaternion getRotation(Quaternion quat) {
if (quat==null) quat=new Quaternion();
if (quat == null) {
quat = new Quaternion();
}
quat.set(rot);
return quat;
}
/**
* Return the rotation quaternion in this matrix.
* Return the rotation quaternion in this Transform.
*
* @return rotation quaternion.
*/
public Quaternion getRotation() {
return rot;
}
}
/**
* Stores this scale value into the given vector3f. If scale is null, a new vector3f is created to
* hold the value. The value, once stored, is returned.
* @param scale The store location for this matrix's scale.
* @return The value of this matrix's scale.
* Stores this scale value into the given vector3f. If scale is null, a new
* vector3f is created to hold the value. The value, once stored, is
* returned.
*
* @param scale The store location for this transform's scale.
* @return The value of this transform's scale.
*/
public Vector3f getScale(Vector3f scale) {
if (scale==null) scale=new Vector3f();
if (scale == null) {
scale = new Vector3f();
}
scale.set(this.scale);
return scale;
}
/**
* Sets this transform to the interpolation between the first transform and the second by delta amount.
* Sets this transform to the interpolation between the first transform and
* the second by delta amount.
*
* @param t1 The beginning transform.
* @param t2 The ending transform.
* @param delta An amount between 0 and 1 representing how far to interpolate from t1 to t2.
* @param delta An amount between 0 and 1 representing how far to
* interpolate from t1 to t2.
*/
public void interpolateTransforms(Transform t1, Transform t2, float delta) {
t1.rot.nlerp(t2.rot, delta);
this.rot.set(t1.rot);
this.translation.interpolateLocal(t1.translation,t2.translation,delta);
this.scale.interpolateLocal(t1.scale,t2.scale,delta);
this.translation.interpolateLocal(t1.translation, t2.translation, delta);
this.scale.interpolateLocal(t1.scale, t2.scale, delta);
}
/**
* Changes the values of this matrix according to its parent. Very similar to the concept of Node/Spatial transforms.
* @param parent The parent matrix.
* @return This matrix, after combining.
* Changes the values of this Transform according to its parent. Very similar
* to the concept of Node/Spatial transforms.
*
* @param parent The parent Transform.
* @return This Transform, after combining.
*/
public Transform combineWithParent(Transform parent) {
//applying parent scale to local scale
@ -202,56 +226,58 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
translation.multLocal(parent.scale);
//applying parent rotation to local translation, then applying parent translation to local translation.
//Note that parent.rot.multLocal(translation) doesn't modify "parent.rot" but "translation"
parent
.rot
.multLocal(translation)
.addLocal(parent.translation);
parent.rot
.multLocal(translation)
.addLocal(parent.translation);
return this;
}
/**
* Sets this matrix's translation to the given x,y,z values.
* @param x This matrix's new x translation.
* @param y This matrix's new y translation.
* @param z This matrix's new z translation.
* Sets this transform's translation to the given x,y,z values.
*
* @param x This transform's new x translation.
* @param y This transform's new y translation.
* @param z This transform's new z translation.
* @return this
*/
public Transform setTranslation(float x,float y, float z) {
translation.set(x,y,z);
public Transform setTranslation(float x, float y, float z) {
translation.set(x, y, z);
return this;
}
/**
* Sets this matrix's scale to the given x,y,z values.
* @param x This matrix's new x scale.
* @param y This matrix's new y scale.
* @param z This matrix's new z scale.
* Sets this transform's scale to the given x,y,z values.
*
* @param x This transform's new x scale.
* @param y This transform's new y scale.
* @param z This transform's new z scale.
* @return this
*/
public Transform setScale(float x, float y, float z) {
scale.set(x,y,z);
scale.set(x, y, z);
return this;
}
public Vector3f transformVector(final Vector3f in, Vector3f store){
if (store == null)
public Vector3f transformVector(final Vector3f in, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
// multiply with scale first, then rotate, finally translate (cf.
// Eberly)
return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);
}
public Vector3f transformInverseVector(final Vector3f in, Vector3f store){
if (store == null)
public Vector3f transformInverseVector(final Vector3f in, Vector3f store) {
if (store == null) {
store = new Vector3f();
}
// The author of this code should look above and take the inverse of that
// But for some reason, they didn't ..
// in.subtract(translation, store).divideLocal(scale);
// rot.inverse().mult(store, store);
in.subtract(translation, store);
rot.inverse().mult(store, store);
store.divideLocal(scale);
@ -272,7 +298,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
store.setScale(scale);
return store;
}
public void fromTransformMatrix(Matrix4f mat) {
TempVars vars = TempVars.get();
translation.set(mat.toTranslationVector(vars.vect1));
@ -280,13 +306,13 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
scale.set(mat.toScaleVector(vars.vect2));
vars.release();
}
public Transform invert() {
Transform t = new Transform();
t.fromTransformMatrix(toTransformMatrix().invertLocal());
return t;
}
/**
* Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1.
*/
@ -331,15 +357,17 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
}
@Override
public String toString(){
return getClass().getSimpleName() + "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n"
+ "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n"
+ "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]";
public String toString() {
return getClass().getSimpleName()
+ "[ " + translation.x + ", " + translation.y + ", " + translation.z + "]\n"
+ "[ " + rot.x + ", " + rot.y + ", " + rot.z + ", " + rot.w + "]\n"
+ "[ " + scale.x + " , " + scale.y + ", " + scale.z + "]";
}
/**
* Sets this matrix to be equal to the given matrix.
* @param matrixQuat The matrix to be equal to.
* Sets this Transform to be equal to the given Transform.
*
* @param matrixQuat The Transform to be equal to.
* @return this
*/
public Transform set(Transform matrixQuat) {
@ -360,12 +388,12 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable
@Override
public void read(JmeImporter e) throws IOException {
InputCapsule capsule = e.getCapsule(this);
rot.set((Quaternion)capsule.readSavable("rot", Quaternion.IDENTITY));
translation.set((Vector3f)capsule.readSavable("translation", Vector3f.ZERO));
scale.set((Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ));
rot.set((Quaternion) capsule.readSavable("rot", Quaternion.IDENTITY));
translation.set((Vector3f) capsule.readSavable("translation", Vector3f.ZERO));
scale.set((Vector3f) capsule.readSavable("scale", Vector3f.UNIT_XYZ));
}
@Override
public Transform clone() {
try {

@ -235,6 +235,7 @@ public final class Vector2f implements Savable, Cloneable, java.io.Serializable
* @param changeAmnt
* An amount between 0.0 - 1.0 representing a percentage change
* from this towards finalVec
* @return this
*/
public Vector2f interpolateLocal(Vector2f finalVec, float changeAmnt) {
this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x;
@ -253,6 +254,7 @@ public final class Vector2f implements Savable, Cloneable, java.io.Serializable
* @param changeAmnt
* An amount between 0.0 - 1.0 representing a percentage change
* from beginVec towards finalVec
* @return this
*/
public Vector2f interpolateLocal(Vector2f beginVec, Vector2f finalVec,
float changeAmnt) {
@ -622,6 +624,8 @@ public final class Vector2f implements Savable, Cloneable, java.io.Serializable
/**
* <code>zero</code> resets this vector's data to zero internally.
*
* @return this
*/
public Vector2f zero() {
x = y = 0;
@ -696,6 +700,10 @@ public final class Vector2f implements Savable, Cloneable, java.io.Serializable
/**
* Returns true if this vector is similar to the specified vector within
* some value of epsilon.
*
* @param other the vector to compare with (not null, unaffected)
* @param epsilon the desired error tolerance for each component
* @return true if both components are within tolerance, otherwise false
*/
public boolean isSimilar(Vector2f other, float epsilon) {
if (other == null) {

@ -29,7 +29,6 @@
* 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.math;
import com.jme3.export.*;
@ -52,7 +51,6 @@ import java.util.logging.Logger;
public final class Vector3f implements Savable, Cloneable, java.io.Serializable {
static final long serialVersionUID = 1;
private static final Logger logger = Logger.getLogger(Vector3f.class.getName());
public final static Vector3f ZERO = new Vector3f(0, 0, 0);
@ -69,18 +67,14 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY,
Float.NEGATIVE_INFINITY);
/**
/**
* the x value of the vector.
*/
public float x;
/**
* the y value of the vector.
*/
public float y;
/**
* the z value of the vector.
*/
@ -156,7 +150,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>add</code> adds a provided vector to this vector creating a
* resultant vector which is returned. If the provided vector is null, null
* is returned.
@ -174,7 +167,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>add</code> adds the values of a provided vector storing the
* values in the supplied vector.
*
@ -212,7 +204,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>add</code> adds the provided values to this vector, creating a
* new vector that is then returned.
*
@ -249,7 +240,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>scaleAdd</code> multiplies this vector by a scalar then adds the
* given Vector3f.
*
@ -257,6 +247,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* the value to multiply this vector by.
* @param add
* the value to add
* @return this
*/
public Vector3f scaleAdd(float scalar, Vector3f add) {
x = x * scalar + add.x;
@ -266,7 +257,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>scaleAdd</code> multiplies the given vector by a scalar then adds
* the given vector.
*
@ -276,6 +266,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* the value to multiply the scalar by
* @param add
* the value to add
* @return this
*/
public Vector3f scaleAdd(float scalar, Vector3f mult, Vector3f add) {
this.x = mult.x * scalar + add.x;
@ -285,7 +276,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>dot</code> calculates the dot product of this vector with a
* provided vector. If the provided vector is null, 0 is returned.
*
@ -323,7 +313,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* the vector to store the cross product result.
* @return result, after receiving the cross product vector.
*/
public Vector3f cross(Vector3f v,Vector3f result) {
public Vector3f cross(Vector3f v, Vector3f result) {
return cross(v.x, v.y, v.z, result);
}
@ -342,8 +332,10 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return result, after receiving the cross product vector.
*/
public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result) {
if (result == null) result = new Vector3f();
float resX = ((y * otherZ) - (z * otherY));
if (result == null) {
result = new Vector3f();
}
float resX = ((y * otherZ) - (z * otherY));
float resY = ((z * otherX) - (x * otherZ));
float resZ = ((x * otherY) - (y * otherX));
result.set(resX, resY, resZ);
@ -375,8 +367,8 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return this.
*/
public Vector3f crossLocal(float otherX, float otherY, float otherZ) {
float tempx = ( y * otherZ ) - ( z * otherY );
float tempy = ( z * otherX ) - ( x * otherZ );
float tempx = (y * otherZ) - (z * otherY);
float tempy = (z * otherX) - (x * otherZ);
z = (x * otherY) - (y * otherX);
x = tempx;
y = tempy;
@ -389,10 +381,10 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @param other The vector to project this vector onto
* @return A new vector with the projection result
*/
public Vector3f project(Vector3f other){
public Vector3f project(Vector3f other) {
float n = this.dot(other); // A . B
float d = other.lengthSquared(); // |B|^2
return new Vector3f(other).multLocal(n/d);
return new Vector3f(other).multLocal(n / d);
}
/**
@ -402,20 +394,20 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @param other The vector to project this vector onto
* @return This Vector3f, set to the projection result
*/
public Vector3f projectLocal(Vector3f other){
public Vector3f projectLocal(Vector3f other) {
float n = this.dot(other); // A . B
float d = other.lengthSquared(); // |B|^2
return set(other).multLocal(n/d);
return set(other).multLocal(n / d);
}
/**
* Returns true if this vector is a unit vector (length() ~= 1),
* returns false otherwise.
*
*
* @return true if this vector is a unit vector (length() ~= 1),
* or false otherwise.
*/
public boolean isUnitVector(){
public boolean isUnitVector() {
float len = length();
return 0.99f < len && len < 1.01f;
}
@ -465,7 +457,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>mult</code> multiplies this vector by a scalar. The resultant
* vector is returned.
*
@ -478,7 +469,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>mult</code> multiplies this vector by a scalar. The resultant
* vector is supplied as the second parameter and returned.
*
@ -581,11 +571,12 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
logger.warning("Provided vector is null, null returned.");
return null;
}
if (store == null) store = new Vector3f();
if (store == null) {
store = new Vector3f();
}
return store.set(x * vec.x, y * vec.y, z * vec.z);
}
/**
* <code>divide</code> divides the values of this vector by a scalar and
* returns the result. The values of this vector remain untouched.
@ -595,7 +586,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return the result <code>Vector</code>.
*/
public Vector3f divide(float scalar) {
scalar = 1f/scalar;
scalar = 1f / scalar;
return new Vector3f(x * scalar, y * scalar, z * scalar);
}
@ -609,14 +600,13 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return this
*/
public Vector3f divideLocal(float scalar) {
scalar = 1f/scalar;
scalar = 1f / scalar;
x *= scalar;
y *= scalar;
z *= scalar;
return this;
}
/**
* <code>divide</code> divides the values of this vector by a scalar and
* returns the result. The values of this vector remain untouched.
@ -646,7 +636,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>negate</code> returns the negative of this vector. All values are
* negated and set to a new vector.
*
@ -657,7 +646,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>negateLocal</code> negates the internal values of this vector.
*
* @return this.
@ -670,7 +658,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>subtract</code> subtracts the values of a given vector from those
* of this vector creating a new vector object. If the provided vector is
* null, null is returned.
@ -704,7 +691,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>subtract</code>
*
* @param vec
@ -714,7 +700,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return result
*/
public Vector3f subtract(Vector3f vec, Vector3f result) {
if(result == null) {
if (result == null) {
result = new Vector3f();
}
result.x = x - vec.x;
@ -724,7 +710,6 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
*
* <code>subtract</code> subtracts the provided values from this vector,
* creating a new vector that is then returned.
*
@ -773,7 +758,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
//
// return divide(1);
float length = x * x + y * y + z * z;
if (length != 1f && length != 0f){
if (length != 1f && length != 0f) {
length = 1.0f / FastMath.sqrt(length);
return new Vector3f(x * length, y * length, z * length);
}
@ -791,7 +776,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
// than the old jme normalize as this method
// is commonly used.
float length = x * x + y * y + z * z;
if (length != 1f && length != 0f){
if (length != 1f && length != 0f) {
length = 1.0f / FastMath.sqrt(length);
x *= length;
y *= length;
@ -801,12 +786,14 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
/**
* <code>maxLocal</code> computes the maximum value for each
* <code>maxLocal</code> computes the maximum value for each
* component in this and <code>other</code> vector. The result is stored
* in this vector.
* @param other
*
* @param other
* @return this
*/
public Vector3f maxLocal(Vector3f other){
public Vector3f maxLocal(Vector3f other) {
x = other.x > x ? other.x : x;
y = other.y > y ? other.y : y;
z = other.z > z ? other.z : z;
@ -817,9 +804,11 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* <code>minLocal</code> computes the minimum value for each
* component in this and <code>other</code> vector. The result is stored
* in this vector.
*
* @param other
* @return this
*/
public Vector3f minLocal(Vector3f other){
public Vector3f minLocal(Vector3f other) {
x = other.x < x ? other.x : x;
y = other.y < y ? other.y : y;
z = other.z < z ? other.z : z;
@ -828,6 +817,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>zero</code> resets this vector's data to zero internally.
* @return this
*/
public Vector3f zero() {
x = y = z = 0;
@ -837,7 +827,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
/**
* <code>angleBetween</code> returns (in radians) the angle between two vectors.
* It is assumed that both this vector and the given vector are unit vectors (iow, normalized).
*
*
* @param otherVector a unit vector to find the angle against
* @return the angle in radians.
*/
@ -846,51 +836,62 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
float angle = FastMath.acos(dotProduct);
return angle;
}
/**
* Sets this vector to the interpolation by changeAmnt from this to the finalVec
* this=(1-changeAmnt)*this + changeAmnt * finalVec
*
* @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from this towards finalVec
* @return this
*/
public Vector3f interpolateLocal(Vector3f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*this.x + changeAmnt*finalVec.x;
this.y=(1-changeAmnt)*this.y + changeAmnt*finalVec.y;
this.z=(1-changeAmnt)*this.z + changeAmnt*finalVec.z;
this.x = (1 - changeAmnt) * this.x + changeAmnt * finalVec.x;
this.y = (1 - changeAmnt) * this.y + changeAmnt * finalVec.y;
this.z = (1 - changeAmnt) * this.z + changeAmnt * finalVec.z;
return this;
}
/**
* Sets this vector to the interpolation by changeAmnt from beginVec to finalVec
* this=(1-changeAmnt)*beginVec + changeAmnt * finalVec
*
* @param beginVec the beginning vector (changeAmnt=0)
* @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from beginVec towards finalVec
* @return this
*/
public Vector3f interpolateLocal(Vector3f beginVec,Vector3f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*beginVec.x + changeAmnt*finalVec.x;
this.y=(1-changeAmnt)*beginVec.y + changeAmnt*finalVec.y;
this.z=(1-changeAmnt)*beginVec.z + changeAmnt*finalVec.z;
public Vector3f interpolateLocal(Vector3f beginVec, Vector3f finalVec, float changeAmnt) {
this.x = (1 - changeAmnt) * beginVec.x + changeAmnt * finalVec.x;
this.y = (1 - changeAmnt) * beginVec.y + changeAmnt * finalVec.y;
this.z = (1 - changeAmnt) * beginVec.z + changeAmnt * finalVec.z;
return this;
}
/**
* Check a vector... if it is null or its floats are NaN or infinite,
* return false. Else return true.
*
* @param vector the vector to check
* @return true or false as stated above.
*/
public static boolean isValidVector(Vector3f vector) {
if (vector == null) return false;
if (Float.isNaN(vector.x) ||
Float.isNaN(vector.y) ||
Float.isNaN(vector.z)) return false;
if (Float.isInfinite(vector.x) ||
Float.isInfinite(vector.y) ||
Float.isInfinite(vector.z)) return false;
return true;
if (vector == null) {
return false;
}
if (Float.isNaN(vector.x)
|| Float.isNaN(vector.y)
|| Float.isNaN(vector.z)) {
return false;
}
if (Float.isInfinite(vector.x)
|| Float.isInfinite(vector.y)
|| Float.isInfinite(vector.z)) {
return false;
}
return true;
}
public static void generateOrthonormalBasis(Vector3f u, Vector3f v, Vector3f w) {
@ -934,7 +935,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
/**
* Saves this Vector3f into the given float[] object.
*
*
* @param floats
* The float[] to take this Vector3f. If null, a new float[3] is
* created.
@ -959,20 +960,34 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* @return true if they are equal
*/
public boolean equals(Object o) {
if (!(o instanceof Vector3f)) { return false; }
if (!(o instanceof Vector3f)) {
return false;
}
if (this == o) { return true; }
if (this == o) {
return true;
}
Vector3f comp = (Vector3f) o;
if (Float.compare(x,comp.x) != 0) return false;
if (Float.compare(y,comp.y) != 0) return false;
if (Float.compare(z,comp.z) != 0) return false;
if (Float.compare(x, comp.x) != 0) {
return false;
}
if (Float.compare(y, comp.y) != 0) {
return false;
}
if (Float.compare(z, comp.z) != 0) {
return false;
}
return true;
}
/**
* Returns true if this vector is similar to the specified vector within
* some value of epsilon.
*
* @param other the vector to compare with (not null, unaffected)
* @param epsilon the desired error tolerance for each component
* @return true if all 3 components are within tolerance, otherwise false
*/
public boolean isSimilar(Vector3f other, float epsilon) {
if (other == null) {
@ -994,6 +1009,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
* <code>hashCode</code> returns a unique code for this vector object based
* on its values. If two vectors are logically equivalent, they will return
* the same hash code value.
*
* @return the hash code value of this vector.
*/
public int hashCode() {
@ -1056,7 +1072,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
this.z = z;
return this;
}
/**
* @param index
* @return x value if index == 0, y value if index == 1 or z value if index ==
@ -1075,7 +1091,7 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
throw new IllegalArgumentException("index must be either 0, 1 or 2");
}
/**
* @param index
* which field index in this vector to set.
@ -1098,5 +1114,4 @@ public final class Vector3f implements Savable, Cloneable, java.io.Serializable
}
throw new IllegalArgumentException("index must be either 0, 1 or 2");
}
}

@ -232,6 +232,8 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* the y value to add.
* @param addZ
* the z value to add.
* @param addW
* the w value to add.
* @return the result vector.
*/
public Vector4f add(float addX, float addY, float addZ, float addW) {
@ -249,6 +251,8 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* value to add to y
* @param addZ
* value to add to z
* @param addW
* the w value to add.
* @return this
*/
public Vector4f addLocal(float addX, float addY, float addZ, float addW) {
@ -268,6 +272,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* the value to multiply this vector by.
* @param add
* the value to add
* @return this
*/
public Vector4f scaleAdd(float scalar, Vector4f add) {
x = x * scalar + add.x;
@ -288,6 +293,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* the value to multiply the scalar by
* @param add
* the value to add
* @return this
*/
public Vector4f scaleAdd(float scalar, Vector4f mult, Vector4f add) {
this.x = mult.x * scalar + add.x;
@ -732,6 +738,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* component in this and <code>other</code> vector. The result is stored
* in this vector.
* @param other
* @return this
*/
public Vector4f maxLocal(Vector4f other){
x = other.x > x ? other.x : x;
@ -746,6 +753,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* component in this and <code>other</code> vector. The result is stored
* in this vector.
* @param other
* @return this
*/
public Vector4f minLocal(Vector4f other){
x = other.x < x ? other.x : x;
@ -757,6 +765,8 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
/**
* <code>zero</code> resets this vector's data to zero internally.
*
* @return this, with all components set to zero
*/
public Vector4f zero() {
x = y = z = w = 0;
@ -782,6 +792,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from this towards finalVec
* @return this
*/
public Vector4f interpolateLocal(Vector4f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*this.x + changeAmnt*finalVec.x;
@ -798,6 +809,7 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
* @param finalVec The final vector to interpolate towards
* @param changeAmnt An amount between 0.0 - 1.0 representing a percentage
* change from beginVec towards finalVec
* @return this
*/
public Vector4f interpolateLocal(Vector4f beginVec,Vector4f finalVec, float changeAmnt) {
this.x=(1-changeAmnt)*beginVec.x + changeAmnt*finalVec.x;
@ -878,6 +890,10 @@ public final class Vector4f implements Savable, Cloneable, java.io.Serializable
/**
* Returns true if this vector is similar to the specified vector within
* some value of epsilon.
*
* @param other the vector to compare with (not null, unaffected)
* @param epsilon the desired error tolerance for each component
* @return true if all 4 components are within tolerance, otherwise false
*/
public boolean isSimilar(Vector4f other, float epsilon) {
if (other == null) {

@ -45,7 +45,7 @@ public abstract class AbstractOpenCLObject implements OpenCLObject {
@Override
public AbstractOpenCLObject register() {
OpenCLObjectManager.getInstance().registerObject(this);
return this;
return this;
}
@Override
public void release() {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,8 +43,8 @@ import java.nio.ByteBuffer;
* All access methods (read/write/copy/map) are available in both sychronized/blocking versions
* and in async/non-blocking versions. The later ones always return an {@link Event} object
* and have the prefix -Async in their name.
*
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
*
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @author shaman
*/
public abstract class Buffer extends AbstractOpenCLObject {
@ -53,21 +53,21 @@ public abstract class Buffer extends AbstractOpenCLObject {
super(releaser);
}
@Override
public Buffer register() {
super.register();
return this;
}
@Override
public Buffer register() {
super.register();
return this;
}
/**
* @return the size of the buffer in bytes.
* @see Context#createBuffer(long)
* @see Context#createBuffer(long)
*/
public abstract long getSize();
/**
* @return the memory access flags set on creation.
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
* @see Context#createBuffer(long, com.jme3.opencl.MemoryAccess)
*/
public abstract MemoryAccess getMemoryAccessFlags();
@ -75,6 +75,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs a blocking read of the buffer.
* The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte read.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the size in bytes being read
@ -102,6 +103,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs an async/non-blocking read of the buffer.
* The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte read.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the size in bytes being read
@ -130,6 +132,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs a blocking write to the buffer.
* The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte that will be written.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
* @param size the size in bytes to write
@ -157,6 +160,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Performs an async/non-blocking write to the buffer.
* The target buffer must have at least {@code size} bytes remaining.
* This method may set the limit to the last byte that will be written.
*
* @param queue the command queue
* @param src the source buffer, its data is written to this buffer
* @param size the size in bytes to write
@ -183,6 +187,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/**
* Performs a blocking copy operation from this buffer to the specified buffer.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the size in bytes to copy
@ -209,6 +214,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/**
* Performs an async/non-blocking copy operation from this buffer to the specified buffer.
*
* @param queue the command queue
* @param dest the target buffer
* @param size the size in bytes to copy
@ -238,8 +244,9 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Maps this buffer directly into host memory. This might be the fastest method
* to access the contents of the buffer since the OpenCL implementation directly
* provides the memory.<br>
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue
* @param size the size in bytes to map
* @param offset the offset into this buffer
@ -251,7 +258,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/**
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
* sets {@code offset} to zero.
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/
public ByteBuffer map(CommandQueue queue, long size, MappingAccess access) {
@ -261,7 +268,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
/**
* Alternative version of {@link #map(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
* sets {@code size} to {@link #getSize() }.
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/
public ByteBuffer map(CommandQueue queue, MappingAccess access) {
@ -272,6 +279,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Unmaps a previously mapped memory.
* This releases the native resources and for WRITE_ONLY or READ_WRITE access,
* the memory content is sent back to the GPU.
*
* @param queue the command queue
* @param ptr the buffer that was previously mapped
*/
@ -281,8 +289,9 @@ public abstract class Buffer extends AbstractOpenCLObject {
* Maps this buffer asynchronously into host memory. This might be the fastest method
* to access the contents of the buffer since the OpenCL implementation directly
* provides the memory.<br>
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*
* @param queue the command queue
* @param size the size in bytes to map
* @param offset the offset into this buffer
@ -291,28 +300,31 @@ public abstract class Buffer extends AbstractOpenCLObject {
* and the event indicating when the buffer contents are available
*/
public abstract AsyncMapping mapAsync(CommandQueue queue, long size, long offset, MappingAccess access);
/**
* Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, long, com.jme3.opencl.MappingAccess) },
* sets {@code offset} to zero.
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/
public AsyncMapping mapAsync(CommandQueue queue, long size, MappingAccess access) {
return mapAsync(queue, size, 0, access);
}
/**
* Alternative version of {@link #mapAsync(com.jme3.opencl.CommandQueue, long, com.jme3.opencl.MappingAccess) },
* sets {@code size} to {@link #getSize() }.
* <b>Important:</b> The mapped memory MUST be released by calling
* <b>Important:</b> The mapped memory MUST be released by calling
* {@link #unmap(com.jme3.opencl.CommandQueue, java.nio.ByteBuffer) }.
*/
public AsyncMapping mapAsync(CommandQueue queue, MappingAccess access) {
return mapAsync(queue, getSize(), 0, access);
}
/**
* Enqueues a fill operation. This method can be used to initialize or clear
* a buffer with a certain value.
*
* @param queue the command queue
* @param pattern the buffer containing the filling pattern.
* The remaining bytes specify the pattern length
@ -354,14 +366,14 @@ public abstract class Buffer extends AbstractOpenCLObject {
return buffer;
}
}
/**
* Copies this buffer to the specified image.
* Note that no format conversion is done.
* <br>
* For detailed description of the origin and region paramenter, see the
* documentation of the {@link Image} class.
*
*
* @param queue the command queue
* @param dest the target image
* @param srcOffset the offset in bytes into this buffer
@ -370,7 +382,7 @@ public abstract class Buffer extends AbstractOpenCLObject {
* @return the event object
*/
public abstract Event copyToImageAsync(CommandQueue queue, Image dest, long srcOffset, long[] destOrigin, long[] destRegion);
/**
* Aquires this buffer object for using. Only call this method if this buffer
* represents a shared object from OpenGL, created with e.g.
@ -379,11 +391,12 @@ public abstract class Buffer extends AbstractOpenCLObject {
* done, the buffer must be released by calling
* {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the VertexBuffer again.
*
* @param queue the command queue
* @return the event object
*/
public abstract Event acquireBufferForSharingAsync(CommandQueue queue);
/**
* Aquires this buffer object for using. Only call this method if this buffer
* represents a shared object from OpenGL, created with e.g.
@ -392,36 +405,37 @@ public abstract class Buffer extends AbstractOpenCLObject {
* done, the buffer must be released by calling
* {@link #releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the VertexBuffer again.
*
*
* The generated event object is directly released.
* This brings a performance improvement when the resource is e.g. directly
* used by a kernel afterwards on the same queue (this implicitly waits for
* this action). If you need the event, use
* this action). If you need the event, use
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) } instead.
*
*
* @param queue the command queue
*/
public void acquireBufferForSharingNoEvent(CommandQueue queue) {
//default implementation, overwrite for better performance
acquireBufferForSharingAsync(queue).release();
}
/**
* Releases a shared buffer object.
* Call this method after the buffer object was acquired by
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL.
*
* @param queue the command queue
* @return the event object
*/
public abstract Event releaseBufferForSharingAsync(CommandQueue queue);
/**
* Releases a shared buffer object.
* Call this method after the buffer object was acquired by
* {@link #acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL.
* The generated event object is directly released, resulting in
* The generated event object is directly released, resulting in
* performance improvements.
* @param queue the command queue
*/
@ -430,9 +444,8 @@ public abstract class Buffer extends AbstractOpenCLObject {
releaseBufferForSharingAsync(queue).release();
}
@Override
public String toString() {
return "Buffer (" + getSize() + "B)";
}
@Override
public String toString() {
return "Buffer (" + getSize() + "B)";
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,39 +34,40 @@ package com.jme3.opencl;
/**
* Wrapper for an OpenCL command queue.
* The command queue serializes every GPU function call: By passing the same
* queue to OpenCL function (buffer, image operations, kernel calls), it is
* queue to OpenCL function (buffer, image operations, kernel calls), it is
* ensured that they are executed in the order in which they are passed.
* <br>
* Each command queue is associtated with exactly one device: that device
* is specified on creation ({@link Context#createQueue(com.jme3.opencl.Device) })
* and all commands are sent to this device.
*
* @author shaman
*/
public abstract class CommandQueue extends AbstractOpenCLObject {
protected Device device;
protected Device device;
protected CommandQueue(ObjectReleaser releaser, Device device) {
super(releaser);
this.device = device;
this.device = device;
}
@Override
public CommandQueue register() {
super.register();
return this;
}
@Override
public CommandQueue register() {
super.register();
return this;
}
/**
* Returns the device associated with this command queue.
* It can be used to query properties of the device that is used to execute
* the commands issued to this command queue.
*
* @return the associated device
*/
public Device getDevice() {
return device;
}
/**
* Returns the device associated with this command queue.
* It can be used to query properties of the device that is used to execute
* the commands issued to this command queue.
* @return the associated device
*/
public Device getDevice() {
return device;
}
/**
* Issues all previously queued OpenCL commands in command_queue to the
* device associated with command queue. Flush only guarantees that all
@ -83,5 +84,4 @@ public abstract class CommandQueue extends AbstractOpenCLObject {
* processed and completed. Finish is also a synchronization point.
*/
public abstract void finish();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -63,6 +63,7 @@ import java.util.logging.Logger;
* <li>Created buffers and images shared with OpenGL vertex buffers, textures and renderbuffers</li>
* <li>Create program objects from source code and source files</li>
* </ul>
*
* @author shaman
*/
public abstract class Context extends AbstractOpenCLObject {
@ -72,11 +73,11 @@ public abstract class Context extends AbstractOpenCLObject {
super(releaser);
}
@Override
public Context register() {
super.register();
return this;
}
@Override
public Context register() {
super.register();
return this;
}
/**
* Returns all available devices for this context.
@ -87,6 +88,7 @@ public abstract class Context extends AbstractOpenCLObject {
* memory size and so on, are queried over the Device instances.
* <br>
* The available devices were specified by a {@link PlatformChooser}.
*
* @return a list of devices
*/
public abstract List<? extends Device> getDevices();
@ -94,29 +96,35 @@ public abstract class Context extends AbstractOpenCLObject {
/**
* Alternative version of {@link #createQueue(com.jme3.opencl.Device) },
* just uses the first device returned by {@link #getDevices() }.
*
* @return the command queue
*/
public CommandQueue createQueue() {
return createQueue(getDevices().get(0));
}
/**
* Creates a command queue sending commands to the specified device.
* The device must be an entry of {@link #getDevices() }.
*
* @param device the target device
* @return the command queue
*/
public abstract CommandQueue createQueue(Device device);
public abstract CommandQueue createQueue(Device device);
/**
* Allocates a new buffer of the specific size and access type on the device.
*
* @param size the size of the buffer in bytes
* @param access the allowed access of this buffer from kernel code
* @return the new buffer
*/
public abstract Buffer createBuffer(long size, MemoryAccess access);
/**
* Alternative version of {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) },
* creates a buffer with read and write access.
*
* @param size the size of the buffer in bytes
* @return the new buffer
*/
@ -129,14 +137,17 @@ public abstract class Context extends AbstractOpenCLObject {
* specified by a ByteBuffer can then be used directly by kernel code,
* although the access might be slower than with native buffers
* created by {@link #createBuffer(long, com.jme3.opencl.MemoryAccess) }.
*
* @param data the host buffer to use
* @param access the allowed access of this buffer from kernel code
* @return the new buffer
*/
public abstract Buffer createBufferFromHost(ByteBuffer data, MemoryAccess access);
/**
* Alternative version of {@link #createBufferFromHost(java.nio.ByteBuffer, com.jme3.opencl.MemoryAccess) },
* creates a buffer with read and write access.
*
* @param data the host buffer to use
* @return the new buffer
*/
@ -152,14 +163,15 @@ public abstract class Context extends AbstractOpenCLObject {
* with row and slice pitches. This buffer is then used to store the image.
* If no ByteBuffer is specified, a new buffer is allocated (this is the
* normal behaviour).
*
* @param access the allowed access of this image from kernel code
* @param format the image format
* @param descr the image descriptor
* @return the new image object
*/
public abstract Image createImage(MemoryAccess access, ImageFormat format, ImageDescriptor descr);
//TODO: add simplified methods for 1D, 2D, 3D textures
//TODO: add simplified methods for 1D, 2D, 3D textures
/**
* Queries all supported image formats for a specified memory access and
* image type.
@ -168,16 +180,17 @@ public abstract class Context extends AbstractOpenCLObject {
* where {@code ImageChannelType} or {@code ImageChannelOrder} are {@code null}
* (or both). This is the case when the device supports new formats that
* are not included in this wrapper yet.
*
* @param access the memory access type
* @param type the image type (1D, 2D, 3D, ...)
* @return an array of all supported image formats
*/
public abstract ImageFormat[] querySupportedFormats(MemoryAccess access, ImageType type);
//Interop
//Interop
/**
* Creates a shared buffer from a VertexBuffer.
* The returned buffer and the vertex buffer operate on the same memory,
* Creates a shared buffer from a VertexBuffer.
* The returned buffer and the vertex buffer operate on the same memory,
* changes in one view are visible in the other view.
* This can be used to modify meshes directly from OpenCL (e.g. for particle systems).
* <br>
@ -188,6 +201,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Buffer#acquireBufferForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Buffer#releaseBufferForSharingAsync(com.jme3.opencl.CommandQueue) }.
* This is needed so that OpenGL and OpenCL operations do not interfere with each other.
*
* @param vb the vertex buffer to share
* @param access the memory access for the kernel
* @return the new buffer
@ -208,7 +222,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* This is needed so that OpenGL and OpenCL operations do not interfere with each other.
*
*
* @param image the jME3 image object
* @param textureType the texture type (1D, 2D, 3D), since this is not stored in the image
* @param miplevel the mipmap level that should be shared
@ -216,6 +230,7 @@ public abstract class Context extends AbstractOpenCLObject {
* @return the OpenCL image
*/
public abstract Image bindImage(com.jme3.texture.Image image, Texture.Type textureType, int miplevel, MemoryAccess access);
/**
* Creates a shared image object from a jME3 texture.
* The returned image shares the same memory with the jME3 texture, changes
@ -233,7 +248,7 @@ public abstract class Context extends AbstractOpenCLObject {
* <p>
* This method is equivalent to calling
* {@code bindImage(texture.getImage(), texture.getType(), miplevel, access)}.
*
*
* @param texture the jME3 texture
* @param miplevel the mipmap level that should be shared
* @param access the allowed memory access for kernels
@ -242,9 +257,11 @@ public abstract class Context extends AbstractOpenCLObject {
public Image bindImage(Texture texture, int miplevel, MemoryAccess access) {
return bindImage(texture.getImage(), texture.getType(), miplevel, access);
}
/**
* Alternative version to {@link #bindImage(com.jme3.texture.Texture, int, com.jme3.opencl.MemoryAccess) },
* uses {@code miplevel=0}.
* uses {@code miplevel=0}.
*
* @param texture the jME3 texture
* @param access the allowed memory access for kernels
* @return the OpenCL image
@ -252,6 +269,7 @@ public abstract class Context extends AbstractOpenCLObject {
public Image bindImage(Texture texture, MemoryAccess access) {
return bindImage(texture, 0, access);
}
/**
* Creates a shared image object from a jME3 render buffer.
* The returned image shares the same memory with the jME3 render buffer, changes
@ -267,7 +285,7 @@ public abstract class Context extends AbstractOpenCLObject {
* by {@link Image#acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* and after modifying it, released by {@link Image#releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* This is needed so that OpenGL and OpenCL operations do not interfere with each other.
*
*
* @param buffer
* @param access
* @return an image
@ -279,22 +297,24 @@ public abstract class Context extends AbstractOpenCLObject {
return bindImage(buffer.getTexture(), access);
}
}
protected abstract Image bindPureRenderBuffer(FrameBuffer.RenderBuffer buffer, MemoryAccess access);
/**
* Creates a program object from the provided source code.
* The program still needs to be compiled using {@link Program#build() }.
*
*
* @param sourceCode the source code
* @return the program object
*/
public abstract Program createProgramFromSourceCode(String sourceCode);
/**
* Resolves dependencies (using {@code #include } in the source code)
* and delegates the combined source code to
* {@link #createProgramFromSourceCode(java.lang.String) }.
* Important: only absolute paths are allowed.
*
* @param sourceCode the original source code
* @param assetManager the asset manager to load the files
* @return the created program object
@ -310,6 +330,7 @@ public abstract class Context extends AbstractOpenCLObject {
}
return createProgramFromSourceCode(builder.toString());
}
private void buildSourcesRec(BufferedReader reader, StringBuilder builder, AssetManager assetManager) throws IOException {
String ln;
while ((ln = reader.readLine()) != null) {
@ -319,11 +340,11 @@ public abstract class Context extends AbstractOpenCLObject {
ln = ln.substring(1);
}
if (ln.endsWith("\"")) {
ln = ln.substring(0, ln.length()-1);
ln = ln.substring(0, ln.length() - 1);
}
AssetInfo info = assetManager.locateAsset(new AssetKey<String>(ln));
if (info == null) {
throw new AssetNotFoundException("Unable to load source file \""+ln+"\"");
throw new AssetNotFoundException("Unable to load source file \"" + ln + "\"");
}
try (BufferedReader r = new BufferedReader(new InputStreamReader(info.openStream()))) {
builder.append("//-- begin import ").append(ln).append(" --\n");
@ -335,10 +356,10 @@ public abstract class Context extends AbstractOpenCLObject {
}
}
}
/**
* Creates a program object from the provided source code and files.
* The source code is made up from the specified include string first,
* The source code is made up from the specified include string first,
* then all files specified by the resource array (array of asset paths)
* are loaded by the provided asset manager and appended to the source code.
* <p>
@ -348,10 +369,10 @@ public abstract class Context extends AbstractOpenCLObject {
* <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li>
* <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li>
* </ul>
*
*
* After the files were combined, additional include statements are resolved
* by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }.
*
*
* @param assetManager the asset manager used to load the files
* @param include an additional include string
* @param resources an array of asset paths pointing to OpenCL source files
@ -364,7 +385,7 @@ public abstract class Context extends AbstractOpenCLObject {
/**
* Creates a program object from the provided source code and files.
* The source code is made up from the specified include string first,
* The source code is made up from the specified include string first,
* then all files specified by the resource array (array of asset paths)
* are loaded by the provided asset manager and appended to the source code.
* <p>
@ -374,10 +395,10 @@ public abstract class Context extends AbstractOpenCLObject {
* <li>Some common OpenCL files used as libraries (Convention: file names end with {@code .clh}</li>
* <li>One main OpenCL file containing the actual kernels (Convention: file name ends with {@code .cl})</li>
* </ul>
*
*
* After the files were combined, additional include statements are resolved
* by {@link #createProgramFromSourceCodeWithDependencies(java.lang.String, com.jme3.asset.AssetManager) }.
*
*
* @param assetManager the asset manager used to load the files
* @param include an additional include string
* @param resources an array of asset paths pointing to OpenCL source files
@ -390,7 +411,7 @@ public abstract class Context extends AbstractOpenCLObject {
for (String res : resources) {
AssetInfo info = assetManager.locateAsset(new AssetKey<String>(res));
if (info == null) {
throw new AssetNotFoundException("Unable to load source file \""+res+"\"");
throw new AssetNotFoundException("Unable to load source file \"" + res + "\"");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(info.openStream()))) {
while (true) {
@ -401,7 +422,7 @@ public abstract class Context extends AbstractOpenCLObject {
str.append(line).append('\n');
}
} catch (IOException ex) {
LOG.log(Level.WARNING, "unable to load source file '"+res+"'", ex);
LOG.log(Level.WARNING, "unable to load source file '" + res + "'", ex);
}
}
return createProgramFromSourceCodeWithDependencies(str.toString(), assetManager);
@ -410,6 +431,7 @@ public abstract class Context extends AbstractOpenCLObject {
/**
* Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.lang.String...) }
* with an empty include string
*
* @throws AssetNotFoundException if a file could not be loaded
*/
public Program createProgramFromSourceFiles(AssetManager assetManager, String... resources) {
@ -419,12 +441,13 @@ public abstract class Context extends AbstractOpenCLObject {
/**
* Alternative version of {@link #createProgramFromSourceFilesWithInclude(com.jme3.asset.AssetManager, java.lang.String, java.util.List) }
* with an empty include string
*
* @throws AssetNotFoundException if a file could not be loaded
*/
public Program createProgramFromSourceFiles(AssetManager assetManager, List<String> resources) {
return createProgramFromSourceFilesWithInclude(assetManager, "", resources);
}
/**
* Creates a program from the specified binaries.
* The binaries are created by {@link Program#getBinary(com.jme3.opencl.Device) }.
@ -432,20 +455,19 @@ public abstract class Context extends AbstractOpenCLObject {
* {@link Program#build(java.lang.String, com.jme3.opencl.Device...) }.
* <b>Important:</b>The device passed to {@code Program.getBinary(..)},
* this method and {@code Program#build(..)} must be the same.
*
*
* The binaries are used to build a program cache across multiple launches
* of the application. The programs build much faster from binaries than
* from sources.
*
*
* @param binaries the binaries
* @param device the device to use
* @return the new program
*/
public abstract Program createProgramFromBinary(ByteBuffer binaries, Device device);
@Override
public String toString() {
return "Context (" + getDevices() + ')';
}
@Override
public String toString() {
return "Context (" + getDevices() + ')';
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -41,185 +41,217 @@ import java.util.Collection;
* queue ({@link Context#createQueue(com.jme3.opencl.Device) }).
* <p>
* This class is used to query the capabilities of the underlying device.
*
*
* @author shaman
*/
public interface Device {
/**
* @return the platform associated with this device
*/
Platform getPlatform();
/**
* The device type
*/
public static enum DeviceType {
DEFAULT,
CPU,
GPU,
ACCELEARTOR,
ALL
}
public static enum DeviceType {
DEFAULT,
CPU,
GPU,
ACCELEARTOR,
ALL
}
/**
* @return queries the device type
*/
DeviceType getDeviceType();
DeviceType getDeviceType();
/**
* @return the vendor id
*/
int getVendorId();
int getVendorId();
/**
* checks if this device is available at all, must always be tested
*
* @return checks if this device is available at all, must always be tested
*/
boolean isAvailable();
boolean isAvailable();
/**
* @return if this device has a compiler for kernel code
*/
boolean hasCompiler();
boolean hasCompiler();
/**
* @return supports double precision floats (64 bit)
*/
boolean hasDouble();
boolean hasDouble();
/**
* @return supports half precision floats (16 bit)
*/
boolean hasHalfFloat();
boolean hasHalfFloat();
/**
* @return supports error correction for every access to global or constant memory
*/
boolean hasErrorCorrectingMemory();
boolean hasErrorCorrectingMemory();
/**
* @return supports unified virtual memory (OpenCL 2.0)
*/
boolean hasUnifiedMemory();
boolean hasUnifiedMemory();
/**
* @return supports images
*/
boolean hasImageSupport();
boolean hasImageSupport();
/**
* @return supports writes to 3d images (this is an extension)
*/
boolean hasWritableImage3D();
/**
* @return supports sharing with OpenGL
*/
boolean hasOpenGLInterop();
/**
* Explictly tests for the availability of the specified extension
*
* @param extension the name of the extension
* @return {@code true} iff this extension is supported
*/
boolean hasExtension(String extension);
boolean hasExtension(String extension);
/**
* Lists all available extensions
*
* @return all available extensions
*/
Collection<? extends String> getExtensions();
Collection<? extends String> getExtensions();
/**
* Returns the number of parallel compute units on
* the OpenCL device. A work-group
* executes on a single compute unit. The
* minimum value is 1.
* @return the number of parallel compute units
* @see #getMaximumWorkItemDimensions()
* @see #getMaximumWorkItemSizes()
* @see #getMaximumWorkItemDimensions()
* @see #getMaximumWorkItemSizes()
*/
int getComputeUnits();
int getComputeUnits();
/**
* @return maximum clock frequency of the device in MHz
*/
int getClockFrequency();
int getClockFrequency();
/**
* Returns the default compute device address space
* size specified as an unsigned integer value
* in bits. Currently supported values are 32
* or 64 bits.
*
* @return the size of an address
*/
int getAddressBits();
int getAddressBits();
/**
* @return {@code true} if this device is little endian
*/
boolean isLittleEndian();
boolean isLittleEndian();
/**
* The maximum dimension that specify the local and global work item ids.
* You can always assume to be this at least 3.
* Therefore, the ids are always three integers x,y,z.
*
* @return the maximum dimension of work item ids
*/
long getMaximumWorkItemDimensions();
long getMaximumWorkItemDimensions();
/**
* Maximum number of work-items that can be specified in each dimension of the
* work-group to {@link Kernel#Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)}.
* The array has a length of at least 3.
*
* @return the maximum size of the work group in each dimension
*/
long[] getMaximumWorkItemSizes();
long[] getMaximumWorkItemSizes();
/**
* Maximum number of work-items in a
* work-group executing a kernel on a single
* compute unit, using the data parallel
* execution model.
*
* @return maximum number of work-items in a work-group
*/
long getMaxiumWorkItemsPerGroup();
long getMaxiumWorkItemsPerGroup();
/**
* @return the maximum number of samples that can be used in a kernel
*/
int getMaximumSamplers();
int getMaximumSamplers();
/**
* @return the maximum number of images that can be used for reading in a kernel
*/
int getMaximumReadImages();
int getMaximumReadImages();
/**
* @return the maximum number of images that can be used for writing in a kernel
*/
int getMaximumWriteImages();
int getMaximumWriteImages();
/**
* Queries the maximal size of a 2D image
*
* @return an array of length 2 with the maximal size of a 2D image
*/
long[] getMaximumImage2DSize();
long[] getMaximumImage2DSize();
/**
* Queries the maximal size of a 3D image
*
* @return an array of length 3 with the maximal size of a 3D image
*/
long[] getMaximumImage3DSize();
long[] getMaximumImage3DSize();
/**
* @return the maximal size of a memory object (buffer and image) in bytes
*/
long getMaximumAllocationSize();
/**
* @return the total available global memory in bytes
*/
long getGlobalMemorySize();
/**
* @return the total available local memory in bytes
*/
long getLocalMemorySize();
/**
* Returns the maximal size of a constant buffer.
* <br>
* Constant buffers are normal buffer objects, but passed to the kernel
* with the special declaration {@code __constant BUFFER_TYPE* BUFFER_NAME}.
* Because they have a special caching, their size is usually very limited.
*
*
* @return the maximal size of a constant buffer
*/
long getMaximumConstantBufferSize();
/**
* @return the maximal number of constant buffer arguments in a kernel call
*/
int getMaximumConstantArguments();
//TODO: cache, prefered sizes properties
//TODO: cache, prefered sizes properties
/**
* OpenCL profile string. Returns the profile name supported by the device.
* The profile name returned can be one of the following strings:<br>
@ -230,7 +262,8 @@ public interface Device {
*
* @return the profile string
*/
String getProfile();
String getProfile();
/**
* OpenCL version string. Returns the OpenCL version supported by the
* device. This version string has the following format: OpenCL space
@ -240,20 +273,24 @@ public interface Device {
*
* @return the version string
*/
String getVersion();
String getVersion();
/**
* Extracts the major version from the version string
*
* @return the major version
* @see #getVersion()
* @see #getVersion()
*/
int getVersionMajor();
int getVersionMajor();
/**
* Extracts the minor version from the version string
*
* @return the minor version
* @see #getVersion() }
*/
int getVersionMinor();
int getVersionMinor();
/**
* OpenCL C version string. Returns the highest OpenCL C version supported
* by the compiler for this device that is not of type
@ -268,44 +305,53 @@ public interface Device {
*
* @return the compiler version
*/
String getCompilerVersion();
String getCompilerVersion();
/**
* Extracts the major version from the compiler version
*
* @return the major compiler version
* @see #getCompilerVersion()
* @see #getCompilerVersion()
*/
int getCompilerVersionMajor();
int getCompilerVersionMajor();
/**
* Extracts the minor version from the compiler version
*
* @return the minor compiler version
* @see #getCompilerVersion()
* @see #getCompilerVersion()
*/
int getCompilerVersionMinor();
/**
int getCompilerVersionMinor();
/**
* @return the OpenCL software driver version string in the form
* major_number.minor_number
*/
String getDriverVersion();
String getDriverVersion();
/**
* Extracts the major version from the driver version
*
* @return the major driver version
* @see #getDriverVersion()
* @see #getDriverVersion()
*/
int getDriverVersionMajor();
int getDriverVersionMajor();
/**
* Extracts the minor version from the driver version
*
* @return the minor driver version
* @see #getDriverVersion()
* @see #getDriverVersion()
*/
int getDriverVersionMinor();
int getDriverVersionMinor();
/**
* @return the device name
*/
String getName();
String getName();
/**
* @return the vendor
*/
String getVendor();
String getVendor();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,6 +36,7 @@ package com.jme3.opencl;
* Events are returned from kernel launches and all asynchronous operations.
* They allow to test if the action has completed and to block until the operation
* is done.
*
* @author shaman
*/
public abstract class Event extends AbstractOpenCLObject {
@ -44,22 +45,23 @@ public abstract class Event extends AbstractOpenCLObject {
super(releaser);
}
@Override
public Event register() {
super.register();
return this;
}
@Override
public Event register() {
super.register();
return this;
}
/**
* Waits until the action has finished (blocking).
* This automatically releases the event.
*/
public abstract void waitForFinished();
public abstract void waitForFinished();
/**
* Tests if the action is completed.
* If the action is completed, the event is released.
*
* @return {@code true} if the action is completed
*/
public abstract boolean isCompleted();
public abstract boolean isCompleted();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -41,16 +41,16 @@ import java.util.Objects;
* An image object is similar to a {@link Buffer}, but with a specific element
* format and buffer structure.
* <br>
* The image is specified by the {@link ImageDescriptor}, specifying
* The image is specified by the {@link ImageDescriptor}, specifying
* the extend and dimension of the image, and {@link ImageFormat}, specifying
* the type of each pixel.
* <br>
* An image is created from scratch using
* An image is created from scratch using
* {@link Context#createImage(com.jme3.opencl.MemoryAccess, com.jme3.opencl.Image.ImageFormat, com.jme3.opencl.Image.ImageDescriptor) }
* or from OpenGL by
* {@link Context#bindImage(com.jme3.texture.Image, com.jme3.texture.Texture.Type, int, com.jme3.opencl.MemoryAccess) }
* (and alternative versions).
*
*
* <p>
* Most methods take long arrays as input: {@code long[] origin} and {@code long[] region}.
* Both are arrays of length 3.
@ -75,7 +75,6 @@ import java.util.Objects;
* @author shaman
*/
public abstract class Image extends AbstractOpenCLObject {
/**
* {@code ImageChannelType} describes the size of the channel data type.
*/
@ -96,10 +95,10 @@ public abstract class Image extends AbstractOpenCLObject {
HALF_FLOAT,
FLOAT
}
/**
* {@code ImageChannelOrder} specifies the number of channels and the channel layout i.e. the
memory layout in which channels are stored in the image.
* memory layout in which channels are stored in the image.
*/
public static enum ImageChannelOrder {
R, Rx, A,
@ -112,7 +111,7 @@ memory layout in which channels are stored in the image.
}
/**
* Describes the image format, consisting of
* Describes the image format, consisting of
* {@link ImageChannelOrder} and {@link ImageChannelType}.
*/
public static class ImageFormat { //Struct
@ -157,7 +156,6 @@ memory layout in which channels are stored in the image.
}
return true;
}
}
/**
@ -193,13 +191,14 @@ memory layout in which channels are stored in the image.
/*
public int numMipLevels; //They must always be set to zero
public int numSamples;
*/
*/
public ImageDescriptor() {
}
/**
* Used to specify an image with the provided ByteBuffer as soruce
*
* @param type the image type
* @param width the width
* @param height the height, unused for image types {@code ImageType.IMAGE_1D*}
@ -219,9 +218,11 @@ memory layout in which channels are stored in the image.
this.slicePitch = slicePitch;
this.hostPtr = hostPtr;
}
/**
* Specifies an image without a host buffer, a new chunk of memory
* Specifies an image without a host buffer, a new chunk of memory
* will be allocated.
*
* @param type the image type
* @param width the width
* @param height the height, unused for image types {@code ImageType.IMAGE_1D*}
@ -243,60 +244,68 @@ memory layout in which channels are stored in the image.
public String toString() {
return "ImageDescriptor{" + "type=" + type + ", width=" + width + ", height=" + height + ", depth=" + depth + ", arraySize=" + arraySize + ", rowPitch=" + rowPitch + ", slicePitch=" + slicePitch + '}';
}
}
protected Image(ObjectReleaser releaser) {
super(releaser);
}
@Override
public Image register() {
super.register();
return this;
}
@Override
public Image register() {
super.register();
return this;
}
/**
* @return the width of the image
*/
public abstract long getWidth();
/**
* @return the height of the image
*/
public abstract long getHeight();
/**
* @return the depth of the image
*/
public abstract long getDepth();
/**
* @return the row pitch when the image was created from a host buffer
*/
public abstract long getRowPitch();
/**
* @return the slice pitch when the image was created from a host buffer
*/
public abstract long getSlicePitch();
/**
* @return the number of elements in the image array
* @see ImageType#IMAGE_1D_ARRAY
* @see ImageType#IMAGE_2D_ARRAY
*/
public abstract long getArraySize();
/**
* @return the image format
*/
public abstract ImageFormat getImageFormat();
/**
* @return the image type
*/
public abstract ImageType getImageType();
/**
* @return the number of bytes per pixel
*/
public abstract int getElementSize();
/**
* Performs a blocking read of the image into the specified byte buffer.
*
* @param queue the command queue
* @param dest the target byte buffer
* @param origin the image origin location, see class description for the format
@ -307,8 +316,10 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
public abstract void readImage(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking read of the image into the specified byte buffer.
*
* @param queue the command queue
* @param dest the target byte buffer
* @param origin the image origin location, see class description for the format
@ -320,9 +331,10 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation
*/
public abstract Event readImageAsync(CommandQueue queue, ByteBuffer dest, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking write from the specified byte buffer into the image.
*
* @param queue the command queue
* @param src the source buffer
* @param origin the image origin location, see class description for the format
@ -333,8 +345,10 @@ memory layout in which channels are stored in the image.
* If set to 0 for 3D images, the slice pitch is calculated as {@code rowPitch * height}
*/
public abstract void writeImage(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs an async/non-blocking write from the specified byte buffer into the image.
*
* @param queue the command queue
* @param src the source buffer
* @param origin the image origin location, see class description for the format
@ -346,10 +360,11 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation
*/
public abstract Event writeImageAsync(CommandQueue queue, ByteBuffer src, long[] origin, long[] region, long rowPitch, long slicePitch);
/**
* Performs a blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format!
*
* @param queue the command queue
* @param dest the target image
* @param srcOrigin the source image origin, see class description for the format
@ -357,9 +372,11 @@ memory layout in which channels are stored in the image.
* @param region the copied region, see class description for the format
*/
public abstract void copyTo(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Performs an async/non-blocking copy operation from one image to another.
* <b>Important:</b> Both images must have the same format!
*
* @param queue the command queue
* @param dest the target image
* @param srcOrigin the source image origin, see class description for the format
@ -368,20 +385,22 @@ memory layout in which channels are stored in the image.
* @return the event object indicating the status of the operation
*/
public abstract Event copyToAsync(CommandQueue queue, Image dest, long[] srcOrigin, long[] destOrigin, long[] region);
/**
* Maps the image into host memory.
* The returned structure contains the mapped byte buffer and row and slice pitch.
* The event object is set to {@code null}, it is needed for the asnyc
* version {@link #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }.
*
* @param queue the command queue
* @param origin the image origin, see class description for the format
* @param region the mapped region, see class description for the format
* @param access the allowed memory access to the mapped memory
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
public abstract ImageMapping map(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Non-blocking version of {@link #map(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess) }.
* The returned structure contains the mapped byte buffer and row and slice pitch.
@ -391,16 +410,18 @@ memory layout in which channels are stored in the image.
* @param region the mapped region, see class description for the format
* @param access the allowed memory access to the mapped memory
* @return a structure describing the mapped memory
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
* @see #unmap(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image.ImageMapping)
*/
public abstract ImageMapping mapAsync(CommandQueue queue, long[] origin, long[] region, MappingAccess access);
/**
* Unmaps the mapped memory
*
* @param queue the command queue
* @param mapping the mapped memory
*/
public abstract void unmap(CommandQueue queue, ImageMapping mapping);
/**
* Describes a mapped region of the image
*/
@ -421,7 +442,8 @@ memory layout in which channels are stored in the image.
public final long slicePitch;
/**
* The event object used to detect when the memory is available.
* @see #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess)
*
* @see #mapAsync(com.jme3.opencl.CommandQueue, long[], long[], com.jme3.opencl.MappingAccess)
*/
public final Event event;
@ -431,19 +453,20 @@ memory layout in which channels are stored in the image.
this.slicePitch = slicePitch;
this.event = event;
}
public ImageMapping(ByteBuffer buffer, long rowPitch, long slicePitch) {
this.buffer = buffer;
this.rowPitch = rowPitch;
this.slicePitch = slicePitch;
this.event = null;
}
}
/**
* Fills the image with the specified color.
* Does <b>only</b> work if the image channel is {@link ImageChannelType#FLOAT}
* or {@link ImageChannelType#HALF_FLOAT}.
*
* @param queue the command queue
* @param origin the image origin, see class description for the format
* @param region the size of the region, see class description for the format
@ -455,6 +478,7 @@ memory layout in which channels are stored in the image.
* Fills the image with the specified color given as four integer variables.
* Does <b>not</b> work if the image channel is {@link ImageChannelType#FLOAT}
* or {@link ImageChannelType#HALF_FLOAT}.
*
* @param queue the command queue
* @param origin the image origin, see class description for the format
* @param region the size of the region, see class description for the format
@ -462,11 +486,12 @@ memory layout in which channels are stored in the image.
* @return an event object to detect for the completion
*/
public abstract Event fillAsync(CommandQueue queue, long[] origin, long[] region, int[] color);
/**
* Copies this image into the specified buffer, no format conversion is done.
* This is the dual function to
* This is the dual function to
* {@link Buffer#copyToImageAsync(com.jme3.opencl.CommandQueue, com.jme3.opencl.Image, long, long[], long[]) }.
*
* @param queue the command queue
* @param dest the target buffer
* @param srcOrigin the image origin, see class description for the format
@ -475,7 +500,7 @@ memory layout in which channels are stored in the image.
* @return the event object to detect the completion of the operation
*/
public abstract Event copyToBufferAsync(CommandQueue queue, Buffer dest, long[] srcOrigin, long[] srcRegion, long destOffset);
/**
* Aquires this image object for using. Only call this method if this image
* represents a shared object from OpenGL, created with e.g.
@ -485,11 +510,12 @@ memory layout in which channels are stored in the image.
* done, the image must be released by calling
* {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the image/texture/renderbuffer again.
*
* @param queue the command queue
* @return the event object
*/
public abstract Event acquireImageForSharingAsync(CommandQueue queue);
/**
* Aquires this image object for using. Only call this method if this image
* represents a shared object from OpenGL, created with e.g.
@ -499,37 +525,39 @@ memory layout in which channels are stored in the image.
* done, the image must be released by calling
* {@link #releaseImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* so that OpenGL can use the image/texture/renderbuffer again.
*
*
* The generated event object is directly released.
* This brings a performance improvement when the resource is e.g. directly
* used by a kernel afterwards on the same queue (this implicitly waits for
* this action). If you need the event, use
* this action). If you need the event, use
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }.
*
*
* @param queue the command queue
*/
public void acquireImageForSharingNoEvent(CommandQueue queue) {
//Default implementation, overwrite for performance
acquireImageForSharingAsync(queue).release();
}
/**
* Releases a shared image object.
* Call this method after the image object was acquired by
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL.
*
* @param queue the command queue
* @return the event object
*/
public abstract Event releaseImageForSharingAsync(CommandQueue queue);
/**
* Releases a shared image object.
* Call this method after the image object was acquired by
* {@link #acquireImageForSharingAsync(com.jme3.opencl.CommandQueue) }
* to hand the control back to OpenGL.
* The generated event object is directly released, resulting in
* The generated event object is directly released, resulting in
* performance improvements.
*
* @param queue the command queue
*/
public void releaseImageForSharingNoEvent(CommandQueue queue) {
@ -537,25 +565,24 @@ memory layout in which channels are stored in the image.
releaseImageForSharingAsync(queue).release();
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("Image (");
ImageType t = getImageType();
str.append(t);
str.append(", w=").append(getWidth());
if (t == ImageType.IMAGE_2D || t == ImageType.IMAGE_3D) {
str.append(", h=").append(getHeight());
}
if (t == ImageType.IMAGE_3D) {
str.append(", d=").append(getDepth());
}
if (t == ImageType.IMAGE_1D_ARRAY || t == ImageType.IMAGE_2D_ARRAY) {
str.append(", arrays=").append(getArraySize());
}
str.append(", ").append(getImageFormat());
str.append(')');
return str.toString();
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("Image (");
ImageType t = getImageType();
str.append(t);
str.append(", w=").append(getWidth());
if (t == ImageType.IMAGE_2D || t == ImageType.IMAGE_3D) {
str.append(", h=").append(getHeight());
}
if (t == ImageType.IMAGE_3D) {
str.append(", d=").append(getDepth());
}
if (t == ImageType.IMAGE_1D_ARRAY || t == ImageType.IMAGE_2D_ARRAY) {
str.append(", arrays=").append(getArraySize());
}
str.append(", ").append(getImageFormat());
str.append(')');
return str.toString();
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2018 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -40,7 +40,7 @@ import java.util.Arrays;
* Wrapper for an OpenCL kernel, a piece of executable code on the GPU.
* <p>
* Terminology:<br>
* A Kernel is executed in parallel. In total number of parallel threads,
* A Kernel is executed in parallel. In total number of parallel threads,
* called work items, are specified by the <i>global work size</i> (of type
* {@link WorkSize}. These threads are organized in a 1D, 2D or 3D grid
* (of coarse, this is only a logical view). Inside each kernel,
@ -54,7 +54,7 @@ import java.util.Arrays;
* The maximal size of it can be queried by {@link Device#getMaxiumWorkItemsPerGroup() }.
* Again, the threads inside the work group can be organized in a 1D, 2D or 3D
* grid, but this is also just a logical view (specifying how the threads are
* indexed).
* indexed).
* The work group is important for another concept: <i> shared memory</i>
* Unlike the normal global or constant memory (passing a {@link Buffer} object
* as argument), shared memory can't be set from outside. Shared memory is
@ -64,22 +64,22 @@ import java.util.Arrays;
* {@link LocalMem} or {@link LocalMemPerElement} as argument.<br>
* Due to heavy register usage or other reasons, a kernel might not be able
* to utilize a whole work group. Therefore, the actual number of threads
* that can be executed in a work group can be queried by
* {@link #getMaxWorkGroupSize(com.jme3.opencl.Device) }, which might differ from the
* that can be executed in a work group can be queried by
* {@link #getMaxWorkGroupSize(com.jme3.opencl.Device) }, which might differ from the
* value returned from the Device.
*
*
* <p>
* There are two ways to launch a kernel:<br>
* First, arguments and the work group sizes can be set in advance
* First, arguments and the work group sizes can be set in advance
* ({@code setArg(index, ...)}, {@code setGlobalWorkSize(...)} and {@code setWorkGroupSize(...)}.
* Then a kernel is launched by {@link #Run(com.jme3.opencl.CommandQueue) }.<br>
* Second, two convenient functions are provided that set the arguments
* and work sizes in one call:
* {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }
* and {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*
*
* @author shaman
* @see Program#createKernel(java.lang.String)
* @see Program#createKernel(java.lang.String)
*/
public abstract class Kernel extends AbstractOpenCLObject {
/**
@ -97,12 +97,12 @@ public abstract class Kernel extends AbstractOpenCLObject {
this.workGroupSize = new WorkSize(0);
}
@Override
public Kernel register() {
super.register();
return this;
}
@Override
public Kernel register() {
super.register();
return this;
}
/**
* @return the name of the kernel as defined in the program source code
*/
@ -122,6 +122,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the global work size.
*
* @param ws the work size to set
*/
public void setGlobalWorkSize(WorkSize ws) {
@ -130,6 +131,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the global work size to a 1D grid
*
* @param size the size in 1D
*/
public void setGlobalWorkSize(int size) {
@ -138,6 +140,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the global work size to be a 2D grid
*
* @param width the width
* @param height the height
*/
@ -147,6 +150,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the global work size to be a 3D grid
*
* @param width the width
* @param height the height
* @param depth the depth
@ -164,6 +168,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the work group size
*
* @param ws the work group size to set
*/
public void setWorkGroupSize(WorkSize ws) {
@ -172,6 +177,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the work group size to be a 1D grid
*
* @param size the size to set
*/
public void setWorkGroupSize(int size) {
@ -180,6 +186,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the work group size to be a 2D grid
*
* @param width the width
* @param height the height
*/
@ -189,6 +196,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the work group size to be a 3D grid
*
* @param width the width
* @param height the height
* @param depth the depth
@ -196,7 +204,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
public void setWorkGroupSdize(int width, int height, int depth) {
workGroupSize.set(3, width, height, depth);
}
/**
* Tells the driver to figure out the work group size on their own.
* Use this if you do not rely on specific work group layouts, i.e.
@ -207,10 +215,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
public void setWorkGroupSizeToNull() {
workGroupSize.set(1, 0, 0, 0);
}
/**
* Returns the maximal work group size when this kernel is executed on
* the specified device
*
* @param device the device
* @return the maximal work group size
*/
@ -221,7 +230,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
public abstract void setArg(int index, LocalMem t);
public abstract void setArg(int index, Buffer t);
public abstract void setArg(int index, Image i);
public abstract void setArg(int index, byte b);
@ -237,20 +246,20 @@ public abstract class Kernel extends AbstractOpenCLObject {
public abstract void setArg(int index, double d);
public abstract void setArg(int index, Vector2f v);
public abstract void setArg(int index, Vector4f v);
public abstract void setArg(int index, Quaternion q);
public abstract void setArg(int index, Matrix4f mat);
public void setArg(int index, Matrix3f mat) {
TempVars vars = TempVars.get();
try {
Matrix4f m = vars.tempMat4;
m.zero();
for (int i=0; i<3; ++i) {
for (int j=0; j<3; ++j) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
m.set(i, j, mat.get(i, j));
}
}
@ -259,13 +268,14 @@ public abstract class Kernel extends AbstractOpenCLObject {
vars.release();
}
}
/**
* Raw version to set an argument.
* {@code size} bytes of the provided byte buffer are copied to the kernel
* argument. The size in bytes must match exactly the argument size
* as defined in the kernel code.
* Use this method to send custom structures to the kernel
*
* @param index the index of the argument
* @param buffer the raw buffer
* @param size the size in bytes
@ -279,6 +289,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
* long, float, double, Vector2f, Vector4f, Quaternion, Matrix3f, Matrix4f}.
* <br>
* Note: Matrix3f and Matrix4f will be mapped to a {@code float16} (row major).
*
* @param index the index of the argument, from 0 to {@link #getArgCount()}-1
* @param arg the argument
* @throws IllegalArgumentException if the argument type is not one of the listed ones
@ -331,24 +342,26 @@ public abstract class Kernel extends AbstractOpenCLObject {
* If the returned event object is not needed and would otherwise be
* released immediately, {@link #RunNoEvent(com.jme3.opencl.CommandQueue) }
* might bring a better performance.
*
* @param queue the command queue
* @return an event object indicating when the kernel is finished
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object)
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object)
*/
public abstract Event Run(CommandQueue queue);
/**
* Launches the kernel with the current global work size, work group size
* and arguments without returning an event object.
* The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use {@link #Run(com.jme3.opencl.CommandQueue) }.
*
* @param queue the command queue
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object)
* @see #setGlobalWorkSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setWorkGroupSize(com.jme3.opencl.Kernel.WorkSize)
* @see #setArg(int, java.lang.Object)
*/
public void RunNoEvent(CommandQueue queue) {
//Default implementation, overwrite to not allocate the event object
@ -361,11 +374,12 @@ public abstract class Kernel extends AbstractOpenCLObject {
* size is automatically determined by the driver.
* Each object in the argument array is sent to the kernel by
* {@link #setArg(int, java.lang.Object) }.
*
* @param queue the command queue
* @param globalWorkSize the global work size
* @param args the kernel arguments
* @return an event object indicating when the kernel is finished
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
*/
public Event Run1(CommandQueue queue, WorkSize globalWorkSize, Object... args) {
setGlobalWorkSize(globalWorkSize);
@ -373,7 +387,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
setArgs(args);
return Run(queue);
}
/**
* Sets the work sizes and arguments in one call and launches the kernel.
* The global work size is set to the specified size. The work group
@ -382,12 +396,13 @@ public abstract class Kernel extends AbstractOpenCLObject {
* {@link #setArg(int, java.lang.Object) }.
* The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use
* has finished. For this purpose, use
* {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*
* @param queue the command queue
* @param globalWorkSize the global work size
* @param args the kernel arguments
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
* @see #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...)
*/
public void Run1NoEvent(CommandQueue queue, WorkSize globalWorkSize, Object... args) {
setGlobalWorkSize(globalWorkSize);
@ -398,6 +413,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Sets the work sizes and arguments in one call and launches the kernel.
*
* @param queue the command queue
* @param globalWorkSize the global work size
* @param workGroupSize the work group size
@ -416,8 +432,9 @@ public abstract class Kernel extends AbstractOpenCLObject {
* Sets the work sizes and arguments in one call and launches the kernel.
* The generated event is directly released. Therefore, the performance
* is better, but there is no way to detect when the kernel execution
* has finished. For this purpose, use
* has finished. For this purpose, use
* {@link #Run2(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*
* @param queue the command queue
* @param globalWorkSize the global work size
* @param workGroupSize the work group size
@ -431,22 +448,22 @@ public abstract class Kernel extends AbstractOpenCLObject {
RunNoEvent(queue);
}
@Override
public String toString() {
return "Kernel (" + getName() + ")";
}
@Override
public String toString() {
return "Kernel (" + getName() + ")";
}
/**
* A placeholder for kernel arguments representing local kernel memory.
* This defines the size of available shared memory of a {@code __shared} kernel
* A placeholder for kernel arguments representing local kernel memory. This
* defines the size of available shared memory of a {@code __shared} kernel
* argument
*/
public static final class LocalMem {
private int size;
/**
* Creates a new LocalMem instance
*
* @param size the size of the available shared memory in bytes
*/
public LocalMem(int size) {
@ -480,11 +497,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true;
}
@Override
public String toString() {
return "LocalMem (" + size + "B)";
}
@Override
public String toString() {
return "LocalMem (" + size + "B)";
}
}
/**
@ -498,11 +515,11 @@ public abstract class Kernel extends AbstractOpenCLObject {
* (e.g. by {@link #setWorkGroupSizeToNull()} or {@link #Run1(com.jme3.opencl.CommandQueue, com.jme3.opencl.Kernel.WorkSize, java.lang.Object...) }.
*/
public static final class LocalMemPerElement {
private int size;
/**
* Creates a new LocalMemPerElement instance
*
* @param size the number of bytes available for each thread within
* a work group
*/
@ -537,15 +554,16 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true;
}
@Override
public String toString() {
return "LocalMemPerElement (" + size + "B)";
}
@Override
public String toString() {
return "LocalMemPerElement (" + size + "B)";
}
}
/**
* The work size (global and local) for executing a kernel
*
* @author shaman
*/
public static final class WorkSize {
@ -555,6 +573,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Creates a new work size object
*
* @param dimension the dimension (1,2,3)
* @param sizes the sizes in each dimension, the length must match the specified dimension
*/
@ -572,6 +591,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Creates a 1D work size of the specified extend
*
* @param size the size
*/
public WorkSize(long size) {
@ -580,6 +600,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Creates a 2D work size of the specified extend
*
* @param width the width
* @param height the height
*/
@ -589,6 +610,7 @@ public abstract class Kernel extends AbstractOpenCLObject {
/**
* Creates a 3D work size of the specified extend.
*
* @param width the width
* @param height the height
* @param depth the depth
@ -647,20 +669,18 @@ public abstract class Kernel extends AbstractOpenCLObject {
return true;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("WorkSize[");
for (int i=0; i<dimension; ++i) {
if (i>0) {
str.append(", ");
}
str.append(sizes[i]);
}
str.append(']');
return str.toString();
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("WorkSize[");
for (int i = 0; i < dimension; ++i) {
if (i > 0) {
str.append(", ");
}
str.append(sizes[i]);
}
str.append(']');
return str.toString();
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,23 +36,23 @@ package com.jme3.opencl;
* when the compilation failed.
* The error log returned by {@link #getLog() } contains detailed information
* where the error occurred.
*
* @author shaman
*/
public class KernelCompilationException extends OpenCLException {
private final String log;
private final String log;
public KernelCompilationException(String msg, int errorCode, String log) {
super(msg, errorCode);
this.log = log;
}
public KernelCompilationException(String msg, int errorCode, String log) {
super(msg, errorCode);
this.log = log;
}
/**
* The output of the compiler
*
* @return the output text
*/
public String getLog() {
return log;
}
}
public String getLog() {
return log;
}
}

@ -41,18 +41,18 @@ public enum MappingAccess {
/**
* Only read access is allowed to the mapped memory.
*/
MAP_READ_ONLY,
MAP_READ_ONLY,
/**
* Only write access is allowed to the mapped memory.
*/
MAP_WRITE_ONLY,
MAP_WRITE_ONLY,
/**
* Both read and write access is allowed.
*/
MAP_READ_WRITE,
MAP_READ_WRITE,
/**
* The old memory content is completely discarded and the buffer is filled
* completely with new data. This might be faster than {@link #MAP_WRITE_ONLY}
*/
MAP_WRITE_INVALIDATE
MAP_WRITE_INVALIDATE
}

@ -40,13 +40,13 @@ public enum MemoryAccess {
/**
* A kernel can both read and write the buffer.
*/
READ_WRITE,
READ_WRITE,
/**
* A kernel can only write this buffer.
*/
WRITE_ONLY,
WRITE_ONLY,
/**
* A kernel can only read this buffer
*/
READ_ONLY
READ_ONLY
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,43 +36,42 @@ package com.jme3.opencl;
* The error code and its name is reported in the message string as well as the OpenCL call that
* causes this exception. Please refer to the official OpenCL specification
* to see what might cause this exception.
*
* @author shaman
*/
public class OpenCLException extends RuntimeException {
private static final long serialVersionUID = 8471229972153694848L;
private final int errorCode;
/**
* Creates a new instance of <code>OpenCLExceptionn</code> without detail
* message.
*/
public OpenCLException() {
errorCode = 0;
}
private final int errorCode;
/**
* Constructs an instance of <code>OpenCLExceptionn</code> with the
* specified detail message.
*
* @param msg the detail message.
*/
public OpenCLException(String msg) {
super(msg);
errorCode = 0;
}
public OpenCLException(String msg, int errorCode) {
super(msg);
this.errorCode = errorCode;
}
/**
* Creates a new instance of <code>OpenCLExceptionn</code> without detail
* message.
*/
public OpenCLException() {
errorCode = 0;
}
/**
* @return the error code
* Constructs an instance of <code>OpenCLExceptionn</code> with the
* specified detail message.
*
* @param msg the detail message.
*/
public int getErrorCode() {
return errorCode;
}
public OpenCLException(String msg) {
super(msg);
errorCode = 0;
}
public OpenCLException(String msg, int errorCode) {
super(msg);
this.errorCode = errorCode;
}
/**
* @return the error code
*/
public int getErrorCode() {
return errorCode;
}
}

@ -61,7 +61,7 @@ public interface OpenCLObject {
ObjectReleaser getReleaser();
/**
* Releases this native object.
*
*
* Should delegate to {@code getReleaser().release()}.
*/
void release();
@ -71,10 +71,10 @@ public interface OpenCLObject {
* {@link OpenCLObjectManager}, you have to release it manually
* by calling {@link #release() }.
* Without registering or releasing, a memory leak might occur.
* <br>
* Returns {@code this} to allow calls like
* {@code Buffer buffer = clContext.createBuffer(1024).register();}.
* @return {@code this}
* <br>
* Returns {@code this} to allow calls like
* {@code Buffer buffer = clContext.createBuffer(1024).register();}.
* @return {@code this}
*/
OpenCLObject register();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,9 +39,9 @@ import java.nio.ByteBuffer;
* <p>
* Warning: Creating the same kernel more than one leads to undefined behaviour,
* this is especially important for {@link #createAllKernels() }
*
* @see Context#createProgramFromSourceCode(java.lang.String)
* @see #createKernel(java.lang.String)
*
* @see Context#createProgramFromSourceCode(java.lang.String)
* @see #createKernel(java.lang.String)
* @author shaman
*/
public abstract class Program extends AbstractOpenCLObject {
@ -49,13 +49,13 @@ public abstract class Program extends AbstractOpenCLObject {
protected Program(ObjectReleaser releaser) {
super(releaser);
}
@Override
public Program register() {
super.register();
return this;
}
@Override
public Program register() {
super.register();
return this;
}
/**
* Builds this program with the specified argument string on the specified
* devices.
@ -64,46 +64,50 @@ public abstract class Program extends AbstractOpenCLObject {
* The list of devices specify on which device the compiled program
* can then be executed. It must be a subset of {@link Context#getDevices() }.
* If {@code null} is passed, the program is built on all available devices.
*
*
* @param args the compilation arguments
* @param devices a list of devices on which the program is build.
* @throws KernelCompilationException if the compilation fails
* @see #build()
* @see #build()
*/
public abstract void build(String args, Device... devices) throws KernelCompilationException;
public abstract void build(String args, Device... devices) throws KernelCompilationException;
/**
* Builds this program without additional arguments
*
* @throws KernelCompilationException if the compilation fails
*/
public void build() throws KernelCompilationException {
public void build() throws KernelCompilationException {
build("", (Device[]) null);
}
/**
* Creates the kernel with the specified name.
*
* @param name the name of the kernel as defined in the source code
* @return the kernel object
* @throws OpenCLException if the kernel was not found or some other
* error occurred
* @throws OpenCLException if the kernel was not found or some other error
* occurred
*/
public abstract Kernel createKernel(String name);
public abstract Kernel createKernel(String name);
/**
* Creates all available kernels in this program.
* The names of the kernels can then by queried by {@link Kernel#getName() }.
*
* @return an array of all kernels
*/
public abstract Kernel[] createAllKernels();
public abstract Kernel[] createAllKernels();
/**
* Queries a compiled binary representation of this program for a particular
* device. This binary can then be used e.g. in the next application launch
* to create the program from the binaries and not from the sources.
* This saves time.
*
* @param device the device from which the binaries are taken
* @return the binaries
* @see Context#createProgramFromBinary(java.nio.ByteBuffer, com.jme3.opencl.Device)
* @see Context#createProgramFromBinary(java.nio.ByteBuffer, com.jme3.opencl.Device)
*/
public abstract ByteBuffer getBinary(Device device);
}

@ -287,14 +287,14 @@ public class Camera implements Savable, Cloneable {
}
}
/**
* This method copies the settings of the given camera.
*
* @param cam
* the camera we copy the settings from
*/
/**
* This method copies the settings of the given camera.
*
* @param cam
* the camera we copy the settings from
*/
public void copyFrom(Camera cam) {
location.set(cam.location);
location.set(cam.location);
rotation.set(cam.rotation);
frustumNear = cam.frustumNear;

@ -32,7 +32,6 @@
package com.jme3.renderer;
import com.jme3.material.RenderState;
import com.jme3.material.RenderState.BlendFunc;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
@ -49,123 +48,123 @@ public class RenderContext {
/**
* @see RenderState#setFaceCullMode(com.jme3.material.RenderState.FaceCullMode)
*/
public RenderState.FaceCullMode cullMode = RenderState.FaceCullMode.Off;
public RenderState.FaceCullMode cullMode;
/**
* @see RenderState#setDepthTest(boolean)
* @see RenderState#setDepthTest(boolean)
*/
public boolean depthTestEnabled = false;
public boolean depthTestEnabled;
/**
* @see RenderState#setDepthWrite(boolean)
* @see RenderState#setDepthWrite(boolean)
*/
public boolean depthWriteEnabled = true;
public boolean depthWriteEnabled;
/**
* @see RenderState#setColorWrite(boolean)
* @see RenderState#setColorWrite(boolean)
*/
public boolean colorWriteEnabled = true;
public boolean colorWriteEnabled;
/**
* @see Renderer#setClipRect(int, int, int, int)
* @see Renderer#setClipRect(int, int, int, int)
*/
public boolean clipRectEnabled = false;
public boolean clipRectEnabled;
/**
* @see RenderState#setPolyOffset(float, float)
* @see RenderState#setPolyOffset(float, float)
*/
public boolean polyOffsetEnabled = false;
public boolean polyOffsetEnabled;
/**
* @see RenderState#setPolyOffset(float, float)
* @see RenderState#setPolyOffset(float, float)
*/
public float polyOffsetFactor = 0;
public float polyOffsetFactor;
/**
* @see RenderState#setPolyOffset(float, float)
* @see RenderState#setPolyOffset(float, float)
*/
public float polyOffsetUnits = 0;
public float polyOffsetUnits;
/**
* @see Mesh#setPointSize(float)
* @see Mesh#setPointSize(float)
*/
public float pointSize = 1;
public float pointSize;
/**
* @see RenderState#setLineWidth(float)
*/
public float lineWidth = 1;
public float lineWidth;
/**
* @see RenderState#setBlendMode(com.jme3.material.RenderState.BlendMode)
* @see RenderState#setBlendMode(com.jme3.material.RenderState.BlendMode)
*/
public RenderState.BlendMode blendMode = RenderState.BlendMode.Off;
public RenderState.BlendMode blendMode;
/**
* @see RenderState#setBlendEquation(com.jme3.material.RenderState.BlendEquation)
* @see RenderState#setBlendEquation(com.jme3.material.RenderState.BlendEquation)
*/
public RenderState.BlendEquation blendEquation = RenderState.BlendEquation.Add;
public RenderState.BlendEquation blendEquation;
/**
* @see RenderState#setBlendEquationAlpha(com.jme3.material.RenderState.BlendEquationAlpha)
* @see RenderState#setBlendEquationAlpha(com.jme3.material.RenderState.BlendEquationAlpha)
*/
public RenderState.BlendEquationAlpha blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor;
public RenderState.BlendEquationAlpha blendEquationAlpha;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc sfactorRGB = RenderState.BlendFunc.One;
public RenderState.BlendFunc sfactorRGB;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc dfactorRGB = RenderState.BlendFunc.One;
public RenderState.BlendFunc dfactorRGB;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc sfactorAlpha = RenderState.BlendFunc.One;
public RenderState.BlendFunc sfactorAlpha;
/**
* @see RenderState#setCustomBlendFactors(com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc,
* com.jme3.material.RenderState.BlendFunc, com.jme3.material.RenderState.BlendFunc)
*/
public RenderState.BlendFunc dfactorAlpha = RenderState.BlendFunc.One;
public RenderState.BlendFunc dfactorAlpha;
/**
* @see RenderState#setWireframe(boolean)
* @see RenderState#setWireframe(boolean)
*/
public boolean wireframe = false;
public boolean wireframe;
/**
* @see Renderer#setShader(com.jme3.shader.Shader)
* @see Renderer#setShader(com.jme3.shader.Shader)
*/
public int boundShaderProgram;
/**
* @see Renderer#setShader(com.jme3.shader.Shader)
* @see Renderer#setShader(com.jme3.shader.Shader)
*/
public Shader boundShader;
/**
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*/
public int boundFBO = 0;
public int boundFBO;
/**
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*/
public FrameBuffer boundFB;
/**
* Currently bound Renderbuffer
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*/
public int boundRB = 0;
public int boundRB;
/**
* Currently bound draw buffer
@ -174,20 +173,20 @@ public class RenderContext {
* 0 = GL_COLOR_ATTACHMENT0
* n = GL_COLOR_ATTACHMENTn
* where n is an integer greater than 1
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see FrameBuffer#setTargetIndex(int)
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see FrameBuffer#setTargetIndex(int)
*/
public int boundDrawBuf = -1;
public int boundDrawBuf;
/**
* Currently bound read buffer
*
* @see RenderContext#boundDrawBuf
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see FrameBuffer#setTargetIndex(int)
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
* @see FrameBuffer#setTargetIndex(int)
*/
public int boundReadBuf = -1;
public int boundReadBuf;
/**
* Currently bound element array vertex buffer.
@ -207,118 +206,114 @@ public class RenderContext {
* @see Renderer#renderMesh(com.jme3.scene.Mesh, int, int, com.jme3.scene.VertexBuffer[])
*/
public int boundArrayVBO;
/**
* Currently bound pixel pack pixel buffer.
*/
public int boundPixelPackPBO;
public int numTexturesSet = 0;
public int numTexturesSet;
/**
* Current bound texture IDs for each texture unit.
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*/
public Image[] boundTextures = new Image[16];
public final Image[] boundTextures = new Image[16];
/**
* IDList for texture units
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*/
public IDList textureIndexList = new IDList();
public final IDList textureIndexList = new IDList();
/**
* Currently bound texture unit
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*
* @see Renderer#setTexture(int, com.jme3.texture.Texture)
*/
public int boundTextureUnit = 0;
public int boundTextureUnit;
/**
* Stencil Buffer state
*/
public boolean stencilTest = false;
public RenderState.StencilOperation frontStencilStencilFailOperation = RenderState.StencilOperation.Keep;
public RenderState.StencilOperation frontStencilDepthFailOperation = RenderState.StencilOperation.Keep;
public RenderState.StencilOperation frontStencilDepthPassOperation = RenderState.StencilOperation.Keep;
public RenderState.StencilOperation backStencilStencilFailOperation = RenderState.StencilOperation.Keep;
public RenderState.StencilOperation backStencilDepthFailOperation = RenderState.StencilOperation.Keep;
public RenderState.StencilOperation backStencilDepthPassOperation = RenderState.StencilOperation.Keep;
public RenderState.TestFunction frontStencilFunction = RenderState.TestFunction.Always;
public RenderState.TestFunction backStencilFunction = RenderState.TestFunction.Always;
public boolean stencilTest;
public RenderState.StencilOperation frontStencilStencilFailOperation;
public RenderState.StencilOperation frontStencilDepthFailOperation;
public RenderState.StencilOperation frontStencilDepthPassOperation;
public RenderState.StencilOperation backStencilStencilFailOperation;
public RenderState.StencilOperation backStencilDepthFailOperation;
public RenderState.StencilOperation backStencilDepthPassOperation;
public RenderState.TestFunction frontStencilFunction;
public RenderState.TestFunction backStencilFunction;
/**
* Vertex attribs currently bound and enabled. If a slot is null, then
* it is disabled.
*/
public VertexBuffer[] boundAttribs = new VertexBuffer[16];
public final VertexBuffer[] boundAttribs = new VertexBuffer[16];
/**
* IDList for vertex attributes
*/
public IDList attribIndexList = new IDList();
public final IDList attribIndexList = new IDList();
/**
* depth test function
*/
public RenderState.TestFunction depthFunc = RenderState.TestFunction.Less;
public RenderState.TestFunction depthFunc;
/**
* alpha test function
*/
public RenderState.TestFunction alphaFunc = RenderState.TestFunction.Greater;
public RenderState.TestFunction alphaFunc;
public int initialDrawBuf;
public int initialReadBuf;
public ColorRGBA clearColor = new ColorRGBA(0,0,0,0);
/**
* Reset the RenderContext to default GL state
*/
public void reset(){
public ColorRGBA clearColor = new ColorRGBA(0, 0, 0, 0);
public RenderContext() {
init();
}
private void init() {
cullMode = RenderState.FaceCullMode.Off;
depthTestEnabled = false;
depthWriteEnabled = false;
colorWriteEnabled = false;
depthWriteEnabled = true;
colorWriteEnabled = true;
clipRectEnabled = false;
polyOffsetEnabled = false;
polyOffsetFactor = 0;
polyOffsetUnits = 0;
pointSize = 1;
lineWidth = 1;
blendMode = RenderState.BlendMode.Off;
blendEquation = RenderState.BlendEquation.Add;
blendEquationAlpha = RenderState.BlendEquationAlpha.InheritColor;
sfactorRGB = BlendFunc.One;
dfactorRGB = BlendFunc.One;
sfactorAlpha = BlendFunc.One;
dfactorAlpha = BlendFunc.One;
sfactorRGB = RenderState.BlendFunc.One;
dfactorRGB = RenderState.BlendFunc.One;
sfactorAlpha = RenderState.BlendFunc.One;
dfactorAlpha = RenderState.BlendFunc.One;
wireframe = false;
boundShaderProgram = 0;
boundShader = null;
boundFBO = 0;
boundFB = null;
boundRB = 0;
boundDrawBuf = -1;
boundDrawBuf = -1;
boundReadBuf = -1;
boundElementArrayVBO = 0;
boundVertexArray = 0;
boundArrayVBO = 0;
boundPixelPackPBO = 0;
numTexturesSet = 0;
for (int i = 0; i < boundTextures.length; i++)
boundTextures[i] = null;
textureIndexList.reset();
boundTextureUnit = 0;
for (int i = 0; i < boundAttribs.length; i++)
boundAttribs[i] = null;
attribIndexList.reset();
stencilTest = false;
frontStencilStencilFailOperation = RenderState.StencilOperation.Keep;
frontStencilDepthFailOperation = RenderState.StencilOperation.Keep;
frontStencilDepthPassOperation = RenderState.StencilOperation.Keep;
@ -327,9 +322,30 @@ public class RenderContext {
backStencilDepthPassOperation = RenderState.StencilOperation.Keep;
frontStencilFunction = RenderState.TestFunction.Always;
backStencilFunction = RenderState.TestFunction.Always;
depthFunc = RenderState.TestFunction.LessOrEqual;
depthFunc = RenderState.TestFunction.Less;
alphaFunc = RenderState.TestFunction.Greater;
clearColor.set(0,0,0,0);
cullMode = RenderState.FaceCullMode.Off;
clearColor.set(0, 0, 0, 0);
}
/**
* Reset the RenderContext to default GL state
*/
public void reset(){
init();
for (int i = 0; i < boundTextures.length; i++) {
boundTextures[i] = null;
}
textureIndexList.reset();
for (int i = 0; i < boundAttribs.length; i++) {
boundAttribs[i] = null;
}
attribIndexList.reset();
}
}

@ -1,11 +1,66 @@
/*
* Copyright (c) 2009-2020 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.renderer.opengl;
import com.jme3.renderer.RendererException;
public abstract class GLDebug {
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* This class uses Reflection to intercept method calls to the Proxy Object ({@link #createProxy(GL, Object, Class[])}
* and extends them with the Error Checking in {@link #checkError()}.<br/>
* This means we don't have to generate a class with overrides for every possible method just to add a
* {@link #checkError()} call.<br/>
* Note that we should not call {@link #checkError()} for {@link GL#glGetError()}, it doesn't make sense.<br />
* Note that this class is general purpose and as such every class instance (every object) can be guarded as long as
* the passed gl instance is valid.<br/>
*
* @author MeFisto94
*/
public class GLDebug implements InvocationHandler {
protected Object obj;
protected GL gl;
protected Method methodGlGetError;
private GLDebug(GL gl, Object obj) throws NoSuchMethodException {
this.gl = gl;
this.obj = obj;
methodGlGetError = GL.class.getMethod("glGetError");
/* The NoSuchMethodException shouldn't be thrown, but since we're in a constructor and cannot fail safe
* otherwise, we throw it. */
}
protected String decodeError(int err) {
String errMsg;
switch (err) {
@ -46,4 +101,38 @@ public abstract class GLDebug {
throw new RendererException("An OpenGL error occurred - " + decodeError(err));
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(obj, args);
if (method.equals(methodGlGetError)) {
return result;
}
checkError();
return result;
}
/**
* Creates a debug-proxied object, which will call {@link GL#glGetError()} after every method invocation and throw
* a {@link com.jme3.renderer.RendererException} if there was a GL Error.
*
* @param gl The GL Context, required to call {@link GL#glGetError()}
* @param obj The object which methods will be proxied
* @param implementedInterfaces The interfaces/class this object implements
* @return The Proxy object (or null if an error occured)
*/
public static Object createProxy(GL gl, Object obj, Class<?>... implementedInterfaces) {
try {
return Proxy.newProxyInstance(
GLDebug.class.getClassLoader(),
implementedInterfaces,
new GLDebug(gl, obj)
);
} catch (NoSuchMethodException nsme) {
throw new IllegalArgumentException ("Could not initialize the proxy because the glGetError method wasn't " +
"found!", nsme);
}
}
}

@ -1,134 +0,0 @@
package com.jme3.renderer.opengl;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 {
private final GL2 gl2;
private final GL3 gl3;
private final GL4 gl4;
public GLDebugDesktop(GL gl, GLExt glext, GLFbo glfbo) {
super(gl, glext, glfbo);
this.gl2 = gl instanceof GL2 ? (GL2) gl : null;
this.gl3 = gl instanceof GL3 ? (GL3) gl : null;
this.gl4 = gl instanceof GL4 ? (GL4) gl : null;
}
public void glAlphaFunc(int func, float ref) {
gl2.glAlphaFunc(func, ref);
checkError();
}
public void glPointSize(float size) {
gl2.glPointSize(size);
checkError();
}
public void glPolygonMode(int face, int mode) {
gl2.glPolygonMode(face, mode);
checkError();
}
public void glDrawBuffer(int mode) {
gl2.glDrawBuffer(mode);
checkError();
}
public void glReadBuffer(int mode) {
gl2.glReadBuffer(mode);
checkError();
}
public void glCompressedTexImage3D(int target, int level, int internalformat, int width, int height, int depth, int border, ByteBuffer data) {
gl2.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, data);
checkError();
}
public void glCompressedTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, ByteBuffer data) {
gl2.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, data);
checkError();
}
public void glTexImage3D(int target, int level, int internalFormat, int width, int height, int depth, int border, int format, int type, ByteBuffer data) {
gl2.glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
checkError();
}
public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, ByteBuffer data) {
gl2.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
checkError();
}
public void glBindFragDataLocation(int param1, int param2, String param3) {
gl3.glBindFragDataLocation(param1, param2, param3);
checkError();
}
public void glBindVertexArray(int param1) {
gl3.glBindVertexArray(param1);
checkError();
}
public void glGenVertexArrays(IntBuffer param1) {
gl3.glGenVertexArrays(param1);
checkError();
}
@Override
public String glGetString(int param1, int param2) {
String result = gl3.glGetString(param1, param2);
checkError();
return result;
}
@Override
public int glGetUniformBlockIndex(final int program, final String uniformBlockName) {
final int result = gl3.glGetUniformBlockIndex(program, uniformBlockName);
checkError();
return result;
}
@Override
public void glBindBufferBase(final int target, final int index, final int buffer) {
gl3.glBindBufferBase(target, index, buffer);
checkError();
}
@Override
public void glDeleteVertexArrays(IntBuffer arrays) {
gl3.glDeleteVertexArrays(arrays);
checkError();
}
@Override
public void glPatchParameter(int count) {
gl4.glPatchParameter(count);
checkError();
}
@Override
public int glGetProgramResourceIndex(int program, int programInterface, String name) {
final int result = gl4.glGetProgramResourceIndex(program, programInterface, name);
checkError();
return result;
}
@Override
public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding) {
gl4.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
checkError();
}
public void glBlendEquationSeparate(int colorMode, int alphaMode) {
gl.glBlendEquationSeparate(colorMode, alphaMode);
checkError();
}
@Override
public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) {
gl3.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
checkError();
}
}

@ -1,662 +0,0 @@
package com.jme3.renderer.opengl;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class GLDebugES extends GLDebug implements GL, GL2, GLES_30, GLFbo, GLExt {
private final GLFbo glfbo;
private final GLExt glext;
public GLDebugES(GL gl, GLExt glext, GLFbo glfbo) {
this.gl = gl;
this.glext = glext;
this.glfbo = glfbo;
}
public void resetStats() {
gl.resetStats();
}
public void glActiveTexture(int texture) {
gl.glActiveTexture(texture);
checkError();
}
public void glAttachShader(int program, int shader) {
gl.glAttachShader(program, shader);
checkError();
}
@Override
public void glBeginQuery(int target, int query) {
gl.glBeginQuery(target, query);
checkError();
}
public void glBindBuffer(int target, int buffer) {
gl.glBindBuffer(target, buffer);
checkError();
}
public void glBindTexture(int target, int texture) {
gl.glBindTexture(target, texture);
checkError();
}
public void glBlendFunc(int sfactor, int dfactor) {
gl.glBlendFunc(sfactor, dfactor);
checkError();
}
public void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dFactorAlpha)
{
gl.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dFactorAlpha);
checkError();
}
public void glBufferData(int target, FloatBuffer data, int usage) {
gl.glBufferData(target, data, usage);
checkError();
}
public void glBufferData(int target, ShortBuffer data, int usage) {
gl.glBufferData(target, data, usage);
checkError();
}
public void glBufferData(int target, ByteBuffer data, int usage) {
gl.glBufferData(target, data, usage);
checkError();
}
public void glBufferSubData(int target, long offset, FloatBuffer data) {
gl.glBufferSubData(target, offset, data);
checkError();
}
public void glBufferSubData(int target, long offset, ShortBuffer data) {
gl.glBufferSubData(target, offset, data);
checkError();
}
public void glBufferSubData(int target, long offset, ByteBuffer data) {
gl.glBufferSubData(target, offset, data);
checkError();
}
public void glClear(int mask) {
gl.glClear(mask);
checkError();
}
public void glClearColor(float red, float green, float blue, float alpha) {
gl.glClearColor(red, green, blue, alpha);
checkError();
}
public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
gl.glColorMask(red, green, blue, alpha);
checkError();
}
public void glCompileShader(int shader) {
gl.glCompileShader(shader);
checkError();
}
public void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, ByteBuffer data) {
gl.glCompressedTexImage2D(target, level, internalformat, width, height, border, data);
checkError();
}
public void glCompressedTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, ByteBuffer data) {
gl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data);
checkError();
}
public int glCreateProgram() {
int program = gl.glCreateProgram();
checkError();
return program;
}
public int glCreateShader(int shaderType) {
int shader = gl.glCreateShader(shaderType);
checkError();
return shader;
}
public void glCullFace(int mode) {
gl.glCullFace(mode);
checkError();
}
public void glDeleteBuffers(IntBuffer buffers) {
gl.glDeleteBuffers(buffers);
checkError();
}
public void glDeleteProgram(int program) {
gl.glDeleteProgram(program);
checkError();
}
public void glDeleteShader(int shader) {
gl.glDeleteShader(shader);
checkError();
}
public void glDeleteTextures(IntBuffer textures) {
gl.glDeleteTextures(textures);
checkError();
}
public void glDepthFunc(int func) {
gl.glDepthFunc(func);
checkError();
}
public void glDepthMask(boolean flag) {
gl.glDepthMask(flag);
checkError();
}
public void glDepthRange(double nearVal, double farVal) {
gl.glDepthRange(nearVal, farVal);
checkError();
}
public void glDetachShader(int program, int shader) {
gl.glDetachShader(program, shader);
checkError();
}
public void glDisable(int cap) {
gl.glDisable(cap);
checkError();
}
public void glDisableVertexAttribArray(int index) {
gl.glDisableVertexAttribArray(index);
checkError();
}
public void glDrawArrays(int mode, int first, int count) {
gl.glDrawArrays(mode, first, count);
checkError();
}
public void glDrawRangeElements(int mode, int start, int end, int count, int type, long indices) {
gl.glDrawRangeElements(mode, start, end, count, type, indices);
checkError();
}
public void glEnable(int cap) {
gl.glEnable(cap);
checkError();
}
public void glEnableVertexAttribArray(int index) {
gl.glEnableVertexAttribArray(index);
checkError();
}
@Override
public void glEndQuery(int target) {
checkError();
}
public void glGenBuffers(IntBuffer buffers) {
gl.glGenBuffers(buffers);
checkError();
}
public void glGenTextures(IntBuffer textures) {
gl.glGenTextures(textures);
checkError();
}
@Override
public void glGenQueries(int num, IntBuffer ids) {
glGenQueries(num, ids);
checkError();
}
public int glGetAttribLocation(int program, String name) {
int location = gl.glGetAttribLocation(program, name);
checkError();
return location;
}
public void glGetBoolean(int pname, ByteBuffer params) {
gl.glGetBoolean(pname, params);
checkError();
}
public int glGetError() {
// No need to check for error here? Haha
return gl.glGetError();
}
public void glGetInteger(int pname, IntBuffer params) {
gl.glGetInteger(pname, params);
checkError();
}
public void glGetProgram(int program, int pname, IntBuffer params) {
gl.glGetProgram(program, pname, params);
checkError();
}
public String glGetProgramInfoLog(int program, int maxSize) {
String infoLog = gl.glGetProgramInfoLog(program, maxSize);
checkError();
return infoLog;
}
@Override
public long glGetQueryObjectui64(int query, int pname) {
long res = gl.glGetQueryObjectui64(query, pname);
checkError();
return res;
}
@Override
public int glGetQueryObjectiv(int query, int pname) {
int res = gl.glGetQueryObjectiv(query, pname);
checkError();
return res;
}
public void glGetShader(int shader, int pname, IntBuffer params) {
gl.glGetShader(shader, pname, params);
checkError();
}
public String glGetShaderInfoLog(int shader, int maxSize) {
String infoLog = gl.glGetShaderInfoLog(shader, maxSize);
checkError();
return infoLog;
}
public String glGetString(int name) {
String string = gl.glGetString(name);
checkError();
return string;
}
public int glGetUniformLocation(int program, String name) {
int location = gl.glGetUniformLocation(program, name);
checkError();
return location;
}
public boolean glIsEnabled(int cap) {
boolean enabled = gl.glIsEnabled(cap);
checkError();
return enabled;
}
public void glLineWidth(float width) {
gl.glLineWidth(width);
checkError();
}
public void glLinkProgram(int program) {
gl.glLinkProgram(program);
checkError();
}
public void glPixelStorei(int pname, int param) {
gl.glPixelStorei(pname, param);
checkError();
}
public void glPolygonOffset(float factor, float units) {
gl.glPolygonOffset(factor, units);
checkError();
}
public void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data) {
gl.glReadPixels(x, y, width, height, format, type, data);
checkError();
}
public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset) {
gl.glReadPixels(x, y, width, height, format, type, offset);
checkError();
}
public void glScissor(int x, int y, int width, int height) {
gl.glScissor(x, y, width, height);
checkError();
}
public void glShaderSource(int shader, String[] string, IntBuffer length) {
gl.glShaderSource(shader, string, length);
checkError();
}
public void glStencilFuncSeparate(int face, int func, int ref, int mask) {
gl.glStencilFuncSeparate(face, func, ref, mask);
checkError();
}
public void glStencilOpSeparate(int face, int sfail, int dpfail, int dppass) {
gl.glStencilOpSeparate(face, sfail, dpfail, dppass);
checkError();
}
public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, ByteBuffer data) {
gl.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
checkError();
}
public void glTexParameterf(int target, int pname, float param) {
gl.glTexParameterf(target, pname, param);
checkError();
}
public void glTexParameteri(int target, int pname, int param) {
gl.glTexParameteri(target, pname, param);
checkError();
}
public void glTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, ByteBuffer data) {
gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
checkError();
}
public void glUniform1(int location, FloatBuffer value) {
gl.glUniform1(location, value);
checkError();
}
public void glUniform1(int location, IntBuffer value) {
gl.glUniform1(location, value);
checkError();
}
public void glUniform1f(int location, float v0) {
gl.glUniform1f(location, v0);
checkError();
}
public void glUniform1i(int location, int v0) {
gl.glUniform1i(location, v0);
checkError();
}
public void glUniform2(int location, IntBuffer value) {
gl.glUniform2(location, value);
checkError();
}
public void glUniform2(int location, FloatBuffer value) {
gl.glUniform2(location, value);
checkError();
}
public void glUniform2f(int location, float v0, float v1) {
gl.glUniform2f(location, v0, v1);
checkError();
}
public void glUniform3(int location, IntBuffer value) {
gl.glUniform3(location, value);
checkError();
}
public void glUniform3(int location, FloatBuffer value) {
gl.glUniform3(location, value);
checkError();
}
public void glUniform3f(int location, float v0, float v1, float v2) {
gl.glUniform3f(location, v0, v1, v2);
checkError();
}
public void glUniform4(int location, FloatBuffer value) {
gl.glUniform4(location, value);
checkError();
}
public void glUniform4(int location, IntBuffer value) {
gl.glUniform4(location, value);
checkError();
}
public void glUniform4f(int location, float v0, float v1, float v2, float v3) {
gl.glUniform4f(location, v0, v1, v2, v3);
checkError();
}
public void glUniformMatrix3(int location, boolean transpose, FloatBuffer value) {
gl.glUniformMatrix3(location, transpose, value);
checkError();
}
public void glUniformMatrix4(int location, boolean transpose, FloatBuffer value) {
gl.glUniformMatrix4(location, transpose, value);
checkError();
}
public void glUseProgram(int program) {
gl.glUseProgram(program);
checkError();
}
public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) {
gl.glVertexAttribPointer(index, size, type, normalized, stride, pointer);
checkError();
}
public void glViewport(int x, int y, int width, int height) {
gl.glViewport(x, y, width, height);
checkError();
}
public void glBindFramebufferEXT(int param1, int param2) {
glfbo.glBindFramebufferEXT(param1, param2);
checkError();
}
public void glBindRenderbufferEXT(int param1, int param2) {
glfbo.glBindRenderbufferEXT(param1, param2);
checkError();
}
public int glCheckFramebufferStatusEXT(int param1) {
int result = glfbo.glCheckFramebufferStatusEXT(param1);
checkError();
return result;
}
public void glDeleteFramebuffersEXT(IntBuffer param1) {
glfbo.glDeleteFramebuffersEXT(param1);
checkError();
}
public void glDeleteRenderbuffersEXT(IntBuffer param1) {
glfbo.glDeleteRenderbuffersEXT(param1);
checkError();
}
public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
glfbo.glFramebufferRenderbufferEXT(param1, param2, param3, param4);
checkError();
}
public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
glfbo.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5);
checkError();
}
public void glGenFramebuffersEXT(IntBuffer param1) {
glfbo.glGenFramebuffersEXT(param1);
checkError();
}
public void glGenRenderbuffersEXT(IntBuffer param1) {
glfbo.glGenRenderbuffersEXT(param1);
checkError();
}
public void glGenerateMipmapEXT(int param1) {
glfbo.glGenerateMipmapEXT(param1);
checkError();
}
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
glfbo.glRenderbufferStorageEXT(param1, param2, param3, param4);
checkError();
}
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
glfbo.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
checkError();
}
@Override
public void glBufferData(int target, long data_size, int usage) {
gl.glBufferData(target, data_size, usage);
checkError();
}
@Override
public void glGetBufferSubData(int target, long offset, ByteBuffer data) {
gl.glGetBufferSubData(target, offset, data);
checkError();
}
public void glBufferData(int target, IntBuffer data, int usage) {
glext.glBufferData(target, data, usage);
checkError();
}
public void glBufferSubData(int target, long offset, IntBuffer data) {
glext.glBufferSubData(target, offset, data);
checkError();
}
public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) {
glext.glDrawArraysInstancedARB(mode, first, count, primcount);
checkError();
}
public void glDrawBuffers(IntBuffer bufs) {
glext.glDrawBuffers(bufs);
checkError();
}
public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) {
glext.glDrawElementsInstancedARB(mode, indices_count, type, indices_buffer_offset, primcount);
checkError();
}
public void glGetMultisample(int pname, int index, FloatBuffer val) {
glext.glGetMultisample(pname, index, val);
checkError();
}
public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
glfbo.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
checkError();
}
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) {
glext.glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
checkError();
}
public void glVertexAttribDivisorARB(int index, int divisor) {
glext.glVertexAttribDivisorARB(index, divisor);
checkError();
}
@Override
public int glClientWaitSync(Object sync, int flags, long timeout) {
int result = glext.glClientWaitSync(sync, flags, timeout);
checkError();
return result;
}
@Override
public void glDeleteSync(Object sync) {
glext.glDeleteSync(sync);
checkError();
}
@Override
public Object glFenceSync(int condition, int flags) {
Object sync = glext.glFenceSync(condition, flags);
checkError();
return sync;
}
@Override
public void glBlendEquationSeparate(int colorMode, int alphaMode) {
gl.glBlendEquationSeparate(colorMode, alphaMode);
checkError();
}
@Override
public void glFramebufferTextureLayerEXT(int param1, int param2, int param3, int param4, int param5) {
glfbo.glFramebufferTextureLayerEXT(param1, param2, param3, param4, param5);
checkError();
}
public void glAlphaFunc(int func, float ref) {
((GL2)gl).glAlphaFunc(func, ref);
checkError();
}
public void glPointSize(float size) {
((GL2)gl).glPointSize(size);
checkError();
}
public void glPolygonMode(int face, int mode) {
((GL2)gl).glPolygonMode(face, mode);
checkError();
}
public void glDrawBuffer(int mode) {
((GL2)gl).glDrawBuffer(mode);
checkError();
}
public void glReadBuffer(int mode) {
((GL2)gl).glReadBuffer(mode);
checkError();
}
public void glCompressedTexImage3D(int target, int level, int internalFormat, int width, int height, int depth,
int border, ByteBuffer data) {
((GL2)gl).glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, data);
checkError();
}
public void glCompressedTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width,
int height, int depth, int format, ByteBuffer data) {
((GL2)gl).glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, data);
checkError();
}
public void glTexImage3D(int target, int level, int internalFormat, int width, int height, int depth, int border,
int format, int type, ByteBuffer data) {
((GL2)gl).glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
checkError();
}
public void glTexSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height,
int depth, int format, int type, ByteBuffer data) {
((GL2)gl).glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
checkError();
}
}

@ -502,33 +502,42 @@ public final class GLRenderer implements Renderer {
}
}
if (hasExtension("GL_OES_geometry_shader") || hasExtension("GL_EXT_geometry_shader")) {
caps.add(Caps.GeometryShader);
}
if (hasExtension("GL_OES_tessellation_shader") || hasExtension("GL_EXT_tessellation_shader")) {
caps.add(Caps.TesselationShader);
}
if (hasExtension("GL_ARB_shader_storage_buffer_object")) {
caps.add(Caps.ShaderStorageBufferObject);
limits.put(Limits.ShaderStorageBufferObjectMaxBlockSize, getInteger(GL4.GL_MAX_SHADER_STORAGE_BLOCK_SIZE));
limits.put(Limits.ShaderStorageBufferObjectMaxComputeBlocks, getInteger(GL4.GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS));
limits.put(Limits.ShaderStorageBufferObjectMaxGeometryBlocks, getInteger(GL4.GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS));
// Commented out until we support ComputeShaders and the ComputeShader Cap
// limits.put(Limits.ShaderStorageBufferObjectMaxComputeBlocks, getInteger(GL4.GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS));
if (caps.contains(Caps.GeometryShader)) {
limits.put(Limits.ShaderStorageBufferObjectMaxGeometryBlocks, getInteger(GL4.GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS));
}
limits.put(Limits.ShaderStorageBufferObjectMaxFragmentBlocks, getInteger(GL4.GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS));
limits.put(Limits.ShaderStorageBufferObjectMaxVertexBlocks, getInteger(GL4.GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS));
limits.put(Limits.ShaderStorageBufferObjectMaxTessControlBlocks, getInteger(GL4.GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS));
limits.put(Limits.ShaderStorageBufferObjectMaxTessEvaluationBlocks, getInteger(GL4.GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS));
if (caps.contains(Caps.TesselationShader)) {
limits.put(Limits.ShaderStorageBufferObjectMaxTessControlBlocks, getInteger(GL4.GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS));
limits.put(Limits.ShaderStorageBufferObjectMaxTessEvaluationBlocks, getInteger(GL4.GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS));
}
limits.put(Limits.ShaderStorageBufferObjectMaxCombineBlocks, getInteger(GL4.GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS));
}
if (hasExtension("GL_ARB_uniform_buffer_object")) {
caps.add(Caps.UniformBufferObject);
limits.put(Limits.UniformBufferObjectMaxBlockSize, getInteger(GL3.GL_MAX_UNIFORM_BLOCK_SIZE));
limits.put(Limits.UniformBufferObjectMaxGeometryBlocks, getInteger(GL3.GL_MAX_GEOMETRY_UNIFORM_BLOCKS));
if (caps.contains(Caps.GeometryShader)) {
limits.put(Limits.UniformBufferObjectMaxGeometryBlocks, getInteger(GL3.GL_MAX_GEOMETRY_UNIFORM_BLOCKS));
}
limits.put(Limits.UniformBufferObjectMaxFragmentBlocks, getInteger(GL3.GL_MAX_FRAGMENT_UNIFORM_BLOCKS));
limits.put(Limits.UniformBufferObjectMaxVertexBlocks, getInteger(GL3.GL_MAX_VERTEX_UNIFORM_BLOCKS));
}
if (hasExtension("GL_OES_geometry_shader") || hasExtension("GL_EXT_geometry_shader")) {
caps.add(Caps.GeometryShader);
}
if (hasExtension("GL_OES_tessellation_shader") || hasExtension("GL_EXT_tessellation_shader")) {
caps.add(Caps.TesselationShader);
}
if(caps.contains(Caps.OpenGL20)){
caps.add(Caps.UnpackRowLength);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2014 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -71,7 +71,7 @@ public final class GLTracer implements InvocationHandler {
private static void noEnumArgs(String method, int... argSlots) {
IntMap<Void> argSlotsMap = new IntMap<Void>();
for (int argSlot : argSlots) {
argSlotsMap.put(argSlot, (Void) null);
argSlotsMap.put(argSlot, null);
}
nonEnumArgMap.put(method, argSlotsMap);
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -167,7 +167,7 @@ public class AssetLinkNode extends Node {
final InputCapsule capsule = e.getCapsule(this);
final AssetManager assetManager = e.getAssetManager();
assetLoaderKeys = (ArrayList<ModelKey>) capsule.readSavableArrayList("assetLoaderKeyList", new ArrayList<ModelKey>());
assetLoaderKeys = capsule.readSavableArrayList("assetLoaderKeyList", new ArrayList<>());
for (final Iterator<ModelKey> iterator = assetLoaderKeys.iterator(); iterator.hasNext(); ) {

@ -1527,7 +1527,11 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
}
public MorphTarget[] getMorphTargets() {
return morphTargets.getArray();
if (morphTargets == null) {
return new MorphTarget[0];
} else {
return morphTargets.getArray();
}
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2017 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -109,7 +109,7 @@ public class WireSphere extends Mesh {
/*
* Update vertex positions for the great circle in the X-Y plane.
*/
float rate = FastMath.TWO_PI / (float) samples;
float rate = FastMath.TWO_PI / samples;
float angle = 0;
for (int i = 0; i < samples; i++) {
float x = radius * FastMath.cos(angle);
@ -130,7 +130,7 @@ public class WireSphere extends Mesh {
/*
* Update vertex positions for 'zSamples' parallel circles.
*/
float zRate = (radius * 2) / (float) (zSamples);
float zRate = (radius * 2) / zSamples;
float zHeight = -radius + (zRate / 2f);
float rb = 1f / zSamples;
float b = rb / 2f;

@ -1,7 +1,7 @@
package com.jme3.scene.debug.custom;
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -134,12 +134,12 @@ public class ArmatureDebugger extends Node {
Material matWires = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matWires.setBoolean("VertexColor", true);
matWires.getAdditionalRenderState().setLineWidth(3);
matWires.getAdditionalRenderState().setLineWidth(1f);
wires.setMaterial(matWires);
Material matOutline = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matOutline.setBoolean("VertexColor", true);
matOutline.getAdditionalRenderState().setLineWidth(5);
matOutline.getAdditionalRenderState().setLineWidth(1f);
outlines.setMaterial(matOutline);
Material matOutline2 = new Material(assetManager, "Common/MatDefs/Misc/DashedLine.j3md");

@ -161,7 +161,7 @@ public abstract class IndexBuffer {
* mesh.setBuffer(Type.Index, 3,
* indexBuffer.getFormat(), indexBuffer);
* </pre>
* @return
* @return an enum value
*/
public abstract Format getFormat();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -49,7 +49,7 @@ import java.nio.Buffer;
* <li>{@link Mode#TriangleStrip}: 0, 1, 2 | 2, 1, 3 | 2, 3, 4 | ...</li>
* <li>{@link Mode#TriangleFan}: 0, 1, 2 | 0, 2, 3 | 0, 3, 4 | ...</li>
* </ul>
*
*
* @author Kirill Vainer
*/
public class VirtualIndexBuffer extends IndexBuffer {
@ -58,8 +58,8 @@ public class VirtualIndexBuffer extends IndexBuffer {
protected int numIndices = 0;
protected Mode meshMode;
protected int position = 0;
public VirtualIndexBuffer(int numVerts, Mode meshMode){
public VirtualIndexBuffer(int numVerts, Mode meshMode) {
this.numVerts = numVerts;
this.meshMode = meshMode;
switch (meshMode) {
@ -108,33 +108,38 @@ public class VirtualIndexBuffer extends IndexBuffer {
@Override
public int get(int i) {
if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points){
if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points) {
return i;
}else if (meshMode == Mode.LineStrip){
} else if (meshMode == Mode.LineStrip) {
return (i + 1) / 2;
}else if (meshMode == Mode.LineLoop){
return (i == (numVerts-1)) ? 0 : ((i + 1) / 2);
}else if (meshMode == Mode.TriangleStrip){
int triIndex = i/3;
int vertIndex = i%3;
boolean isBack = (i/3)%2==1;
if (!isBack){
} else if (meshMode == Mode.LineLoop) {
return (i == (numVerts - 1)) ? 0 : ((i + 1) / 2);
} else if (meshMode == Mode.TriangleStrip) {
int triIndex = i / 3;
int vertIndex = i % 3;
boolean isBack = (i / 3) % 2 == 1;
if (!isBack) {
return triIndex + vertIndex;
}else{
switch (vertIndex){
case 0: return triIndex + 1;
case 1: return triIndex;
case 2: return triIndex + 2;
default: throw new AssertionError();
}
} else {
switch (vertIndex) {
case 0:
return triIndex + 1;
case 1:
return triIndex;
case 2:
return triIndex + 2;
default:
throw new AssertionError();
}
}
}else if (meshMode == Mode.TriangleFan){
int vertIndex = i%3;
if (vertIndex == 0)
} else if (meshMode == Mode.TriangleFan) {
int vertIndex = i % 3;
if (vertIndex == 0) {
return 0;
else
} else {
return (i / 3) + vertIndex;
}else{
}
} else {
throw new UnsupportedOperationException();
}
}
@ -154,15 +159,15 @@ public class VirtualIndexBuffer extends IndexBuffer {
return null;
}
@Override
public IndexBuffer put (int value) {
throw new UnsupportedOperationException("Does not represent index buffer");
}
@Override
public IndexBuffer put(int value) {
throw new UnsupportedOperationException("Does not represent index buffer");
}
@Override
public Format getFormat () {
// return largest size
return Format.UnsignedInt;
}
@Override
public Format getFormat() {
// return largest size
return Format.UnsignedInt;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -198,12 +198,12 @@ public class Curve extends Mesh {
* points
*/
private void createNurbMesh(int nbSubSegments) {
if(spline.getControlPoints() != null && spline.getControlPoints().size() > 0) {
if(nbSubSegments == 0) {
nbSubSegments = spline.getControlPoints().size() + 1;
} else {
nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1;
}
if (spline.getControlPoints() != null && spline.getControlPoints().size() > 0) {
if (nbSubSegments == 0) {
nbSubSegments = spline.getControlPoints().size() + 1;
} else {
nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1;
}
float minKnot = spline.getMinNurbKnot();
float maxKnot = spline.getMaxNurbKnot();
float deltaU = (maxKnot - minKnot) / nbSubSegments;
@ -233,7 +233,7 @@ public class Curve extends Mesh {
this.setBuffer(VertexBuffer.Type.Index, 2, indices);
this.updateBound();
this.updateCounts();
}
}
}
private void createLinearMesh() {

@ -55,7 +55,7 @@ public class Line extends Mesh {
/**
* No-argument constructor needed by SavableClassUtil.
*/
public Line() { // TODO protected
protected Line() {
}
public Line(Vector3f start, Vector3f end) {
@ -69,7 +69,6 @@ public class Line extends Mesh {
setBuffer(Type.Position, 3, new float[]{start.x, start.y, start.z,
end.x, end.y, end.z,});
setBuffer(Type.TexCoord, 2, new float[]{0, 0,
1, 1});

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -141,7 +141,7 @@ public class PQTorus extends Mesh {
// Move along the length of the pq torus
for (int i = 0; i < steps; i++) {
theta += thetaStep;
float circleFraction = ((float) i) / (float) steps;
float circleFraction = i / (float) steps;
// Find the point on the torus
r = (0.5f * (2.0f + FastMath.sin(q * theta)) * radius);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -199,8 +199,8 @@ public class ShaderNode implements Savable, Cloneable {
name = ic.readString("name", "");
definition = (ShaderNodeDefinition) ic.readSavable("definition", null);
condition = ic.readString("condition", null);
inputMapping = (List<VariableMapping>) ic.readSavableArrayList("inputMapping", new ArrayList<VariableMapping>());
outputMapping = (List<VariableMapping>) ic.readSavableArrayList("outputMapping", new ArrayList<VariableMapping>());
inputMapping = ic.readSavableArrayList("inputMapping", new ArrayList<>());
outputMapping = ic.readSavableArrayList("outputMapping", new ArrayList<>());
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -194,7 +194,7 @@ public class ShaderNodeDefinition implements Savable {
*/
@Override
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this);
OutputCapsule oc = ex.getCapsule(this);
oc.write(name, "name", "");
String[] str = new String[shadersLanguage.size()];
oc.write(shadersLanguage.toArray(str), "shadersLanguage", null);
@ -230,7 +230,7 @@ public class ShaderNodeDefinition implements Savable {
*/
@Override
public void read(JmeImporter im) throws IOException {
InputCapsule ic = (InputCapsule) im.getCapsule(this);
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", "");
String[] str = ic.readStringArray("shadersLanguage", null);
@ -248,8 +248,8 @@ public class ShaderNodeDefinition implements Savable {
}
type = ic.readEnum("type", Shader.ShaderType.class, null);
inputs = (List<ShaderNodeVariable>) ic.readSavableArrayList("inputs", new ArrayList<ShaderNodeVariable>());
outputs = (List<ShaderNodeVariable>) ic.readSavableArrayList("outputs", new ArrayList<ShaderNodeVariable>());
inputs = ic.readSavableArrayList("inputs", new ArrayList<>());
outputs = ic.readSavableArrayList("outputs", new ArrayList<>());
}
/**

@ -92,7 +92,7 @@ public class BasicShadowRenderer implements SceneProcessor {
//DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
dummyTex = new Texture2D(size, size, Format.RGBA8);
shadowFB.setColorTexture(dummyTex);
shadowMapSize = (float)size;
shadowMapSize = size;
preshadowMat = new Material(manager, "Common/MatDefs/Shadow/PreShadow.j3md");
postshadowMat = new Material(manager, "Common/MatDefs/Shadow/BasicPostShadow.j3md");
postshadowMat.setTexture("ShadowMap", shadowMap);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -725,7 +725,7 @@ public class ShadowUtil {
*/
public static void getLitGeometriesInViewPort(Spatial rootScene, Camera vpCamera, Camera[] cameras, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) {
if (rootScene != null && rootScene instanceof Node) {
addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, (Node)rootScene, mode, outputGeometryList);
addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, rootScene, mode, outputGeometryList);
}
}
/**

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -404,16 +404,16 @@ public final class AppSettings extends HashMap<String, Object> {
// Try loading using new method
switch (key.charAt(0)) {
case 'I':
put(key.substring(2), prefs.getInt(key, (Integer) 0));
put(key.substring(2), prefs.getInt(key, 0));
break;
case 'F':
put(key.substring(2), prefs.getFloat(key, (Float) 0f));
put(key.substring(2), prefs.getFloat(key, 0f));
break;
case 'S':
put(key.substring(2), prefs.get(key, (String) null));
put(key.substring(2), prefs.get(key, null));
break;
case 'B':
put(key.substring(2), prefs.getBoolean(key, (Boolean) false));
put(key.substring(2), prefs.getBoolean(key, false));
break;
default:
throw new UnsupportedOperationException("Undefined setting type: " + key.charAt(0));

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* Copyright (c) 2009-2020 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -171,7 +171,7 @@ public abstract class JmeSystemDelegate {
return is64 ? Platform.Windows64 : Platform.Windows32;
} else if (os.contains("linux") || os.contains("freebsd")
|| os.contains("sunos") || os.contains("unix")) {
if (arch.startsWith("arm")) {
if (arch.startsWith("arm") || arch.startsWith("aarch")) {
return is64 ? Platform.Linux_ARM64 : Platform.Linux_ARM32;
} else {
return is64 ? Platform.Linux64 : Platform.Linux32;

@ -41,38 +41,38 @@ import java.util.ArrayList;
* <p>
* <code>FrameBuffer</code>s are rendering surfaces allowing
* off-screen rendering and render-to-texture functionality.
* Instead of the scene rendering to the screen, it is rendered into the
* Instead of the scene rendering to the screen, it is rendered into the
* FrameBuffer, the result can be either a texture or a buffer.
* <p>
* A <code>FrameBuffer</code> supports two methods of rendering,
* using a {@link Texture} or using a buffer.
* A <code>FrameBuffer</code> supports two methods of rendering,
* using a {@link Texture} or using a buffer.
* When using a texture, the result of the rendering will be rendered
* onto the texture, after which the texture can be placed on an object
* and rendered as if the texture was uploaded from disk.
* When using a buffer, the result is rendered onto
* When using a buffer, the result is rendered onto
* a buffer located on the GPU, the data of this buffer is not accessible
* to the user. buffers are useful if one
* wishes to retrieve only the color content of the scene, but still desires
* depth testing (which requires a depth buffer).
* depth testing (which requires a depth buffer).
* Buffers can be copied to other framebuffers
* including the main screen, by using
* including the main screen, by using
* {@link Renderer#copyFrameBuffer(com.jme3.texture.FrameBuffer, com.jme3.texture.FrameBuffer, boolean)}.
* The content of a {@link RenderBuffer} can be retrieved by using
* The content of a {@link RenderBuffer} can be retrieved by using
* {@link Renderer#readFrameBuffer(com.jme3.texture.FrameBuffer, java.nio.ByteBuffer) }.
* <p>
* <code>FrameBuffer</code>s have several attachment points, there are
* several <em>color</em> attachment points and a single <em>depth</em>
* <code>FrameBuffer</code>s have several attachment points, there are
* several <em>color</em> attachment points and a single <em>depth</em>
* attachment point.
* The color attachment points support image formats such as
* {@link Format#RGBA8}, allowing rendering the color content of the scene.
* The depth attachment point requires a depth image format.
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*
* The depth attachment point requires a depth image format.
*
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
*
* @author Kirill Vainer
*/
public class FrameBuffer extends NativeObject {
public static final int SLOT_UNDEF = -1;
public static final int SLOT_DEPTH = -100;
public static final int SLOT_DEPTH_STENCIL = -101;
@ -86,7 +86,7 @@ public class FrameBuffer extends NativeObject {
private boolean srgb;
/**
* <code>RenderBuffer</code> represents either a texture or a
* <code>RenderBuffer</code> represents either a texture or a
* buffer that will be rendered to. <code>RenderBuffer</code>s
* are attached to an attachment slot on a <code>FrameBuffer</code>.
*/
@ -98,7 +98,7 @@ public class FrameBuffer extends NativeObject {
int slot = SLOT_UNDEF;
int face = -1;
int layer = -1;
/**
* @return The image format of the render buffer.
*/
@ -110,7 +110,7 @@ public class FrameBuffer extends NativeObject {
* @return The texture to render to for this <code>RenderBuffer</code>
* or null if content should be rendered into a buffer.
*/
public Texture getTexture(){
public Texture getTexture() {
return tex;
}
@ -124,7 +124,7 @@ public class FrameBuffer extends NativeObject {
/**
* Do not use.
*/
public void setId(int id){
public void setId(int id) {
this.id = id;
}
@ -134,30 +134,30 @@ public class FrameBuffer extends NativeObject {
public int getSlot() {
return slot;
}
public int getFace() {
return face;
}
public void resetObject(){
public void resetObject() {
id = -1;
}
public RenderBuffer createDestructableClone(){
if (tex != null){
public RenderBuffer createDestructableClone() {
if (tex != null) {
return null;
}else{
RenderBuffer destructClone = new RenderBuffer();
} else {
RenderBuffer destructClone = new RenderBuffer();
destructClone.id = id;
return destructClone;
}
}
@Override
public String toString(){
if (tex != null){
public String toString() {
if (tex != null) {
return "TextureTarget[format=" + format + "]";
}else{
} else {
return "BufferTarget[format=" + format + "]";
}
}
@ -173,28 +173,29 @@ public class FrameBuffer extends NativeObject {
* of samples. If any textures are attached to this FrameBuffer, then
* they must have the same number of samples as given in this constructor.
* <p>
* Note that if the {@link Renderer} does not expose the
* Note that if the {@link Renderer} does not expose the
* {@link Caps#NonPowerOfTwoTextures}, then an exception will be thrown
* if the width and height arguments are not power of two.
*
*
* @param width The width to use
* @param height The height to use
* @param samples The number of samples to use for a multisampled
* framebuffer, or 1 if the framebuffer should be singlesampled.
*
*
* @throws IllegalArgumentException If width or height are not positive.
*/
public FrameBuffer(int width, int height, int samples){
public FrameBuffer(int width, int height, int samples) {
super();
if (width <= 0 || height <= 0)
throw new IllegalArgumentException("FrameBuffer must have valid size.");
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("FrameBuffer must have valid size.");
}
this.width = width;
this.height = height;
this.samples = samples == 0 ? 1 : samples;
}
protected FrameBuffer(FrameBuffer src){
protected FrameBuffer(FrameBuffer src) {
super(src.id);
/*
for (RenderBuffer renderBuf : src.colorBufs){
@ -209,60 +210,68 @@ public class FrameBuffer extends NativeObject {
/**
* Enables the use of a depth buffer for this <code>FrameBuffer</code>.
*
*
* @param format The format to use for the depth buffer.
* @throws IllegalArgumentException If <code>format</code> is not a depth format.
*/
public void setDepthBuffer(Image.Format format){
if (id != -1)
public void setDepthBuffer(Image.Format format) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (!format.isDepthFormat())
if (!format.isDepthFormat()) {
throw new IllegalArgumentException("Depth buffer format must be depth.");
}
depthBuf = new RenderBuffer();
depthBuf.slot = format.isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.slot = format.isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.format = format;
}
/**
* Enables the use of a color buffer for this <code>FrameBuffer</code>.
*
*
* @param format The format to use for the color buffer.
* @throws IllegalArgumentException If <code>format</code> is not a color format.
*/
public void setColorBuffer(Image.Format format){
if (id != -1)
public void setColorBuffer(Image.Format format) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (format.isDepthFormat())
if (format.isDepthFormat()) {
throw new IllegalArgumentException("Color buffer format must be color/luminance.");
}
RenderBuffer colorBuf = new RenderBuffer();
colorBuf.slot = 0;
colorBuf.format = format;
colorBufs.clear();
colorBufs.add(colorBuf);
}
private void checkSetTexture(Texture tex, boolean depth){
private void checkSetTexture(Texture tex, boolean depth) {
Image img = tex.getImage();
if (img == null)
if (img == null) {
throw new IllegalArgumentException("Texture not initialized with RTT.");
}
if (depth && !img.getFormat().isDepthFormat())
if (depth && !img.getFormat().isDepthFormat()) {
throw new IllegalArgumentException("Texture image format must be depth.");
else if (!depth && img.getFormat().isDepthFormat())
} else if (!depth && img.getFormat().isDepthFormat()) {
throw new IllegalArgumentException("Texture image format must be color/luminance.");
}
// check that resolution matches texture resolution
if (width != img.getWidth() || height != img.getHeight())
throw new IllegalArgumentException("Texture image resolution " +
"must match FB resolution");
if (width != img.getWidth() || height != img.getHeight()) {
throw new IllegalArgumentException("Texture image resolution "
+ "must match FB resolution");
}
if (samples != tex.getImage().getMultiSamples())
if (samples != tex.getImage().getMultiSamples()) {
throw new IllegalStateException("Texture samples must match framebuffer samples");
}
}
/**
@ -270,38 +279,43 @@ public class FrameBuffer extends NativeObject {
* will be able to write several results into the renderbuffers
* by using the <code>gl_FragData</code> array. Every slot in that
* array maps into a color buffer attached to this framebuffer.
*
*
* @param enabled True to enable MRT (multiple rendering targets).
*/
public void setMultiTarget(boolean enabled){
if (enabled) colorBufIndex = -1;
else colorBufIndex = 0;
public void setMultiTarget(boolean enabled) {
if (enabled) {
colorBufIndex = -1;
} else {
colorBufIndex = 0;
}
}
/**
* @return True if MRT (multiple rendering targets) is enabled.
* @see FrameBuffer#setMultiTarget(boolean)
*/
public boolean isMultiTarget(){
public boolean isMultiTarget() {
return colorBufIndex == -1;
}
/**
* If MRT is not enabled ({@link FrameBuffer#setMultiTarget(boolean) } is false)
* then this specifies the color target to which the scene should be rendered.
* <p>
* By default the value is 0.
*
*
* @param index The color attachment index.
* @throws IllegalArgumentException If index is negative or doesn't map
* to any attachment on this framebuffer.
*/
public void setTargetIndex(int index){
if (index < 0 || index >= 16)
public void setTargetIndex(int index) {
if (index < 0 || index >= 16) {
throw new IllegalArgumentException("Target index must be between 0 and 16");
}
if (colorBufs.size() < index)
if (colorBufs.size() < index) {
throw new IllegalArgumentException("The target at " + index + " is not set!");
}
colorBufIndex = index;
setUpdateNeeded();
@ -309,10 +323,10 @@ public class FrameBuffer extends NativeObject {
/**
* @return The color target to which the scene should be rendered.
*
* @see FrameBuffer#setTargetIndex(int)
*
* @see FrameBuffer#setTargetIndex(int)
*/
public int getTargetIndex(){
public int getTargetIndex() {
return colorBufIndex;
}
@ -321,27 +335,27 @@ public class FrameBuffer extends NativeObject {
* This automatically clears all existing textures added previously
* with {@link FrameBuffer#addColorTexture } and adds this texture as the
* only target.
*
*
* @param tex The color texture to set.
*/
public void setColorTexture(Texture2D tex){
public void setColorTexture(Texture2D tex) {
clearColorTargets();
addColorTexture(tex);
}
/**
* Set the color texture array to use for this framebuffer.
* This automatically clears all existing textures added previously
* with {@link FrameBuffer#addColorTexture } and adds this texture as the
* only target.
*
*
* @param tex The color texture array to set.
*/
public void setColorTexture(TextureArray tex, int layer){
public void setColorTexture(TextureArray tex, int layer) {
clearColorTargets();
addColorTexture(tex, layer);
}
/**
* Set the color texture to use for this framebuffer.
* This automatically clears all existing textures added previously
@ -359,47 +373,50 @@ public class FrameBuffer extends NativeObject {
/**
* Clears all color targets that were set or added previously.
*/
public void clearColorTargets(){
public void clearColorTargets() {
colorBufs.clear();
}
/**
/**
* Add a color buffer without a texture bound to it.
* If MRT is enabled, then each subsequently added texture or buffer can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader.
*
*
* @param format the format of the color buffer
* @see #addColorTexture(com.jme3.texture.Texture2D)
* @see #addColorTexture(com.jme3.texture.Texture2D)
*/
public void addColorBuffer(Image.Format format){
if (id != -1)
public void addColorBuffer(Image.Format format) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
if (format.isDepthFormat())
if (format.isDepthFormat()) {
throw new IllegalArgumentException("Color buffer format must be color/luminance.");
}
RenderBuffer colorBuf = new RenderBuffer();
colorBuf.slot = colorBufs.size();
colorBuf.format = format;
colorBufs.add(colorBuf);
}
/**
* Add a color texture to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader.
*
*
* @param tex The texture to add.
* @see #addColorBuffer(com.jme3.texture.Image.Format)
* @see #addColorBuffer(com.jme3.texture.Image.Format)
*/
public void addColorTexture(Texture2D tex) {
if (id != -1)
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage();
checkSetTexture(tex, false);
@ -411,19 +428,20 @@ public class FrameBuffer extends NativeObject {
colorBufs.add(colorBuf);
}
/**
* Add a color texture array to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>.
* If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
* is rendered to by the shader.
*
*
* @param tex The texture array to add.
*/
public void addColorTexture(TextureArray tex, int layer) {
if (id != -1)
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage();
checkSetTexture(tex, false);
@ -436,8 +454,8 @@ public class FrameBuffer extends NativeObject {
colorBufs.add(colorBuf);
}
/**
/**
* Add a color texture to use for this framebuffer.
* If MRT is enabled, then each subsequently added texture can be
* rendered to through a shader that writes to the array <code>gl_FragData</code>.
@ -448,8 +466,9 @@ public class FrameBuffer extends NativeObject {
* @param face The face of the cube-map to render to.
*/
public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) {
if (id != -1)
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage();
checkSetTexture(tex, false);
@ -465,39 +484,42 @@ public class FrameBuffer extends NativeObject {
/**
* Set the depth texture to use for this framebuffer.
*
*
* @param tex The color texture to set.
*/
public void setDepthTexture(Texture2D tex){
if (id != -1)
public void setDepthTexture(Texture2D tex) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage();
checkSetTexture(tex, true);
depthBuf = new RenderBuffer();
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.tex = tex;
depthBuf.format = img.getFormat();
}
public void setDepthTexture(TextureArray tex, int layer){
if (id != -1)
public void setDepthTexture(TextureArray tex, int layer) {
if (id != -1) {
throw new UnsupportedOperationException("FrameBuffer already initialized.");
}
Image img = tex.getImage();
checkSetTexture(tex, true);
depthBuf = new RenderBuffer();
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.slot = img.getFormat().isDepthStencilFormat() ? SLOT_DEPTH_STENCIL : SLOT_DEPTH;
depthBuf.tex = tex;
depthBuf.format = img.getFormat();
depthBuf.layer = layer;
}
/**
* @return The number of color buffers attached to this texture.
* @return The number of color buffers attached to this texture.
*/
public int getNumColorBuffers(){
public int getNumColorBuffers() {
return colorBufs.size();
}
@ -505,21 +527,22 @@ public class FrameBuffer extends NativeObject {
* @param index
* @return The color buffer at the given index.
*/
public RenderBuffer getColorBuffer(int index){
public RenderBuffer getColorBuffer(int index) {
return colorBufs.get(index);
}
/**
* @return The color buffer with the index set by {@link #setTargetIndex(int)}, or null
* if no color buffers are attached.
* If MRT is disabled, the first color buffer is returned.
* If MRT is disabled, the first color buffer is returned.
*/
public RenderBuffer getColorBuffer() {
if (colorBufs.isEmpty())
if (colorBufs.isEmpty()) {
return null;
if (colorBufIndex<0 || colorBufIndex>=colorBufs.size()) {
return colorBufs.get(0);
}
}
if (colorBufIndex < 0 || colorBufIndex >= colorBufs.size()) {
return colorBufs.get(0);
}
return colorBufs.get(colorBufIndex);
}
@ -554,16 +577,17 @@ public class FrameBuffer extends NativeObject {
}
@Override
public String toString(){
public String toString() {
StringBuilder sb = new StringBuilder();
String mrtStr = colorBufIndex >= 0 ? "" + colorBufIndex : "mrt";
sb.append("FrameBuffer[format=").append(width).append("x").append(height)
.append("x").append(samples).append(", drawBuf=").append(mrtStr).append("]\n");
if (depthBuf != null)
.append("x").append(samples).append(", drawBuf=").append(mrtStr).append("]\n");
if (depthBuf != null) {
sb.append("Depth => ").append(depthBuf).append("\n");
for (RenderBuffer colorBuf : colorBufs){
}
for (RenderBuffer colorBuf : colorBufs) {
sb.append("Color(").append(colorBuf.slot)
.append(") => ").append(colorBuf).append("\n");
.append(") => ").append(colorBuf).append("\n");
}
return sb.toString();
}
@ -571,31 +595,33 @@ public class FrameBuffer extends NativeObject {
@Override
public void resetObject() {
this.id = -1;
for (int i = 0; i < colorBufs.size(); i++) {
colorBufs.get(i).resetObject();
}
if (depthBuf != null)
if (depthBuf != null) {
depthBuf.resetObject();
}
setUpdateNeeded();
}
@Override
public void deleteObject(Object rendererObject) {
((Renderer)rendererObject).deleteFrameBuffer(this);
((Renderer) rendererObject).deleteFrameBuffer(this);
}
public NativeObject createDestructableClone(){
@Override
public NativeObject createDestructableClone() {
return new FrameBuffer(this);
}
@Override
public long getUniqueId() {
return ((long)OBJTYPE_FRAMEBUFFER << 32) | ((long)id);
return ((long) OBJTYPE_FRAMEBUFFER << 32) | ((long) id);
}
/**
* Specifies that the color values stored in this framebuffer are in SRGB
* format.
@ -631,5 +657,4 @@ public class FrameBuffer extends NativeObject {
public boolean isSrgb() {
return srgb;
}
}

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

Loading…
Cancel
Save