Compare commits

..

110 Commits

Author SHA1 Message Date
empirephoenix afe86a314d Revert "Backport changes from the master branch." 8 years ago
empirephoenix ec71c5e04e Merge pull request #671 from JavaSaBr/backport_changes_from_3.2 8 years ago
javasabr fa84e7bf28 backport changes from the master branch. 8 years ago
Nehon b1727b9772 Fixed InstanceGeomerty not working properly when using the lighting material and a non DirectionalLight 8 years ago
empirephoenix 088419eef0 Merge pull request #582 from FennelFetish/font 8 years ago
Rémy Bouquet 9ba574e584 fixed bad comma in previous commit 8 years ago
Nehon c154a47b02 Fixed tangent and normal argument position in Skinning.glsllib 8 years ago
MeFisto94 10b23db94d TestMipMapGen: Use the non AWT MipMap Generator (Don't depend on jme3-desktop but jme3-core, to run this test on android) 8 years ago
MeFisto94 479392f6fd TestFancyCar: Remove unused SettingsDialog imports, allowing the Test to also run on android (no jme3-desktop dependency anymore) 8 years ago
Rémy Bouquet 5470abb2b0 Fixed warnings in Terrain shader. 8 years ago
empirephoenix 8214346e8b Merge pull request #624 from jMonkeyEngine/revert-573-cleanup_build_scripts 8 years ago
empirephoenix a87db2c117 Revert "Cleanup build scripts (3.1)" 8 years ago
empirephoenix 0f93df648e Merge pull request #573 from jMonkeyEngine/cleanup_build_scripts 8 years ago
Paul Speed af04bf9d22 Forcing one of the files to change so we might actually get a new build. 8 years ago
empirephoenix 2761bc3677 Merge pull request #615 from riccardobl/FixMeshCollisionShapeJ3oReadv3.1 8 years ago
Riccardo Balbo 1ae6e98d05 Fix MeshCollisionShape crash when loaded from j3o: always create BVH before scaling. 8 years ago
Nehon 69cd160956 Fixed an issue where ParticleEmitter had NaN bounds during the first update when added to the scene graph during the update loop 8 years ago
Nehon 789daa6295 Fixed warning that were coming out of the particle.j3md. Also fixed the preshadow technique 8 years ago
Rémy Bouquet 659ed8fd23 Merge pull request #602 from stephengold/v3.1 8 years ago
Stephen Gold f3e2925bd8 fix errors in how vector projection is calculated 8 years ago
Rémy Bouquet 5d2c89f040 Merge pull request #599 from stephengold/v3.1 8 years ago
Stephen Gold ac8eb4d40a CapsuleCollisionShape: warn about scaling only if it's not identity 8 years ago
Nehon aae6170cc5 Fixed MikktSpaceTangentGenerator that was not replacing existing Tangent buffers on the mesh. That could cause crashes when the old tangent buffer did not have the same amount of components 8 years ago
iwgeric 7ecb81c230 Update AndroidLocator to allow assets to be stored in Android assets, drawable, or mipmap directories. 8 years ago
Paul Speed 63e8c9c485 Convert Skeleton and Bone over to use the JME cloner system for cloning... 8 years ago
empirephoenix 975954fb17 Merge pull request #575 from Fadorico/upstream3.1 8 years ago
Fennel e60d67b1bb Fixes tab stops in BitmapText / BitmapFont. 8 years ago
Paul Speed 92b5d40003 Modified BitmapTextPage to always deep clone its mesh since otherwise 8 years ago
Paul Speed 4952ad0cb5 Broke out the Serializer's static initializer into a separate initialize() 8 years ago
Paul Speed a13a3a7f09 Another bitmap text clone fix. The text pages array (the list of the actual geometry of 8 years ago
Paul Speed 735397f16e Another fix for BitmapText cloning where the regular clone() was 8 years ago
Paul Speed c1764bc425 Fixed the cloned Letters to use the cloned StringBlock instead of the 8 years ago
Paul Speed da1b7da329 Added a test for cloning BitmapText. 8 years ago
Paul Speed e879a0e142 Fix for issue #577 StringBlock cannot be cloned with the cloner because 8 years ago
Fadorico e3bd122519 Write/read the width and height of the quad 8 years ago
Kirill Vainer 36e99bf032 misc: gitignore update for gradle 3.2.1 8 years ago
Kirill Vainer c37f0e59d2 build: fix gradle 3.2.1 deprecations 8 years ago
Kirill Vainer 06757f73b4 travis: upload artifacts only on linux/jdk8 8 years ago
Kirill Vainer 35b9eed76f travis: reorder structure a bit 8 years ago
Kirill Vainer e4ed3313d5 travis: fix unsupported jdk 8 years ago
Kirill Vainer 8ce2f9cfe7 travis: test matrix build 8 years ago
Kirill Vainer b99d03bd3c version: remove sdk related configuration 8 years ago
Kirill Vainer f800d74e87 travis: remove uneeded install directive 8 years ago
Kirill Vainer 78ac8df78a cleanup build cache according to travis docs 8 years ago
Kirill Vainer 39dc140f79 build v3.1, master, and PRs only from now on 8 years ago
Kirill Vainer f38becf2c6 remove SSH based maven publishing 8 years ago
Kirill Vainer 72b9f186ed fix broken bullet native source url 8 years ago
Kirill Vainer 8c4b44941e Fix #550 8 years ago
Nehon a71fb286f4 Fixed shadow fade and zfar computation as it was breaking shadow border filtering. 8 years ago
Nehon 69d8e5d13e Fixed an issue where some occluders were wrongly culled out from the shadow map at very steep light angle, and when the view cam was almost align with light direction. 8 years ago
Paul Speed 4919620e61 Improved the "compare result changed" error message to include the most 8 years ago
Nehon 1315af8d52 Changed the minimum value of a float when converting it to half float. It was 5.96046E-8f and it's now 3.054738E-5f. This values seems to be the lowest one before 0 when converting back half to float. 8 years ago
Nehon efd47c4347 fixed some javadoc in AbstractShadowRenderer 8 years ago
Nehon 142b006ad6 Fixed post shadow filter for glsl1.5 8 years ago
Nehon 9500227ca7 Defaulted the render back faces shadows in the AbstractShadowRenderer to true to keep the same behavior as in 3.0 8 years ago
Nehon 5495b7d064 Fixed the link to the paper for convertHalfToFloat 8 years ago
Nehon da5e4a18c7 ShaderNodes now move all the declared extensions at the top of the generated shader source 8 years ago
Nehon dd8271e8b3 Fixed SpotLight constructor to properly compute the invSpotRange see https://github.com/jMonkeyEngine/jmonkeyengine/issues/563 8 years ago
jjYBdx4IL cfd491e270 fixes issue https://github.com/jMonkeyEngine/jmonkeyengine/issues/506 : Material->toString() does not prevent/check for possible NPEs 8 years ago
Nehon 95bf9efe9b MikktSpace tangent generator now properly generates the BindPoseTangent buffer when necessary 8 years ago
Rémy Bouquet 7e458e496c Fixed wiki links in the realm.md 8 years ago
Kirill Vainer 09e9c1efa0 Merge pull request #555 from JavaSaBr/master-original 8 years ago
Kirill Vainer 2440fc5a74 Merge pull request #554 from TehLeo/patch-2 8 years ago
empirephoenix bbad454e43 Merge pull request #541 from tonihele/issue-537 8 years ago
empirephoenix 7eb9463496 Merge pull request #505 from JavaSaBr/v3.1 8 years ago
Rémy Bouquet 769cf36221 Merge pull request #547 from MeFisto94/ios-legacyapplication 8 years ago
MeFisto94 7b0a00b364 Using LegacyApplication in the iOS Harness just like it has been done for Android in 3c56afe 8 years ago
Rémy Bouquet b42bf7f67e fixed glsl 1.0 version of the postShadowFilter shader 8 years ago
Rémy Bouquet 056dbdf981 Changed the int value of EdgeFilteringMode.Nearest from 0 to 10 as it seems a define with a 0 value is now ignored. 8 years ago
Rémy Bouquet a7edef3a06 fixed transparent shadows on mac. 8 years ago
Toni Helenius 52c0a35525 Added a cursor cache to avoid cursor disappearing and app crashing when too many cursors are created 8 years ago
Riccardo Balbo c92009a40a Use texture() instead of texture2D() in bloomExtract15 and bloomFinal15 8 years ago
Rémy Bouquet e4a8b8d91c Merge pull request #530 from tiatin/v3.1 8 years ago
tiatin f65f0a7ee8 Added ability to set framebuffer image format used in FilterPostProcessor. 8 years ago
Julien Gouesse 4ba4da2e31 Merge pull request #525 from saloisio/v3.1 9 years ago
saloisio 05c39990ca NewtMouseInput now resets mouse cursor to default image when inputManager.setMouseCursor(null) invoked 9 years ago
Rémy Bouquet fae07c9c71 Merge pull request #522 from MeFisto94/v3.1_HWSkinning 9 years ago
Rémy Bouquet eefc17428c Merge pull request #501 from MeFisto94/HwSkinningFixV02 9 years ago
Julien Gouesse 75c3d61f8f Merge pull request #520 from saloisio/v3.1 9 years ago
saloisio d0175a77b6 Merge branch 'v3.1' of https://github.com/saloisio/jmonkeyengine into v3.1 9 years ago
saloisio 9b8c27a0fb Removed auto centering of mouse cursor 9 years ago
Paul Speed 02c5d9d414 Merge pull request #517 from tiatin/v3.1 9 years ago
tiatin d8529573e4 Changed overrides from ArrayList to SafeArrayList for GC and iteration performance reasons. Fixed bug in SafeArrayList.equals(). 9 years ago
tiatin 9b0422fc3c Added iteration using iterator, if List is not ArrayList. 9 years ago
tiatin 93c2fd1989 Changed iteration over List from for-each to manual iteration. 9 years ago
javasabr be66436745 added warning 9 years ago
empirephoenix 2c3d94a166 Merge pull request #504 from davidB/v3.1 9 years ago
Paul Speed a2efd1323f Merge pull request #509 from davidB/patch-1 9 years ago
David Bernard 758fdcf394 travis: disable uploadArchives 9 years ago
javasabr f354343e47 fixed the NPE with controls 9 years ago
David Bernard f46680815d nifty-gui: upgrade from 1.4.1 to 1.4.2, available on maven central with the new “official” groupId: com.github.nifty-gui 9 years ago
Nehon 3d1a541903 Fixed an issue when resizing the viewport, with a FPP and antialiasing would stop rendering 9 years ago
Nehon 6bdf479a0a Fixed an issue in the fog filter's shader that was preventing it to run on android 9 years ago
Rémy Bouquet 29dfff223c proper equal and hashcode for ShaderNodesVariables. 9 years ago
Kirill Vainer 4faf6cf36c Merge pull request #491 from riccardobl/AddGimpactCollisionAlgo 9 years ago
Kirill Vainer d27b26805a bullet native: fix mingw target platform 9 years ago
Kirill Vainer b2a57e130a travis: set known hosts using travis config 9 years ago
Kirill Vainer fafccdf15e pom: fix incorrect inception year 9 years ago
Kirill Vainer 513fc08fb6 travis: only create dist if deploying 9 years ago
Kirill Vainer 3419256941 travis: use cache rules from docs 9 years ago
Kirill Vainer 2a0a9e7b6e build: fix build error 9 years ago
Kirill Vainer a7b20629e7 build: update to gradle 2.13 9 years ago
Kirill Vainer 8416dd8c65 travis: dont cache netbeans folder anymore 9 years ago
Kirill Vainer 7d4a34f96f build: check file exists before getting text 9 years ago
Kirill Vainer 804c173757 build: minor cleanup 9 years ago
Kirill Vainer 6dfd59ea73 android-examples: use correct maven group 9 years ago
Kirill Vainer 8f7abca01b niftygui: add nifty repository to POM 9 years ago
Kirill Vainer 2c94a3f538 travis: treat v3.1 branch as trunk 9 years ago
Kirill Vainer 652358038d version: treat this branch as trunk 9 years ago
Paul Speed 2fd9da3d50 Merge pull request #487 from Dokthar/joysticks 9 years ago
  1. 93
      .github/actions/tools/bintray.sh
  2. 85
      .github/actions/tools/uploadToMaven.sh
  3. 554
      .github/workflows/main.yml
  4. 34
      .gitignore
  5. 60
      .travis.yml
  6. 13
      CONTRIBUTING.md
  7. 29
      LICENSE
  8. 32
      README.md
  9. 161
      build.gradle
  10. 2
      common-android-app.gradle
  11. 55
      common.gradle
  12. 40
      gradle.properties
  13. BIN
      gradle/wrapper/gradle-wrapper.jar
  14. 3
      gradle/wrapper/gradle-wrapper.properties
  15. 48
      gradlew
  16. 24
      gradlew.bat
  17. 1
      jme3-android-examples/.gitignore
  18. 66
      jme3-android-examples/build.gradle
  19. 17
      jme3-android-examples/proguard-rules.pro
  20. 13
      jme3-android-examples/src/androidTest/java/org/jmonkeyengine/jme3androidexamples/ApplicationTest.java
  21. 56
      jme3-android-examples/src/main/AndroidManifest.xml
  22. BIN
      jme3-android-examples/src/main/assets/mouse.xcf
  23. 39
      jme3-android-examples/src/main/java/jme3test/android/TestAndroidResources.java
  24. 314
      jme3-android-examples/src/main/java/jme3test/android/TestAndroidSensors.java
  25. 354
      jme3-android-examples/src/main/java/jme3test/android/TestAndroidTouch.java
  26. 12
      jme3-android-examples/src/main/java/jme3test/android/TestChooserAndroid.java
  27. 165
      jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/CustomArrayAdapter.java
  28. 85
      jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java
  29. 458
      jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java
  30. 111
      jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/TestActivity.java
  31. BIN
      jme3-android-examples/src/main/res/drawable-hdpi/drawable_monkey.png
  32. BIN
      jme3-android-examples/src/main/res/drawable-ldpi/drawable_monkey.png
  33. BIN
      jme3-android-examples/src/main/res/drawable-mdpi/drawable_monkey.png
  34. BIN
      jme3-android-examples/src/main/res/drawable-xhdpi/drawable_monkey.png
  35. BIN
      jme3-android-examples/src/main/res/drawable/keyboard.png
  36. BIN
      jme3-android-examples/src/main/res/drawable/monkey256.png
  37. BIN
      jme3-android-examples/src/main/res/drawable/monkey256_9.9.png
  38. BIN
      jme3-android-examples/src/main/res/drawable/monkey512.png
  39. BIN
      jme3-android-examples/src/main/res/drawable/monkey512_9.9.png
  40. BIN
      jme3-android-examples/src/main/res/drawable/mouse_disabled.png
  41. BIN
      jme3-android-examples/src/main/res/drawable/mouse_left.png
  42. BIN
      jme3-android-examples/src/main/res/drawable/mouse_none.png
  43. BIN
      jme3-android-examples/src/main/res/drawable/nonselected.png
  44. BIN
      jme3-android-examples/src/main/res/drawable/phone_landscape.png
  45. BIN
      jme3-android-examples/src/main/res/drawable/selected.png
  46. 25
      jme3-android-examples/src/main/res/layout/activity_test.xml
  47. 119
      jme3-android-examples/src/main/res/layout/test_chooser_layout.xml
  48. 30
      jme3-android-examples/src/main/res/layout/test_chooser_row.xml
  49. 33
      jme3-android-examples/src/main/res/menu/menu_items.xml
  50. 19
      jme3-android-examples/src/main/res/menu/test_menu_items.xml
  51. BIN
      jme3-android-examples/src/main/res/mipmap-hdpi/mipmap_monkey.png
  52. BIN
      jme3-android-examples/src/main/res/mipmap-mdpi/mipmap_monkey.png
  53. BIN
      jme3-android-examples/src/main/res/mipmap-xhdpi/mipmap_monkey.png
  54. BIN
      jme3-android-examples/src/main/res/mipmap-xxhdpi/mipmap_monkey.png
  55. BIN
      jme3-android-examples/src/main/res/mipmap-xxxhdpi/mipmap_monkey.png
  56. 6
      jme3-android-examples/src/main/res/values-w820dp/dimens.xml
  57. 6
      jme3-android-examples/src/main/res/values/colors.xml
  58. 5
      jme3-android-examples/src/main/res/values/dimens.xml
  59. 30
      jme3-android-examples/src/main/res/values/strings.xml
  60. 11
      jme3-android-examples/src/main/res/values/styles.xml
  61. 15
      jme3-android-examples/src/test/java/org/jmonkeyengine/jme3androidexamples/ExampleUnitTest.java
  62. 2
      jme3-android-native/.gitignore
  63. 2
      jme3-android-native/build.gradle
  64. 33
      jme3-android-native/decode.gradle
  65. BIN
      jme3-android-native/libs/decode/arm64-v8a/libdecodejme.so
  66. BIN
      jme3-android-native/libs/decode/armeabi-v7a/libdecodejme.so
  67. BIN
      jme3-android-native/libs/decode/armeabi/libdecodejme.so
  68. BIN
      jme3-android-native/libs/decode/mips/libdecodejme.so
  69. BIN
      jme3-android-native/libs/decode/mips64/libdecodejme.so
  70. BIN
      jme3-android-native/libs/decode/x86/libdecodejme.so
  71. BIN
      jme3-android-native/libs/decode/x86_64/libdecodejme.so
  72. BIN
      jme3-android-native/libs/openalsoft/arm64-v8a/libopenalsoftjme.so
  73. BIN
      jme3-android-native/libs/openalsoft/armeabi-v7a/libopenalsoftjme.so
  74. BIN
      jme3-android-native/libs/openalsoft/armeabi/libopenalsoftjme.so
  75. BIN
      jme3-android-native/libs/openalsoft/mips/libopenalsoftjme.so
  76. BIN
      jme3-android-native/libs/openalsoft/mips64/libopenalsoftjme.so
  77. BIN
      jme3-android-native/libs/openalsoft/x86/libopenalsoftjme.so
  78. BIN
      jme3-android-native/libs/openalsoft/x86_64/libopenalsoftjme.so
  79. 38
      jme3-android-native/openalsoft.gradle
  80. 4
      jme3-android-native/src/native/jme_decode/com_jme3_audio_plugins_NativeVorbisFile.c
  81. 2
      jme3-android-native/src/native/jme_decode/com_jme3_texture_plugins_AndroidNativeImageLoader.c
  82. 2
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidAL.c
  83. 173
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidAL.h
  84. 4
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidALC.c
  85. 77
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidALC.h
  86. 4
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidEFX.c
  87. 101
      jme3-android-native/src/native/jme_openalsoft/com_jme3_audio_android_AndroidEFX.h
  88. 9
      jme3-android/build.gradle
  89. 16
      jme3-android/src/main/java/com/jme3/app/AndroidHarness.java
  90. 23
      jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java
  91. 22
      jme3-android/src/main/java/com/jme3/app/DefaultAndroidProfiler.java
  92. 20
      jme3-android/src/main/java/com/jme3/app/R.java
  93. 4
      jme3-android/src/main/java/com/jme3/app/state/MjpegFileWriter.java
  94. 27
      jme3-android/src/main/java/com/jme3/app/state/VideoRecorderAppState.java
  95. 2
      jme3-android/src/main/java/com/jme3/asset/plugins/AndroidLocator.java
  96. 20
      jme3-android/src/main/java/com/jme3/audio/android/AndroidAL.java
  97. 8
      jme3-android/src/main/java/com/jme3/audio/android/AndroidALC.java
  98. 11
      jme3-android/src/main/java/com/jme3/audio/android/AndroidEFX.java
  99. 1
      jme3-android/src/main/java/com/jme3/audio/plugins/NativeVorbisLoader.java
  100. 1
      jme3-android/src/main/java/com/jme3/input/android/AndroidGestureProcessor.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,93 +0,0 @@
#!/bin/bash
# bintray_createPackage [REPO] [PACKAGE] [USER] [PASSWORD] [GIT REPO] [LICENSE]
function bintray_createPackage {
repo="$1"
package="$2"
user="$3"
password="$4"
srcrepo="$5"
license="$6"
repoUrl="https://api.bintray.com/packages/$repo"
if [ "`curl -u$user:$password -H Content-Type:application/json -H Accept:application/json \
--write-out %{http_code} --silent --output /dev/null -X GET \"$repoUrl/$package\"`" != "200" ];
then
if [ "$srcrepo" != "" -a "$license" != "" ];
then
echo "Package does not exist... create."
data="{
\"name\": \"${package}\",
\"labels\": [],
\"licenses\": [\"${license}\"],
\"vcs_url\": \"${srcrepo}\"
}"
curl -u$user:$password -H "Content-Type:application/json" -H "Accept:application/json" -X POST \
-d "${data}" "$repoUrl"
else
echo "Package does not exist... you need to specify a repo and license for it to be created."
fi
else
echo "The package already exists. Skip."
fi
}
# uploadFile file destination [REPO] "content" [PACKAGE] [USER] [PASSWORD] [SRCREPO] [LICENSE]
function bintray_uploadFile {
file="$1"
dest="$2"
echo "Upload $file to $dest"
repo="$3"
type="$4"
package="$5"
user="$6"
password="$7"
srcrepo="$8"
license="$9"
publish="${10}"
bintray_createPackage $repo $package $user $password $srcrepo $license
url="https://api.bintray.com/$type/$repo/$package/$dest"
if [ "$publish" = "true" ]; then url="$url;publish=1"; fi
curl -T "$file" -u$user:$password "$url"
}
function bintray_uploadAll {
path="$1"
destpath="$2"
repo="$3"
type="$4"
package="$5"
user="$6"
password="$7"
srcrepo="$8"
license="$9"
publish="${10}"
cdir="$PWD"
cd "$path"
files="`find . -type f -print`"
IFS="
"
set -f
for f in $files; do
destfile="$destpath/${f:2}"
bintray_uploadFile $f $destfile $repo $type $package $user $password $srcrepo $license $publish
done
set +f
unset IFS
cd "$cdir"
}

@ -1,85 +0,0 @@
#!/bin/bash
#############################################
#
# Usage
# uploadAllToMaven path/of/dist/maven https://api.bintray.com/maven/riccardo/sandbox-maven/ riccardo $BINTRAY_PASSWORD gitrepo license
# Note: gitrepo and license are needed only when uploading to bintray if you want to create missing packages automatically
# gitrepo must be a valid source repository
# license must be a license supported by bintray eg "BSD 3-Clause"
# or
# uploadAllToMaven path/of/dist/maven $GITHUB_PACKAGE_REPOSITORY user password
#
#############################################
root="`dirname ${BASH_SOURCE[0]}`"
source $root/bintray.sh
set -e
function uploadToMaven {
file="$1"
destfile="$2"
repourl="$3"
user="$4"
password="$5"
srcrepo="$6"
license="$7"
auth=""
if [ "$user" != "token" ];
then
echo "Upload with username $user and password"
auth="-u$user:$password"
else
echo "Upload with token"
auth="-H \"Authorization: token $password\""
fi
if [[ $repourl == https\:\/\/api.bintray.com\/* ]];
then
package="`dirname $destfile`"
version="`basename $package`"
package="`dirname $package`"
package="`basename $package`"
if [ "$user" = "" -o "$password" = "" ];
then
echo "Error! You need username and password to upload to bintray"
exit 1
fi
echo "Detected bintray"
bintrayRepo="${repourl/https\:\/\/api.bintray.com\/maven/}"
echo "Create package on $bintrayRepo"
bintray_createPackage $bintrayRepo $package $user $password $srcrepo $license
repourl="$repourl/$package"
fi
cmd="curl -T \"$file\" $auth \
\"$repourl/$destfile\" \
-vvv"
echo "Run $cmd"
eval "$cmd"
}
export -f uploadToMaven
function uploadAllToMaven {
path="$1"
cdir="$PWD"
cd "$path"
files="`find . \( -name "*.jar" -o -name "*.pom" \) -type f -print`"
IFS="
"
set -f
for art in $files; do
art="${art:2}"
uploadToMaven "$art" "$art" ${@:2}
done
set +f
unset IFS
cd "$cdir"
}

@ -1,554 +0,0 @@
######################################################################################
# JME CI/CD
######################################################################################
# Quick overview of what is going on in this script:
# - Build natives for android
# - Build natives for linux arm
# - Build natives for windows,mac,linux x86_64 and x86
# - Merge the natives, build the engine, create the zip release, maven artifacts, javadoc and native snapshot
# - (only when there is a change in the native code) Deploy the native snapshot to bintray
# - (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
# 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.
################# CONFIGURATIONS #####################################################
# >> Configure BINTRAY RELEASE & NATIVE SNAPSHOT
# Configure the following secrets/variables (customize the values with your own)
# BINTRAY_GENERIC_REPO=riccardoblsandbox/jmonkeyengine-files
# BINTRAY_MAVEN_REPO=riccardoblsandbox/jmonkeyengine
# BINTRAY_USER=riccardo
# 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
# is running the build.
# >> Configure JAVADOC
# JAVADOC_GHPAGES_REPO="riccardoblsandbox/javadoc.jmonkeyengine.org.git"
# Generate a deloy key
# 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
######################################################################################
# Resources:
# - Github actions docs: https://help.github.com/en/articles/about-github-actions
# - Package registry docs: https://help.github.com/en/articles/about-github-package-registry
# - Official actions: https://github.com/actions
# - Community actions: https://github.com/sdras/awesome-actions
######################################################################################
# - Riccardo Balbo
######################################################################################
name: Build jMonkeyEngine
on:
push:
branches:
- master
- newbuild
- 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@v2
with:
fetch-depth: 1
- 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.
./gradlew -PuseCommitHashAsVersionName=true --no-daemon -PbuildForPlatforms=LinuxArm,LinuxArmHF,LinuxArm64 -PbuildNativeProjects=true \
:jme3-bullet-native:assemble
- name: Upload natives
uses: actions/upload-artifact@master
with:
name: linuxarm-natives
path: build/native
# Build the natives on android
BuildAndroidNatives:
name: Build natives for android
runs-on: ubuntu-18.04
container:
image: riccardoblb/buildenv-jme3:android
steps:
- name: Clone the repo
uses: actions/checkout@v2
with:
fetch-depth: 1
- 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
- name: Upload natives
uses: actions/upload-artifact@master
with:
name: android-natives
path: build/native
# Build the natives
BuildNatives:
strategy:
fail-fast: true
matrix:
os: [ubuntu-18.04,windows-2019,macOS-latest]
jdk: [8.x.x]
include:
- os: ubuntu-18.04
osName: linux
- os: windows-2019
osName: windows
- os: macOS-latest
osName: mac
name: Build natives for ${{ matrix.osName }}
runs-on: ${{ matrix.os }}
steps:
- name: Clone the repo
uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Prepare java environment
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.jdk }}
architecture: x64
- name: Validate the Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Build Natives
shell: bash
env:
OS_NAME: ${{ matrix.osName }}
run: |
# Install dependencies
if [ "$OS_NAME" = "mac" ];
then
echo "Prepare mac"
elif [ "$OS_NAME" = "linux" ];
then
echo "Prepare linux"
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib
else
echo "Prepare windows"
fi
# Build
./gradlew -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:
needs: [BuildNatives,BuildAndroidNatives]
name: Build on ${{ matrix.osName }} jdk${{ matrix.jdk }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [ubuntu-18.04,windows-2019,macOS-latest]
jdk: [8.x.x,11.x.x]
include:
- os: ubuntu-18.04
osName: linux
deploy: true
- os: windows-2019
osName: windows
- os: macOS-latest
osName: mac
- jdk: 11.x.x
deploy: false
steps:
- name: Clone the repo
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
- name: Download natives for linux
uses: actions/download-artifact@master
with:
name: linux-natives
path: build/native
- name: Download natives for windows
uses: actions/download-artifact@master
with:
name: windows-natives
path: build/native
- name: Download natives for mac
uses: actions/download-artifact@master
with:
name: mac-natives
path: build/native
- name: Download natives for android
uses: actions/download-artifact@master
with:
name: android-natives
path: build/native
- name: Download natives for linux (arm)
uses: actions/download-artifact@master
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
./gradlew -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true build
if [ "${{ matrix.deploy }}" = "true" ];
then
# We are going to need "zip"
sudo apt-get update
sudo apt-get install -y zip
# Create the zip release and the javadoc
./gradlew -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/
./gradlew -PuseCommitHashAsVersionName=true -PskipPrebuildLibraries=true install -Dmaven.repo.local="$PWD/dist/maven"
# Zip the natives into a single archive (we are going to use this to deploy native snapshots)
echo "Create native zip"
cdir="$PWD"
cd "build/native"
zip -r "$cdir/dist/jme3-natives.zip" *
cd "$cdir"
echo "Done"
fi
# Used later by DeploySnapshot
- name: Upload merged natives
if: matrix.deploy==true
uses: actions/upload-artifact@master
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
- 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
- name: Upload release
if: github.event_name == 'release' && matrix.deploy==true
uses: actions/upload-artifact@master
with:
name: release
path: dist/release
# This job deploys the native snapshot.
# The snapshot is downloaded when people build the engine without setting buildNativeProject
# this is useful for people that want to build only the java part and don't have
# all the stuff needed to compile natives.
DeploySnapshot:
needs: [BuildJMonkey]
name: "Deploy snapshot"
runs-on: ubuntu-18.04
if: github.event_name == 'push'
steps:
# We clone the repo manually, since we are going to push back a reference to the snapshot
- name: Clone the repo
run: |
branch="${GITHUB_REF//refs\/heads\//}"
if [ "$branch" != "" ];
then
git clone --single-branch --branch "$branch" https://github.com/${GITHUB_REPOSITORY}.git .
fi
- name: Download merged natives
uses: actions/download-artifact@master
with:
name: natives
path: dist/
- name: Deploy natives snapshot
run: |
source .github/actions/tools/bintray.sh
NATIVE_CHANGES="yes"
branch="${GITHUB_REF//refs\/heads\//}"
if [ "$branch" != "" ];
then
if [ -f "natives-snapshot.properties" ];
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
NATIVE_CHANGES=""
else
# We check if the native code changed.
echo "Detect changes"
NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- jme3-bullet-native/)"
if [ "$NATIVE_CHANGES" = "" ];then NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- jme3-android-native/)"; fi
if [ "$NATIVE_CHANGES" = "" ];then NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- jme3-bullet-native-android/)"; fi
if [ "$NATIVE_CHANGES" = "" ];then NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- jme3-bullet/)"; fi
# The bulletUrl (in gradle.properties) might have changed.
if [ "$NATIVE_CHANGES" = "" ];then NATIVE_CHANGES="$(git diff-tree --name-only "$GITHUB_SHA" "$nativeSnapshot" -- gradle.properties)"; fi
fi
fi
# We do nothing if there is no change
if [ "$NATIVE_CHANGES" = "" ];
then
echo "No changes, skip."
else
if [ "${{ secrets.BINTRAY_GENERIC_REPO }}" = "" ];
then
echo "Configure the following secrets to enable native snapshot deployment"
echo "BINTRAY_GENERIC_REPO, BINTRAY_USER, BINTRAY_APIKEY"
else
# Deploy snapshot
bintray_uploadFile dist/jme3-natives.zip \
$GITHUB_SHA/$GITHUB_SHA/jme3-natives.zip \
${{ secrets.BINTRAY_GENERIC_REPO }} "content" "natives" \
${{ secrets.BINTRAY_USER }} \
${{ secrets.BINTRAY_APIKEY }} \
"https://github.com/${GITHUB_REPOSITORY}" \
"${{ secrets.BINTRAY_LICENSE }}" "true"
# 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
# We need to calculate the header for git authentication
header=$(echo -n "ad-m:${{ secrets.GITHUB_TOKEN }}" | base64)
# Push
(git -c http.extraheader="AUTHORIZATION: basic $header" push origin "$branch" || true)
fi
fi
fi
# This job deploys the release
DeployRelease:
needs: [BuildJMonkey]
name: Deploy Release
runs-on: ubuntu-18.04
if: github.event_name == 'release'
steps:
# We need to clone everything again for uploadToMaven.sh ...
- name: Clone the repo
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
run: |
# We need to get the release id (yeah, it's not the same as the tag)
echo "${GITHUB_EVENT_PATH}"
cat ${GITHUB_EVENT_PATH}
releaseId=$(jq --raw-output '.release.id' ${GITHUB_EVENT_PATH})
# Now that we have the id, we just upload the release zip from before
echo "Upload to release $releaseId"
filename="$(ls dist/release/*.zip)"
url="https://uploads.github.com/repos/${GITHUB_REPOSITORY}/releases/$releaseId/assets?name=$(basename $filename)"
echo "Upload to $url"
curl -L \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/zip" \
--data-binary @"$filename" \
"$url"
- name: Deploy to bintray
run: |
source .github/actions/tools/uploadToMaven.sh
if [ "${{ secrets.BINTRAY_MAVEN_REPO }}" = "" ];
then
echo "Configure the following secrets to enable bintray deployment"
echo "BINTRAY_MAVEN_REPO, BINTRAY_USER, BINTRAY_APIKEY"
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:
needs: [BuildJMonkey]
name: Deploy Javadoc
runs-on: ubuntu-18.04
if: github.event_name == 'release'
steps:
# We are going to need a deploy key for this, since we need
# to push to a different repo
- name: Set ssh key
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.JAVADOC_GHPAGES_DEPLOY_PRIVKEY }}" > $HOME/.ssh/deploy.key
chmod 600 $HOME/.ssh/deploy.key
# We clone the javadoc repo
- name: Clone gh-pages
run: |
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
run: |
set -f
IFS=$'\n'
# Get the tag for this release
version="`if [[ $GITHUB_REF == refs\/tags* ]]; then echo ${GITHUB_REF//refs\/tags\//}; fi`"
# If there is no tag, then we do nothing.
if [ "$version" != "" ];
then
echo "Deploy as $version"
# Remove any older version of the javadoc for this tag
if [ -d "$version" ];then rm -Rf "$version"; fi
# Rename newdoc with the version name
mv newdoc "$version"
# 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;
do
if [ "$v" = "$version" ];
then
echo "$v" "$version"
addNew=false
break
fi
done
# If not, we add it to the beginning
if [ "$addNew" = "true" ];
then
echo -e "$version\n$index" > index.txt
index="`cat index.txt`"
fi
# Regenerate the pages
chmod +x make.sh
./make.sh
# Configure git to use the deploy key
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $HOME/.ssh/deploy.key"
# Commit the changes
git config --global user.name "Github Actions"
git config --global user.email "actions@users.noreply.github.com"
git add . || true
git commit -m "$version" || true
branch="gh-pages"
git push origin "$branch" --force || true
fi

34
.gitignore vendored

@ -1,9 +1,4 @@
**/nbproject/private/
**/.classpath
**/.settings
**/.project
**/.vscode
**/out/
/.gradle/
/.nb-gradle/
/.idea/
@ -19,30 +14,21 @@
*.jnilib
*.dylib
*.iml
*.class
*.jtxt
.gradletasknamecache
.DS_Store
/jme3-core/src/main/resources/com/jme3/system/version.properties
/jme3-*/build/
/jme3-*/bin/
/jme3-bullet-native/bullet3.zip
/jme3-bullet-native/bullet3-*/
/jme3-bullet-native/src/native/cpp/com_jme3_bullet_*.h
/jme3-bullet-native/bullet.zip
/jme3-bullet-native/bullet-2.82-r2704/
/jme3-android-native/openal-soft/
/jme3-android-native/OpenALSoft.zip
/jme3-android-native/src/native/jme_decode/STBI/
/jme3-android-native/src/native/jme_decode/Tremor/
/jme3-android-native/src/native/jme_decode/com_jme3_audio_plugins_NativeVorbisFile.h
/jme3-android-native/src/native/jme_decode/com_jme3_texture_plugins_AndroidNativeImageLoader.h
/jme3-android-native/stb_image.h
/jme3-examples/private/
!/jme3-vr/src/main/resources/**/*.dylib
!/jme3-vr/src/main/resources/**/*.so
!/jme3-vr/src/main/resources/**/*.so.dbg
!/jme3-vr/src/main/resources/**/*.dll
!/jme3-vr/src/main/resources/**/*.pdb
/buildMaven.bat
/private
.travis.yml
appveyor.yml
javadoc_deploy
javadoc_deploy.pub
!/jme3-bullet-native/libs/native/windows/x86_64/bulletjme.dll
!/jme3-bullet-native/libs/native/windows/x86/bulletjme.dll
!/jme3-bullet-native/libs/native/osx/x86/libbulletjme.dylib
!/jme3-bullet-native/libs/native/osx/x86_64/libbulletjme.dylib
!/jme3-bullet-native/libs/native/linux/x86/libbulletjme.so
!/jme3-bullet-native/libs/native/linux/x86_64/libbulletjme.so

@ -0,0 +1,60 @@
language: java
sudo: false
addons:
ssh_known_hosts: updates.jmonkeyengine.org
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
notifications:
slack:
on_success: change
on_failure: always
rooms:
secure: "PWEk4+VL986c3gAjWp12nqyifvxCjBqKoESG9d7zWh1uiTLadTHhZJRMdsye36FCpz/c/Jt7zCRO/5y7FaubQptnRrkrRfjp5f99MJRzQVXnUAM+y385qVkXKRKd/PLpM7XPm4AvjvxHCyvzX2wamRvul/TekaXKB9Ti5FCN87s="
install:
- ./gradlew assemble
script:
- ./gradlew check
before_deploy:
- ./gradlew createZipDistribution
- export RELEASE_DIST=$(ls build/distributions/*.zip)
deploy:
provider: releases
api_key:
secure: PuEsJd6juXBH29ByITW3ntSAyrwWs0IeFvXJ5Y2YlhojhSMtTwkoWeB6YmDJWP4fhzbajk4TQ1HlOX2IxJXSW/8ShOEIUlGXz9fHiST0dkSM+iRAUgC5enCLW5ITPTiem7eY9ZhS9miIam7ngce9jHNMh75PTzZrEJtezoALT9w=
file_glob: true
file: "${RELEASE_DIST}"
skip_cleanup: true
on:
repo: jMonkeyEngine/jmonkeyengine
tags: true
before_install:
- git fetch --unshallow
- "[ $TRAVIS_PULL_REQUEST == 'false' ] && openssl aes-256-cbc -K $encrypted_a1949b55824a_key -iv $encrypted_a1949b55824a_iv -in private/www-updater.key.enc -out private/www-updater.key -d || :"
# before_install:
# required libs for android build tools
# sudo apt-get update
# sudo apt-get install -qq p7zip-full
# sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch
# newest Android NDK
# wget http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin -O ndk.bin
# 7z x ndk.bin -y > /dev/null
# export ANDROID_NDK=`pwd`/android-ndk-r10c
after_success:
- '[ -n "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew bintrayUpload || :'
# - '[ "$TRAVIS_BRANCH" == "v3.1" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives || :'
# - '[ -n "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives bintrayUpload || :'

@ -9,8 +9,6 @@ Communication always comes first. **All** code changes and other contributions s
### New Contributors
Check out the [Projects](https://github.com/jMonkeyEngine/jmonkeyengine/projects/1) tab, where the team has prioritized issues that you as a new contributor can undertake that will familiarize you to the workflow of contributing. This highlights some issues the team thinks would be a good start for new contributors but you are free to contribute on any other issues or integration you wish.
When you're ready to submit your code, just make a [pull request](https://help.github.com/articles/using-pull-requests).
- Do not commit your code until you have received proper feedback.
@ -24,15 +22,6 @@ p.s. We will try hold ourselves to a [certain standard](http://www.defmacro.org/
Developers in the Contributors team can push directly to Main instead of submitting pull requests, however for new features it is often a good idea to do a pull request as a means to get a last code review.
## Customs around integration, branching, tagging, and releases
- Most pull requests are integrated directly into the master branch of the repository.
- Integrators should note, unless the history of the pull request is important, it should be integrated to a single commit using “squash and merge”. If the history is important, favor “rebase and merge”. Don’t create a merge commit unless GitHub cannot rebase the PR.
- For each major release (such as v3.0 or v3.3), an appropriately named release branch is created in the repository.
- For each minor (or “dot-dot”) release (such as v3.2.3), an appropriately named tag is created in the repository.
- In general, library changes that plausibly might break existing apps appear only in major releases, not minor ones.
## Building the engine
1. Install [Gradle](http://www.gradle.org/)
@ -66,5 +55,5 @@ We generally abide by the standard Java Code Conventions. Besides that, just mak
## Documentation
- How to edit the [wiki](https://github.com/jMonkeyEngine/wiki).
- How to edit the wiki - WIP
- How to edit JavaDocs - WIP

@ -1,29 +0,0 @@
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.

@ -1,28 +1,24 @@
jMonkeyEngine
jMonkeyEngine
=============
[![Build Status](https://github.com/jMonkeyEngine/jmonkeyengine/workflows/Build%20jMonkeyEngine/badge.svg)](https://github.com/jMonkeyEngine/jmonkeyengine/actions)
[![Build Status](https://travis-ci.org/jMonkeyEngine/jmonkeyengine.svg?branch=master)](https://travis-ci.org/jMonkeyEngine/jmonkeyengine)
jMonkeyEngine is a 3-D game engine for adventurous Java developers. It’s open-source, cross-platform, and cutting-edge. 3.2.4 is the latest stable version of the jMonkeyEngine 3 SDK, a complete game development suite. We'll release 3.2.x updates until the major 3.3 release arrives.
jMonkeyEngine is a 3D game engine for adventurous Java developers. It’s open source, cross platform and cutting edge. And it is all beautifully documented. The 3.0 branch is the latest stable version of the jMonkeyEngine 3 SDK, a complete game development suite. We'll be frequently submitting stable 3.0.x updates until the major 3.1 version arrives.
The engine is used by several commercial game studios and computer-science courses. Here's a taste:
![jME3 Games Mashup](https://i.imgur.com/nF8WOW6.jpg)
![jME3 Games Mashup](http://i.imgur.com/hBehW2i.jpg)
- [jME powered games on IndieDB](http://www.indiedb.com/engines/jmonkeyengine/games)
- [Maker's Tale](http://steamcommunity.com/sharedfiles/filedetails/?id=93461954t)
- [Boardtastic 2](https://boardtastic-2.fileplanet.com/apk)
- [Attack of the Gelatinous Blob](https://attack-gelatinous-blob.softwareandgames.com/)
- [Mythruna](http://mythruna.com/)
- [PirateHell (on Steam)](https://store.steampowered.com/app/321080/Pirate_Hell/)
- [3089 (on Steam)](http://store.steampowered.com/app/263360/)
- [3079 (on Steam)](http://store.steampowered.com/app/259620/)
- [Lightspeed Frontier (on Steam)](https://store.steampowered.com/app/548650/Lightspeed_Frontier/)
- [Skullstone](http://www.skullstonegame.com/)
- [Spoxel (on Steam)](https://store.steampowered.com/app/746880/Spoxel/)
- [Nine Circles of Hell (on Steam)](https://store.steampowered.com/app/1200600/Nine_Circles_of_Hell/)
- [Leap](https://gamejolt.com/games/leap/313308)
- [Jumping Jack Flag](http://timealias.bplaced.net/jack/)
- [Boardtastic 2](https://play.google.com/store/apps/details?id=com.boardtastic.skateboarding)
- [Copod](http://herebeben.com/copod)
- [Attack of the Gelatinous Blob](http://attackofthegelatinousblob.com/)
- [Chaos](http://4realms.net/)
- [Mythruna](https://mythruna.com/)
- [PirateHell](http://www.desura.com/games/piratehell)
- [3089 (on steam)](http://store.steampowered.com/app/263360/)
- [3079 (on steam)](http://store.steampowered.com/app/259620/)
## Getting started
@ -37,8 +33,8 @@ Note: The master branch on GitHub is a development version of the engine and is
- NetBeans Platform
- Gradle
Plus a bunch of awesome libraries & tight integrations like Bullet, NiftyGUI and other goodies.
Plus a bunch of awesome libraries & tight integrations like Bullet, Blender, NiftyGUI and other goodies.
### Documentation
Did you miss it? Don't sweat it, [here it is again](https://jmonkeyengine.github.io/wiki).

@ -1,35 +1,21 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'me.tatarka:gradle-retrolambda:3.7.1'
}
}
allprojects {
repositories {
google()
jcenter()
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.5'
}
}
apply plugin: 'base'
apply from: file('version.gradle')
apply plugin: 'me.tatarka.retrolambda'
// This is applied to all sub projects
subprojects {
if(!project.name.equals('jme3-android-examples')) {
apply from: rootProject.file('common.gradle')
if (!project.name.equals('jme3-testdata')) {
if (!['jme3-testdata', 'sdk'].contains(project.name)) {
apply from: rootProject.file('bintray.gradle')
}
} else {
@ -43,32 +29,31 @@ task run(dependsOn: ':jme3-examples:run') {
defaultTasks 'run'
task libDist(dependsOn: subprojects.build, description: 'Builds and copies the engine binaries, sources and javadoc to build/libDist') {
doLast {
File libFolder = mkdir("$buildDir/libDist/lib")
File sourceFolder = mkdir("$buildDir/libDist/sources")
File javadocFolder = mkdir("$buildDir/libDist/javadoc")
subprojects.each {project ->
if(project.ext.mainClass == ''){
project.tasks.withType(Jar).each {archiveTask ->
if(archiveTask.classifier == "sources"){
copy {
from archiveTask.archivePath
into sourceFolder
rename {project.name + '-' + archiveTask.classifier +'.'+ archiveTask.extension}
}
} else if(archiveTask.classifier == "javadoc"){
copy {
from archiveTask.archivePath
into javadocFolder
rename {project.name + '-' + archiveTask.classifier +'.'+ archiveTask.extension}
}
} else{
copy {
from archiveTask.archivePath
into libFolder
rename {project.name + '.' + archiveTask.extension}
}
task libDist(dependsOn: subprojects.build) << {
// description 'Builds and copies the engine binaries, sources and javadoc to build/libDist'
File libFolder = mkdir("$buildDir/libDist/lib")
File sourceFolder = mkdir("$buildDir/libDist/sources")
File javadocFolder = mkdir("$buildDir/libDist/javadoc")
subprojects.each {project ->
if(project.ext.mainClass == ''){
project.tasks.withType(Jar).each {archiveTask ->
if(archiveTask.classifier == "sources"){
copy {
from archiveTask.archivePath
into sourceFolder
rename {project.name + '-' + archiveTask.classifier +'.'+ archiveTask.extension}
}
} else if(archiveTask.classifier == "javadoc"){
copy {
from archiveTask.archivePath
into javadocFolder
rename {project.name + '-' + archiveTask.classifier +'.'+ archiveTask.extension}
}
} else{
copy {
from archiveTask.archivePath
into libFolder
rename {project.name + '.' + archiveTask.extension}
}
}
}
@ -80,9 +65,9 @@ task createZipDistribution(type:Zip,dependsOn:["dist","libDist"], description:"P
archiveName "jME" + jmeFullVersion + ".zip"
into("/") {
from {"./dist"}
}
}
into("/sources") {
from {"$buildDir/libDist/sources"}
from {"$buildDir/libDist/sources"}
}
}
@ -102,21 +87,21 @@ task dist(dependsOn: [':jme3-examples:dist', 'mergedJavadoc']){
task mergedJavadoc(type: Javadoc, description: 'Creates Javadoc from all the projects.') {
title = 'jMonkeyEngine3'
destinationDir = mkdir("dist/javadoc")
options.encoding = 'UTF-8'
// Allows Javadoc to be generated on Java 8 despite doclint errors.
if (JavaVersion.current().isJava8Compatible()) {
options.addStringOption('Xdoclint:none', '-quiet')
}
options.overview = file("javadoc-overview.html")
// Note: The closures below are executed lazily.
source subprojects.collect {project ->
project.sourceSets*.allJava
}
classpath = files(subprojects.collect {project ->
project.sourceSets*.compileClasspath})
// classpath = files(subprojects.collect {project ->
// project.sourceSets*.compileClasspath})
// source {
// subprojects*.sourceSets*.main*.allSource
// }
@ -125,15 +110,14 @@ task mergedJavadoc(type: Javadoc, description: 'Creates Javadoc from all the pro
}
}
clean.dependsOn('cleanMergedJavadoc')
task cleanMergedJavadoc(type: Delete) {
delete file('dist/javadoc')
}
task mergedSource(type: Copy){
}
task wrapper(type: Wrapper, description: 'Creates and deploys the Gradle wrapper to the current directory.') {
gradleVersion = '2.13'
}
ext {
ndkCommandPath = ""
ndkExists = false
@ -152,69 +136,13 @@ task configureAndroidNDK {
if (System.env.ANDROID_NDK != null) {
ndkBuildPath = System.env.ANDROID_NDK + File.separator + ndkBuildFile
}
if (new File(ndkBuildPath).exists()) {
ndkExists = true
ndkCommandPath = ndkBuildPath
}
}
gradle.rootProject.ext.set("usePrebuildNatives", 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()) {
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 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);
target.getParentFile().mkdirs();
ant.get(src: nativesUrl, dest: target);
}
}
task extractPrebuiltNatives {
inputs.file nativesZipFile
outputs.dir nativesPath
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);
File dest = new File(nativesPath + File.separator + srcRel);
boolean doCopy = !(dest.exists() && dest.lastModified() > src.lastModified())
if (doCopy) {
println("Copy " + src + " " + dest);
dest.getParentFile().mkdirs();
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
assemble.dependsOn extractPrebuiltNatives
}
}
//class IncrementalReverseTask extends DefaultTask {
// @InputDirectory
// def File inputDir
@ -250,14 +178,3 @@ if (skipPrebuildLibraries != "true" && buildNativeProjects != "true") {
// enableAssertions = true // true by default
// }
//}
wrapper {
gradleVersion = '5.6.4'
}
retrolambda {
javaVersion JavaVersion.VERSION_1_7
incremental true
jvmArgs '-noverify'
}

@ -1,7 +1,7 @@
apply plugin: 'com.android.application'
group = 'org.jmonkeyengine'
version = jmeFullVersion
version = jmeVersion + '-' + jmeVersionTag
sourceCompatibility = '1.6'

@ -3,50 +3,33 @@
//
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'maven'
group = 'org.jmonkeyengine'
version = jmeFullVersion
version = jmePomVersion
sourceCompatibility = '1.8'
sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
gradle.projectsEvaluated {
tasks.withType(JavaCompile) { // compile-time options:
options.compilerArgs << '-Xlint:unchecked'
}
}
repositories {
mavenCentral()
maven {
url "http://nifty-gui.sourceforge.net/nifty-maven-repo"
}
flatDir {
dirs rootProject.file('lib')
}
}
configurations {
deployerJars
}
dependencies {
// Adding dependencies here will add the dependencies to each subproject.
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.0.28-beta'
testCompile group: 'org.easytesting', name: 'fest-assert-core', version: '2.0M10'
testCompile 'org.codehaus.groovy:groovy-all:2.5.8'
deployerJars "org.apache.maven.wagon:wagon-ssh:2.9"
}
// Uncomment if you want to see the status of every test that is run and
// the test output.
/*
test {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
}
}
*/
jar {
manifest {
attributes 'Implementation-Title': 'jMonkeyEngine',
@ -57,13 +40,11 @@ jar {
javadoc {
failOnError = false
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
options.docTitle = "jMonkeyEngine ${jmeFullVersion} ${project.name} Javadoc"
options.windowTitle = "jMonkeyEngine ${jmeFullVersion} ${project.name} Javadoc"
options.header = "<b>jMonkeyEngine ${jmeFullVersion} ${project.name}</b>"
options.docTitle = "jMonkeyEngine ${jmeMainVersion} ${project.name} Javadoc"
options.windowTitle = "jMonkeyEngine ${jmeMainVersion} ${project.name} Javadoc"
options.header = "<b>jMonkeyEngine ${jmeMainVersion} ${project.name}</b>"
options.author = "true"
options.use = "true"
options.charSet = "UTF-8"
options.encoding = "UTF-8"
//disable doclint for JDK8, more quiet output
if (JavaVersion.current().isJava8Compatible()){
options.addStringOption('Xdoclint:none', '-quiet')
@ -135,3 +116,17 @@ artifacts {
archives writeFullPom.outputs.files[0]
}
uploadArchives {
repositories.mavenDeployer {
configuration = configurations.deployerJars
// disable this otherwise it will fill up the server with stale jars
uniqueVersion = false
repository(url: "scp://updates.jmonkeyengine.org/var/www/updates/maven") {
authentication(userName: "www-updater", privateKey: "private/www-updater.key")
}
pom.project pomConfig
}
}

@ -1,16 +1,11 @@
# Version number: Major.Minor.SubMinor (e.g. 3.3.0)
jmeVersion = 3.4.0
# Leave empty to autogenerate
# (use -PjmeVersionName="myVersion" from commandline to specify a custom version name )
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
# Version number used for plugins, only 3 numbers (e.g. 3.1.3)
jmeVersion = 3.1.0
# Version used for application and settings folder, no spaces!
jmeMainVersion = 3.1
# Version addition pre-alpha-svn, Stable, Beta
jmeVersionTag = SNAPSHOT
# Increment this each time jmeVersionTag changes but jmeVersion stays the same
jmeVersionTagID = 0
# specify if JavaDoc should be built
buildJavaDoc = true
@ -19,22 +14,21 @@ buildJavaDoc = true
buildNativeProjects = false
buildAndroidExamples = false
buildForPlatforms = Linux64,Linux32,Windows64,Windows32,Mac64
# Forcefully ignore prebuilt libraries
skipPrebuildLibraries=false
# Path to android NDK for building native libraries
#ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7
ndkPath = /opt/android-ndk-r16b
ndkPath = /opt/android-ndk-r10c
# Path for downloading native Bullet
# 2.89+ (circa 26 April 2020, to avoid jMonkeyEngine issue #1283)
bulletUrl = https://github.com/bulletphysics/bullet3/archive/cd8cf7521cbb8b7808126a6adebd47bb83ea166a.zip
bulletFolder = bullet3-cd8cf7521cbb8b7808126a6adebd47bb83ea166a
bulletZipFile = bullet3.zip
bulletUrl = https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/bullet/bullet-2.82-r2704.zip
bulletFolder = bullet-2.82-r2704
bulletZipFile = bullet.zip
# Path for downloading NetBeans Base
netbeansUrl = http://download.netbeans.org/netbeans/8.0.2/final/zip/netbeans-8.0.2-201411181905-javase.zip
# POM settings
POM_NAME=jMonkeyEngine
POM_DESCRIPTION=jMonkeyEngine is a 3-D game engine for adventurous Java developers
POM_DESCRIPTION=jMonkeyEngine is a 3D game engine for adventurous Java developers
POM_URL=http://jmonkeyengine.org
POM_SCM_URL=https://github.com/jMonkeyEngine/jmonkeyengine
POM_SCM_CONNECTION=scm:git:git://github.com/jMonkeyEngine/jmonkeyengine.git
@ -47,5 +41,3 @@ POM_INCEPTION_YEAR=2009
# Bintray settings to override in $HOME/.gradle/gradle.properties or ENV or commandline
bintray_user=
bintray_api_key=
PREBUILD_NATIVES_URL=https://dl.bintray.com/jmonkeyengine/files/${natives.snapshot}/jme3-natives.zip

Binary file not shown.

@ -1,5 +1,6 @@
#Sat Apr 30 16:44:31 EDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip

48
gradlew vendored

@ -1,20 +1,4 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#!/usr/bin/env bash
##############################################################################
##
@ -44,16 +28,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
warn ( ) {
echo "$*"
}
die () {
die ( ) {
echo
echo "$*"
echo
@ -125,8 +109,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@ -170,19 +154,11 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
APP_ARGS=$(save "$@")
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

24
gradlew.bat vendored

@ -1,19 +1,3 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -30,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@ -65,6 +49,7 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@ -75,6 +60,11 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

@ -1,19 +1,29 @@
apply plugin: 'com.android.application'
dependencies {
compile project(':jme3-core')
compile project(':jme3-android')
compile project(':jme3-effects')
compile project(':jme3-bullet')
compile project(':jme3-bullet-native-android')
compile project(':jme3-networking')
compile project(':jme3-niftygui')
compile project(':jme3-plugins')
compile project(':jme3-terrain')
compile project(':jme3-testdata')
}
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
compileSdkVersion 10
buildToolsVersion "22.0.1"
lintOptions {
// Fix nifty gui referencing "java.awt" package.
disable 'InvalidPackage'
abortOnError false
}
defaultConfig {
applicationId "org.jmonkeyengine.jme3androidexamples"
minSdkVersion 15 // Android 4.0.3 ICE CREAM SANDWICH
targetSdkVersion 28 // Android 9 PIE
applicationId "com.jme3.android"
minSdkVersion 10 // Android 2.3 GINGERBREAD
targetSdkVersion 22 // Android 5.1 LOLLIPOP
versionCode 1
versionName "1.0" // TODO: from settings.gradle
}
@ -21,44 +31,10 @@ android {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
assets {
srcDir 'src/assets'
srcDir '../jme3-testdata/src/main/resources'
srcDir '../jme3-examples/src/main/resources'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:28.0.0'
compile project(':jme3-core')
compile project(':jme3-android')
compile project(':jme3-android-native')
compile project(':jme3-effects')
compile project(':jme3-bullet')
compile project(':jme3-bullet-native-android')
compile project(':jme3-networking')
compile project(':jme3-niftygui')
compile project(':jme3-plugins')
compile project(':jme3-terrain')
compile fileTree(dir: '../jme3-examples/build/libs', include: ['*.jar'], exclude: ['*sources*.*'])
// compile project(':jme3-examples')
}
}

@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\potterec\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

@ -1,13 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

@ -1,50 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.jmonkeyengine.jme3androidexamples">
<application
android:allowBackup="true"
android:icon="@mipmap/mipmap_monkey"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".TestActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape">
</activity>
</application>
package="com.jme3.android">
<!-- Tell the system that you need ES 2.0. -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<!-- Tell the system that you need distinct touches (for the zoom gesture). -->
<uses-feature
android:name="android.hardware.touchscreen.multitouch.distinct"
android:required="true"/>
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="true" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application android:label="@string/app_name" android:allowBackup="true">
<activity android:name="jme3test.android.TestChooserAndroid"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
</manifest>

@ -1,39 +0,0 @@
package jme3test.android;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
* Test case to look for images stored in the Android drawable and mipmap directories. Image files are
* stored in the main->res->drawable-xxxx directories and main->res->mipmap-xxxx directories. The Android OS
* will choose the best matching image based on the device capabilities.
*
* @author iwgeric
*/
public class TestAndroidResources extends SimpleApplication {
@Override
public void simpleInitApp() {
// Create boxes with textures that are stored in the Android Resources Folders
// Images are stored in multiple Drawable and Mipmap directories. Android picks the ones that
// match the device size and density.
Box box1Mesh = new Box(1, 1, 1);
Geometry box1 = new Geometry("Monkey Box 1", box1Mesh);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setTexture("ColorMap", assetManager.loadTexture("drawable_monkey.png"));
box1.setMaterial(mat1);
box1.setLocalTranslation(-2, 0, 0);
rootNode.attachChild(box1);
Box box2Mesh = new Box(1, 1, 1);
Geometry box2 = new Geometry("Monkey Box 2", box2Mesh);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setTexture("ColorMap", assetManager.loadTexture("mipmap_monkey.png"));
box2.setMaterial(mat2);
box2.setLocalTranslation(2, 0, 0);
rootNode.attachChild(box2);
}
}

@ -1,314 +0,0 @@
package jme3test.android;
import com.jme3.app.SimpleApplication;
import com.jme3.input.Joystick;
import com.jme3.input.JoystickAxis;
import com.jme3.input.MouseInput;
import com.jme3.input.SensorJoystickAxis;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Line;
import com.jme3.texture.Texture;
import com.jme3.util.IntMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Example Test Case to test using Android sensors as Joystick axes. Make sure to enable Joystick Events from
* the test chooser menus. Rotating the device will cause the block to rotate. Tapping the screen will cause the
* sensors to be calibrated (reset to zero) at the current orientation. Continuously tapping the screen causes
* the "rumble" to intensify until it reaches the maximum amount and then it shuts off.
*
* @author iwgeric
*/
public class TestAndroidSensors extends SimpleApplication implements ActionListener, AnalogListener {
private static final Logger logger = Logger.getLogger(TestAndroidSensors.class.getName());
private Geometry geomZero = null;
// Map of joysticks saved with the joyId as the key
private IntMap<Joystick> joystickMap = new IntMap<Joystick>();
// flag to allow for the joystick axis to be calibrated on startup
private boolean initialCalibrationComplete = false;
// mappings used for onAnalog
private final String ORIENTATION_X_PLUS = "Orientation_X_Plus";
private final String ORIENTATION_X_MINUS = "Orientation_X_Minus";
private final String ORIENTATION_Y_PLUS = "Orientation_Y_Plus";
private final String ORIENTATION_Y_MINUS = "Orientation_Y_Minus";
private final String ORIENTATION_Z_PLUS = "Orientation_Z_Plus";
private final String ORIENTATION_Z_MINUS = "Orientation_Z_Minus";
// variables to save the current rotation
// Used when controlling the geometry with device orientation
private float[] anglesCurrent = new float[]{0f, 0f, 0f};
private Quaternion rotationQuat = new Quaternion();
// switch to apply an absolute rotation (geometry.setLocalRotation) or
// an incremental constant rotation (geometry.rotate)
// Used when controlling the geometry with device orientation
private boolean useAbsolute = false;
// rotation speed to use when apply constant incremental rotation
// Used when controlling the geometry with device orientation
private float rotationSpeedX = 1f;
private float rotationSpeedY = 1f;
// current intensity of the rumble
float rumbleAmount = 0f;
// toggle to enable rumble
boolean enableRumble = true;
// toggle to enable device orientation in FlyByCamera
boolean enableFlyByCameraRotation = false;
// toggle to enable controlling geometry rotation
boolean enableGeometryRotation = true;
// Make sure to set joystickEventsEnabled = true in MainActivity for Android
private float toDegrees(float rad) {
return rad * FastMath.RAD_TO_DEG;
}
@Override
public void simpleInitApp() {
// useAbsolute = true;
// enableRumble = true;
if (enableFlyByCameraRotation) {
flyCam.setEnabled(true);
} else {
flyCam.setEnabled(false);
}
Mesh lineX = new Line(Vector3f.ZERO, Vector3f.ZERO.add(Vector3f.UNIT_X.mult(3)));
Mesh lineY = new Line(Vector3f.ZERO, Vector3f.ZERO.add(Vector3f.UNIT_Y.mult(3)));
Mesh lineZ = new Line(Vector3f.ZERO, Vector3f.ZERO.add(Vector3f.UNIT_Z.mult(3)));
Geometry geoX = new Geometry("X", lineX);
Material matX = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matX.setColor("Color", ColorRGBA.Red);
matX.getAdditionalRenderState().setLineWidth(30);
geoX.setMaterial(matX);
rootNode.attachChild(geoX);
Geometry geoY = new Geometry("Y", lineY);
Material matY = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matY.setColor("Color", ColorRGBA.Green);
matY.getAdditionalRenderState().setLineWidth(30);
geoY.setMaterial(matY);
rootNode.attachChild(geoY);
Geometry geoZ = new Geometry("Z", lineZ);
Material matZ = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matZ.setColor("Color", ColorRGBA.Blue);
matZ.getAdditionalRenderState().setLineWidth(30);
geoZ.setMaterial(matZ);
rootNode.attachChild(geoZ);
Box b = new Box(1, 1, 1);
geomZero = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Yellow);
Texture tex_ml = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
mat.setTexture("ColorMap", tex_ml);
geomZero.setMaterial(mat);
geomZero.setLocalTranslation(Vector3f.ZERO);
geomZero.setLocalRotation(Quaternion.IDENTITY);
rootNode.attachChild(geomZero);
// Touch (aka MouseInput.BUTTON_LEFT) is used to record the starting
// orientation when using absolute rotations
inputManager.addMapping("MouseClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "MouseClick");
Joystick[] joysticks = inputManager.getJoysticks();
if (joysticks == null || joysticks.length < 1) {
logger.log(Level.INFO, "Cannot find any joysticks!");
} else {
// Joysticks return a value of 0 to 1 based on how far the stick is
// push on the axis. This value is then scaled based on how long
// during the frame the joystick axis has been in that position.
// If the joystick is push all the way for the whole frame,
// then the value in onAnalog is equal to tpf.
// If the joystick is push 1/2 way for the entire frame, then the
// onAnalog value is 1/2 tpf.
// Similarly, if the joystick is pushed to the maximum during a frame
// the value in onAnalog will also be scaled.
// For Android sensors, rotating the device 90deg is the same as
// pushing an actual joystick axis to the maximum.
logger.log(Level.INFO, "Number of joysticks: {0}", joysticks.length);
JoystickAxis axis;
for (Joystick joystick : joysticks) {
// Get and display all axes in joystick.
List<JoystickAxis> axes = joystick.getAxes();
for (JoystickAxis joystickAxis : axes) {
logger.log(Level.INFO, "{0} axis scan Name: {1}, LogicalId: {2}, AxisId: {3}",
new Object[]{joystick.getName(), joystickAxis.getName(), joystickAxis.getLogicalId(), joystickAxis.getAxisId()});
}
// Get specific axis based on LogicalId of the JoystickAxis
// If found, map axis
axis = joystick.getAxis(SensorJoystickAxis.ORIENTATION_X);
if (axis != null) {
axis.assignAxis(ORIENTATION_X_PLUS, ORIENTATION_X_MINUS);
inputManager.addListener(this, ORIENTATION_X_PLUS, ORIENTATION_X_MINUS);
logger.log(Level.INFO, "Found {0} Joystick, assigning mapping for X axis: {1}, with max value: {2}",
new Object[]{joystick.toString(), axis.toString(), ((SensorJoystickAxis) axis).getMaxRawValue()});
}
axis = joystick.getAxis(SensorJoystickAxis.ORIENTATION_Y);
if (axis != null) {
axis.assignAxis(ORIENTATION_Y_PLUS, ORIENTATION_Y_MINUS);
inputManager.addListener(this, ORIENTATION_Y_PLUS, ORIENTATION_Y_MINUS);
logger.log(Level.INFO, "Found {0} Joystick, assigning mapping for Y axis: {1}, with max value: {2}",
new Object[]{joystick.toString(), axis.toString(), ((SensorJoystickAxis) axis).getMaxRawValue()});
}
axis = joystick.getAxis(SensorJoystickAxis.ORIENTATION_Z);
if (axis != null) {
axis.assignAxis(ORIENTATION_Z_PLUS, ORIENTATION_Z_MINUS);
inputManager.addListener(this, ORIENTATION_Z_PLUS, ORIENTATION_Z_MINUS);
logger.log(Level.INFO, "Found {0} Joystick, assigning mapping for Z axis: {1}, with max value: {2}",
new Object[]{joystick.toString(), axis.toString(), ((SensorJoystickAxis) axis).getMaxRawValue()});
}
joystickMap.put(joystick.getJoyId(), joystick);
}
}
}
@Override
public void simpleUpdate(float tpf) {
if (!initialCalibrationComplete) {
// Calibrate the axis (set new zero position) if the axis
// is a sensor joystick axis
for (IntMap.Entry<Joystick> entry : joystickMap) {
for (JoystickAxis axis : entry.getValue().getAxes()) {
if (axis instanceof SensorJoystickAxis) {
logger.log(Level.INFO, "Calibrating Axis: {0}", axis.toString());
((SensorJoystickAxis) axis).calibrateCenter();
}
}
}
initialCalibrationComplete = true;
}
if (enableGeometryRotation) {
rotationQuat.fromAngles(anglesCurrent);
rotationQuat.normalizeLocal();
if (useAbsolute) {
geomZero.setLocalRotation(rotationQuat);
} else {
geomZero.rotate(rotationQuat);
}
anglesCurrent[0] = anglesCurrent[1] = anglesCurrent[2] = 0f;
}
}
public void onAction(String string, boolean pressed, float tpf) {
if (string.equalsIgnoreCase("MouseClick") && pressed) {
// Calibrate the axis (set new zero position) if the axis
// is a sensor joystick axis
for (IntMap.Entry<Joystick> entry : joystickMap) {
for (JoystickAxis axis : entry.getValue().getAxes()) {
if (axis instanceof SensorJoystickAxis) {
logger.log(Level.INFO, "Calibrating Axis: {0}", axis.toString());
((SensorJoystickAxis) axis).calibrateCenter();
}
}
}
if (enableRumble) {
// manipulate joystick rumble
for (IntMap.Entry<Joystick> entry : joystickMap) {
rumbleAmount += 0.1f;
if (rumbleAmount > 1f + FastMath.ZERO_TOLERANCE) {
rumbleAmount = 0f;
}
logger.log(Level.INFO, "rumbling with amount: {0}", rumbleAmount);
entry.getValue().rumble(rumbleAmount);
}
}
}
}
public void onAnalog(String string, float value, float tpf) {
logger.log(Level.INFO, "onAnalog for {0}, value: {1}, tpf: {2}",
new Object[]{string, value, tpf});
float scaledValue = value;
if (string.equalsIgnoreCase(ORIENTATION_X_PLUS)) {
if (useAbsolute) {
// set rotation amount
// divide by tpf to get back to actual axis value (0 to 1)
// multiply by 90deg so that 90deg = full axis (value = tpf)
anglesCurrent[0] = (scaledValue / tpf * FastMath.HALF_PI);
} else {
// apply an incremental rotation amount based on rotationSpeed
anglesCurrent[0] += scaledValue * rotationSpeedX;
}
}
if (string.equalsIgnoreCase(ORIENTATION_X_MINUS)) {
if (useAbsolute) {
// set rotation amount
// divide by tpf to get back to actual axis value (0 to 1)
// multiply by 90deg so that 90deg = full axis (value = tpf)
anglesCurrent[0] = (-scaledValue / tpf * FastMath.HALF_PI);
} else {
// apply an incremental rotation amount based on rotationSpeed
anglesCurrent[0] -= scaledValue * rotationSpeedX;
}
}
if (string.equalsIgnoreCase(ORIENTATION_Y_PLUS)) {
if (useAbsolute) {
// set rotation amount
// divide by tpf to get back to actual axis value (0 to 1)
// multiply by 90deg so that 90deg = full axis (value = tpf)
anglesCurrent[1] = (scaledValue / tpf * FastMath.HALF_PI);
} else {
// apply an incremental rotation amount based on rotationSpeed
anglesCurrent[1] += scaledValue * rotationSpeedY;
}
}
if (string.equalsIgnoreCase(ORIENTATION_Y_MINUS)) {
if (useAbsolute) {
// set rotation amount
// divide by tpf to get back to actual axis value (0 to 1)
// multiply by 90deg so that 90deg = full axis (value = tpf)
anglesCurrent[1] = (-scaledValue / tpf * FastMath.HALF_PI);
} else {
// apply an incremental rotation amount based on rotationSpeed
anglesCurrent[1] -= scaledValue * rotationSpeedY;
}
}
}
}

@ -1,354 +0,0 @@
package jme3test.android;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.font.Rectangle;
import com.jme3.input.*;
import com.jme3.input.controls.*;
import com.jme3.input.event.*;
import com.jme3.math.ColorRGBA;
import com.jme3.ui.Picture;
import java.text.NumberFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Test for Android Touch Input integration into jME3.
*
* @author iwgeric
*/
public class TestAndroidTouch extends SimpleApplication {
private static final Logger logger = Logger.getLogger(TestAndroidTouch.class.getSimpleName());
private Picture picMouseBackground;
private Picture picMouseLeftButton;
private Picture picMouseDisabled;
private BitmapText textMouseAnalog;
private BitmapText textMouseLabel;
private BitmapText textMouseLocation;
private BitmapText textCursorLocation;
private BitmapText textKeyPressed;
private BitmapText textPhoneLabel;
private BitmapText textPhoneLocation;
private Picture picPhone;
private String touchMapping = "touch";
private String mappingKeyPrefix = "key-";
private String mappingMouseLeft = "mouse left";
private String mappingMouseXNeg = "mouse x neg";
private String mappingMouseXPos = "mouse x pos";
private String mappingMouseYNeg = "mouse y neg";
private String mappingMouseYPos = "mouse y pos";
private TouchListener touchListener = new MyTouchListener();
private ActionListener actionListener = new MyActionListener();
private AnalogListener analogListener = new MyAnalogListener();
private RawInputListener rawInputListener = new MyRawInputListener();
private NumberFormat analogFormat = NumberFormat.getNumberInstance();
private NumberFormat locationFormat = NumberFormat.getNumberInstance();
@Override
public void simpleInitApp() {
getViewPort().setBackgroundColor(ColorRGBA.White);
analogFormat.setMaximumFractionDigits(3);
analogFormat.setMinimumFractionDigits(3);
locationFormat.setMaximumFractionDigits(0);
locationFormat.setMinimumFractionDigits(0);
// Setup list of triggers based on different keyboard key codes. For Android, the soft keyboard key events
// are translated into jme key events.
int[] keyCodes = new int[] {
KeyInput.KEY_0, KeyInput.KEY_1, KeyInput.KEY_2, KeyInput.KEY_3, KeyInput.KEY_4, KeyInput.KEY_5,
KeyInput.KEY_6, KeyInput.KEY_7, KeyInput.KEY_8, KeyInput.KEY_9, KeyInput.KEY_DECIMAL, KeyInput.KEY_PERIOD,
KeyInput.KEY_A, KeyInput.KEY_B, KeyInput.KEY_C, KeyInput.KEY_D, KeyInput.KEY_E, KeyInput.KEY_F,
KeyInput.KEY_G, KeyInput.KEY_H, KeyInput.KEY_I, KeyInput.KEY_J, KeyInput.KEY_K, KeyInput.KEY_L,
KeyInput.KEY_M, KeyInput.KEY_N, KeyInput.KEY_O, KeyInput.KEY_P, KeyInput.KEY_Q, KeyInput.KEY_R,
KeyInput.KEY_S, KeyInput.KEY_T, KeyInput.KEY_U, KeyInput.KEY_V, KeyInput.KEY_W, KeyInput.KEY_X,
KeyInput.KEY_Y, KeyInput.KEY_Z, KeyInput.KEY_CAPITAL, KeyInput.KEY_LSHIFT, KeyInput.KEY_RSHIFT,
KeyInput.KEY_UP, KeyInput.KEY_DOWN, KeyInput.KEY_LEFT, KeyInput.KEY_RIGHT
};
for (int idx=0; idx<keyCodes.length; idx++) {
String keyMapping = mappingKeyPrefix + KeyNames.getName(keyCodes[idx]);
inputManager.addMapping(keyMapping, new KeyTrigger(keyCodes[idx]));
inputManager.addListener(actionListener, keyMapping);
logger.log(Level.INFO, "Adding key mapping: {0}", keyMapping);
}
// setup InputManager to trigger our listeners when the various triggers are received.
// Touch inputs are all sent to the TouchTrigger. To have one mapping for all touch events, use TouchInput.ALL.
inputManager.addMapping(touchMapping, new TouchTrigger(TouchInput.ALL));
inputManager.addListener(touchListener, touchMapping);
// If inputManager.isSimulateMouse = true, touch events will be translated into Mouse Button and Axis events.
// To enable this, call inputManager.setSimulateMouse(true).
inputManager.addMapping(mappingMouseLeft, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, mappingMouseLeft);
inputManager.addMapping(mappingMouseXNeg, new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping(mappingMouseXPos, new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addMapping(mappingMouseYNeg, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping(mappingMouseYPos, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
inputManager.addListener(analogListener, mappingMouseXNeg, mappingMouseXPos, mappingMouseYNeg, mappingMouseYPos);
// add raw input listener to inputManager
inputManager.addRawInputListener(rawInputListener);
float mouseSize = (settings.getWidth() >= settings.getHeight())? settings.getHeight()/2f: settings.getWidth()/2f;
picMouseBackground = new Picture("Mouse Background");
picMouseBackground.setImage(assetManager, "mouse_none.png", true);
picMouseBackground.setWidth(mouseSize);
picMouseBackground.setHeight(mouseSize);
picMouseBackground.setLocalTranslation(settings.getWidth()-mouseSize, 0f, 0f);
picMouseLeftButton = new Picture("Mouse Button Left");
picMouseLeftButton.setImage(assetManager, "mouse_left.png", true);
picMouseLeftButton.setWidth(mouseSize);
picMouseLeftButton.setHeight(mouseSize);
picMouseLeftButton.setLocalTranslation(settings.getWidth()-mouseSize, 0f, 1f);
picMouseDisabled = new Picture("Mouse Disabled");
picMouseDisabled.setImage(assetManager, "mouse_disabled.png", true);
picMouseDisabled.setWidth(mouseSize);
picMouseDisabled.setHeight(mouseSize);
picMouseDisabled.setLocalTranslation(settings.getWidth()-mouseSize, 0f, 1f);
float phoneSize = (settings.getWidth() >= settings.getHeight())? settings.getHeight()/2f: settings.getWidth()/2f;
// preload images to send data to gpu to avoid hesitations during run time the first time the image is displayed
renderManager.preloadScene(picMouseBackground);
renderManager.preloadScene(picMouseLeftButton);
renderManager.preloadScene(picMouseDisabled);
guiNode.attachChild(picMouseBackground);
if (inputManager.isSimulateMouse()) {
picMouseDisabled.removeFromParent();
} else {
guiNode.attachChild(picMouseDisabled);
}
textMouseLabel = new BitmapText(guiFont, false);
textMouseLabel.setSize(mouseSize/10f);
textMouseLabel.setColor(ColorRGBA.Blue);
textMouseLabel.setBox(new Rectangle(0f, 0f, mouseSize, mouseSize/5f));
textMouseLabel.setAlignment(BitmapFont.Align.Center);
textMouseLabel.setVerticalAlignment(BitmapFont.VAlign.Bottom);
textMouseLabel.setText("Mouse Analog\nand Position");
textMouseLabel.setLocalTranslation(settings.getWidth()-mouseSize, mouseSize*1.25f, 1f);
guiNode.attachChild(textMouseLabel);
textMouseAnalog = new BitmapText(guiFont, false);
textMouseAnalog.setSize(mouseSize/10f);
textMouseAnalog.setColor(ColorRGBA.Blue);
textMouseAnalog.setBox(new Rectangle(0f, 0f, mouseSize, mouseSize/10f));
textMouseAnalog.setAlignment(BitmapFont.Align.Center);
textMouseAnalog.setVerticalAlignment(BitmapFont.VAlign.Center);
textMouseAnalog.setText("0.000, 0.000");
textMouseAnalog.setLocalTranslation(settings.getWidth()-mouseSize, mouseSize/2f, 2f);
guiNode.attachChild(textMouseAnalog);
textMouseLocation = new BitmapText(guiFont, false);
textMouseLocation.setSize(mouseSize/10f);
textMouseLocation.setColor(ColorRGBA.Blue);
textMouseLocation.setBox(new Rectangle(0f, 0f, mouseSize, mouseSize/10f));
textMouseLocation.setAlignment(BitmapFont.Align.Center);
textMouseLocation.setVerticalAlignment(BitmapFont.VAlign.Center);
textMouseLocation.setText("0, 0");
textMouseLocation.setLocalTranslation(settings.getWidth()-mouseSize, mouseSize/2f-mouseSize/10f, 2f);
guiNode.attachChild(textMouseLocation);
textCursorLocation = new BitmapText(guiFont, false);
textCursorLocation.setSize(mouseSize/10f);
textCursorLocation.setColor(ColorRGBA.Blue);
textCursorLocation.setBox(new Rectangle(0f, 0f, mouseSize, mouseSize/10f));
textCursorLocation.setAlignment(BitmapFont.Align.Center);
textCursorLocation.setVerticalAlignment(BitmapFont.VAlign.Center);
textCursorLocation.setText("0, 0");
textCursorLocation.setLocalTranslation(settings.getWidth()-mouseSize, mouseSize/2f-mouseSize/10f*2f, 2f);
guiNode.attachChild(textCursorLocation);
textKeyPressed = new BitmapText(guiFont, false);
textKeyPressed.setSize(mouseSize/10f);
textKeyPressed.setColor(ColorRGBA.Blue);
textKeyPressed.setBox(new Rectangle(0f, 0f, settings.getWidth(), mouseSize/10f));
textKeyPressed.setAlignment(BitmapFont.Align.Center);
textKeyPressed.setVerticalAlignment(BitmapFont.VAlign.Top);
textKeyPressed.setText("Last Key Pressed: None");
textKeyPressed.setLocalTranslation(0f, settings.getHeight()-mouseSize/10f, 2f);
guiNode.attachChild(textKeyPressed);
picPhone = new Picture("Phone");
picPhone.setImage(assetManager, "phone_landscape.png", true);
picPhone.setWidth(phoneSize);
picPhone.setHeight(phoneSize);
picPhone.setLocalTranslation(picMouseBackground.getLocalTranslation().x - phoneSize, 0f, 1f);
guiNode.attachChild(picPhone);
textPhoneLocation = new BitmapText(guiFont, false);
textPhoneLocation.setSize(phoneSize/10f);
textPhoneLocation.setColor(ColorRGBA.White);
textPhoneLocation.setBox(new Rectangle(0f, 0f, phoneSize, phoneSize/10f));
textPhoneLocation.setAlignment(BitmapFont.Align.Center);
textPhoneLocation.setVerticalAlignment(BitmapFont.VAlign.Center);
textPhoneLocation.setText("0, 0");
textPhoneLocation.setLocalTranslation(picMouseBackground.getLocalTranslation().x - phoneSize, phoneSize*0.5f, 2f);
guiNode.attachChild(textPhoneLocation);
textPhoneLabel = new BitmapText(guiFont, false);
textPhoneLabel.setSize(phoneSize/10f);
textPhoneLabel.setColor(ColorRGBA.Blue);
textPhoneLabel.setBox(new Rectangle(0f, 0f, phoneSize, phoneSize/10f));
textPhoneLabel.setAlignment(BitmapFont.Align.Center);
textPhoneLabel.setVerticalAlignment(BitmapFont.VAlign.Bottom);
textPhoneLabel.setText("Touch Location");
textPhoneLabel.setLocalTranslation(picMouseBackground.getLocalTranslation().x - phoneSize, picPhone.getLocalTranslation().y + phoneSize*0.75f, 1f);
guiNode.attachChild(textPhoneLabel);
renderManager.preloadScene(picPhone);
}
private class MyTouchListener implements TouchListener {
@Override
public void onTouch(String name, TouchEvent event, float tpf) {
String touchEvent = event.toString();
logger.log(Level.INFO, "TouchListenerEvent: {0}", touchEvent);
switch (event.getType()) {
case DOWN:
case UP:
case MOVE:
case SCROLL:
textPhoneLocation.setText(
String.valueOf(locationFormat.format(event.getX())) + ", " +
String.valueOf(locationFormat.format(event.getY())));
break;
default:
}
}
}
protected class MyActionListener implements ActionListener {
@Override
public void onAction(String name, boolean isPressed, float tpf) {
logger.log(Level.INFO, "ActionListenerEvent[name:{0}, pressed: {1}, tpf: {2}",
new Object[]{name, isPressed, tpf});
if (name.equalsIgnoreCase(mappingMouseLeft)) {
if (isPressed) {
guiNode.attachChild(picMouseLeftButton);
} else {
picMouseLeftButton.removeFromParent();
}
textCursorLocation.setText(
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getX())) + ", " +
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getY())));
} else if (name.startsWith(mappingKeyPrefix)) {
logger.log(Level.INFO, "key event name: {0}, pressed: {1}", new Object[]{name, isPressed});
if (isPressed) {
textKeyPressed.setText("Last Key Pressed: " + name.substring(mappingKeyPrefix.length(), name.length()));
} else {
// textKeyPressed.setText("Key Pressed: None");
}
}
}
}
protected class MyAnalogListener implements AnalogListener {
float lastValueX = 0;
float lastValueY = 0;
@Override
public void onAnalog(String name, float value, float tpf) {
logger.log(Level.INFO, "AnalogListenerEvent[name:{0}, value: {1}, tpf: {2}",
new Object[]{name, value, tpf});
if (name.equalsIgnoreCase(mappingMouseXPos)) {
setValueX(value);
} else if (name.equalsIgnoreCase(mappingMouseXNeg)) {
setValueX(-value);
} else if (name.equalsIgnoreCase(mappingMouseYPos)) {
setValueY(value);
} else if (name.equalsIgnoreCase(mappingMouseYNeg)) {
setValueY(-value);
}
}
public void setValueX(float x) {
lastValueX = x;
textMouseAnalog.setText(
String.valueOf(analogFormat.format(lastValueX)) + ", " + String.valueOf(analogFormat.format(lastValueY)));
textCursorLocation.setText(
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getX())) + ", " +
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getY())));
}
public void setValueY(float y) {
lastValueY = y;
textMouseAnalog.setText(
String.valueOf(analogFormat.format(lastValueX)) + ", " + String.valueOf(analogFormat.format(lastValueY)));
textCursorLocation.setText(
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getX())) + ", " +
String.valueOf(locationFormat.format(inputManager.getCursorPosition().getY())));
}
}
protected class MyRawInputListener implements RawInputListener {
@Override
public void beginInput() {
// logger.log(Level.INFO, "RawInputListenerEvent: BeginInput");
}
@Override
public void endInput() {
// logger.log(Level.INFO, "RawInputListenerEvent: EndInput");
}
@Override
public void onJoyAxisEvent(JoyAxisEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
}
@Override
public void onJoyButtonEvent(JoyButtonEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
}
@Override
public void onMouseMotionEvent(MouseMotionEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
textMouseLocation.setText(
String.valueOf(locationFormat.format(event.getX())) + ", " + String.valueOf(locationFormat.format(event.getY())));
}
@Override
public void onMouseButtonEvent(MouseButtonEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
textMouseLocation.setText(
String.valueOf(locationFormat.format(event.getX())) + ", " + String.valueOf(locationFormat.format(event.getY())));
}
@Override
public void onKeyEvent(KeyInputEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
}
@Override
public void onTouchEvent(TouchEvent event) {
logger.log(Level.INFO, "RawInputListenerEvent: {0}", event);
}
}
}

@ -0,0 +1,12 @@
package jme3test.android;
import android.content.pm.ActivityInfo;
import android.app.*;
import android.os.Bundle;
public class TestChooserAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

@ -1,165 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class CustomArrayAdapter extends ArrayAdapter<String> {
private static final String TAG = "CustomArrayAdapter";
/* List of items */
private List<String> entries;
private Context activity;
/* Position of selected answer */
private int selectedPosition = -1;
/* Background Color of selected item */
private int selectedBackgroundColor = 0xffff00;
/* Background Color of non selected item */
private int nonselectedBackgroundColor = 0x000000;
/* Background Drawable Resource ID of selected item */
private int selectedBackgroundResource = 0;
/* Background Drawable Resource ID of non selected items */
private int nonselectedBackgroundResource = 0;
/* Variables to support list filtering */
private ArrayList<String> filteredEntries;
private Filter filter;
public CustomArrayAdapter(Context context, int textViewResourceId, List<String> objects) {
super(context, textViewResourceId, objects);
activity = context;
entries = new ArrayList<String>(objects);
filteredEntries = new ArrayList<String>(objects);
filter = new ClassNameFilter();
}
/** Setter for selected item position */
public void setSelectedPosition(int selectedPosition) {
this.selectedPosition = selectedPosition;
Log.i(TAG, "Setting position to: " + this.selectedPosition);
}
/** Setter for selected item background color */
public void setSelectedBackgroundColor(int selectedBackgroundColor) {
this.selectedBackgroundColor = selectedBackgroundColor;
}
/** Setter for non selected background color */
public void setNonSelectedBackgroundColor(int nonselectedBackgroundColor) {
this.nonselectedBackgroundColor = nonselectedBackgroundColor;
}
/** Setter for selected item background resource id*/
public void setSelectedBackgroundResource(int selectedBackgroundResource) {
this.selectedBackgroundResource = selectedBackgroundResource;
}
/** Setter for non selected background resource id*/
public void setNonSelectedBackgroundResource(int nonselectedBackgroundResource) {
this.nonselectedBackgroundResource = nonselectedBackgroundResource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.i(TAG, "getView for position: " + position + " with selectedItem: " + selectedPosition);
View v = convertView;
ViewHolder holder;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.test_chooser_row, null);
holder = new ViewHolder();
holder.textView = (TextView) v.findViewById(R.id.txtClassName);
holder.layoutRow = (LinearLayout) v.findViewById(R.id.layoutTestChooserRow);
v.setTag(holder);
} else {
holder=(ViewHolder)v.getTag();
}
final String itemText = filteredEntries.get(position);
if (itemText != null) {
holder.textView.setText(itemText);
if (position == selectedPosition) {
Log.i(TAG, "setting Background Color to: " + selectedBackgroundColor);
// holder.textView.setBackgroundColor(selectedBackgroundColor);
// holder.textView.setBackgroundResource(selectedBackgroundResource);
holder.layoutRow.setBackgroundResource(selectedBackgroundResource);
} else {
Log.i(TAG, "setting Background Color to: " + nonselectedBackgroundColor);
// holder.textView.setBackgroundColor(nonselectedBackgroundColor);
// holder.textView.setBackgroundResource(nonselectedBackgroundResource);
holder.layoutRow.setBackgroundResource(nonselectedBackgroundResource);
}
}
return v;
}
@Override
public Filter getFilter(){
if(filter == null){
filter = new ClassNameFilter();
}
return filter;
}
public static class ViewHolder{
public TextView textView;
public LinearLayout layoutRow;
}
private class ClassNameFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint){
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
Log.i(TAG, "performFiltering: entries size: " + entries.size());
if (prefix == null || prefix.length() == 0){
ArrayList<String> list = new ArrayList<String>(entries);
results.values = list;
results.count = list.size();
Log.i(TAG, "clearing filter with size: " + list.size());
}else{
final ArrayList<String> list = new ArrayList<String>(entries);
final ArrayList<String> nlist = new ArrayList<String>();
int count = list.size();
for (int i = 0; i<count; i++){
if(list.get(i).toLowerCase().contains(prefix)){
nlist.add(list.get(i));
}
results.values = nlist;
results.count = nlist.size();
}
Log.i(TAG, "filtered list size: " + nlist.size() + ", entries size: " + entries.size());
}
Log.i(TAG, "Returning filter count: " + results.count);
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredEntries = (ArrayList<String>)results.values;
notifyDataSetChanged();
clear();
int count = filteredEntries.size();
for(int i = 0; i<count; i++){
add(filteredEntries.get(i));
notifyDataSetInvalidated();
}
Log.i(TAG, "publishing results with size: " + count);
}
}
}

@ -1,85 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import android.os.Bundle;
import com.jme3.app.AndroidHarnessFragment;
import java.util.logging.Level;
import java.util.logging.LogManager;
/**
* A placeholder fragment containing a jME GLSurfaceView.
*/
public class JmeFragment extends AndroidHarnessFragment {
public JmeFragment() {
// Set the desired EGL configuration
eglBitsPerPixel = 24;
eglAlphaBits = 0;
eglDepthBits = 16;
eglSamples = 0;
eglStencilBits = 0;
// Set the maximum framerate
// (default = -1 for unlimited)
frameRate = -1;
// Set the maximum resolution dimension
// (the smaller side, height or width, is set automatically
// to maintain the original device screen aspect ratio)
// (default = -1 to match device screen resolution)
maxResolutionDimension = -1;
/*
Skip these settings and use the settings stored in the Bundle retrieved during onCreate.
// Set main project class (fully qualified path)
appClass = "";
// Set input configuration settings
joystickEventsEnabled = false;
keyEventsEnabled = true;
mouseEventsEnabled = true;
*/
// Set application exit settings
finishOnAppStop = true;
handleExitHook = true;
exitDialogTitle = "Do you want to exit?";
exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
// Set splash screen resource id, if used
// (default = 0, no splash screen)
// For example, if the image file name is "splash"...
// splashPicID = R.drawable.splash;
splashPicID = 0;
// splashPicID = R.drawable.android_splash;
// Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
}
@Override
public void onCreate(Bundle savedInstanceState) {
Bundle bundle=getArguments();
appClass = bundle.getString(MainActivity.SELECTED_APP_CLASS);
// Log.d(this.getClass().getSimpleName(), "AppClass: " + appClass);
joystickEventsEnabled = bundle.getBoolean(MainActivity.ENABLE_JOYSTICK_EVENTS);
// Log.d(this.getClass().getSimpleName(), "JoystickEventsEnabled: " + joystickEventsEnabled);
keyEventsEnabled = bundle.getBoolean(MainActivity.ENABLE_KEY_EVENTS);
// Log.d(this.getClass().getSimpleName(), "KeyEventsEnabled: " + keyEventsEnabled);
mouseEventsEnabled = bundle.getBoolean(MainActivity.ENABLE_MOUSE_EVENTS);
// Log.d(this.getClass().getSimpleName(), "MouseEventsEnabled: " + mouseEventsEnabled);
boolean verboseLogging = bundle.getBoolean(MainActivity.VERBOSE_LOGGING);
// Log.d(this.getClass().getSimpleName(), "VerboseLogging: " + verboseLogging);
if (verboseLogging) {
// Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
LogManager.getLogManager().getLogger("").setLevel(Level.ALL);
} else {
// Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
}
super.onCreate(savedInstanceState);
}
}

@ -1,458 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import com.jme3.app.Application;
import dalvik.system.DexFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
//TODO: Create onscreen virtual keypad for triggering normal mapped keys used by test apps or modify test apps for touch with onscreen keypad
/**
* Main Activity started by the application. Users select different jME3 test
* applications that are started via TestsHarness Activity.
* @author iwgeric
*/
public class MainActivity extends AppCompatActivity implements OnItemClickListener, View.OnClickListener, TextWatcher {
private static final String TAG = "MainActivity";
/**
* Static String to pass the key for the selected test app to the
* TestsHarness class to start the application. Also used to store the
* current selection to the savedInstanceState Bundle.
*/
public static final String SELECTED_APP_CLASS = "Selected_App_Class";
/**
* Static String to pass the key for the selected list position to the
* savedInstanceState Bundle so the list position can be restored after
* exiting the test application.
*/
public static final String SELECTED_LIST_POSITION = "Selected_List_Position";
/**
* Static String to pass the key for the setting for enabling mouse events to the
* savedInstanceState Bundle.
*/
public static final String ENABLE_MOUSE_EVENTS = "Enable_Mouse_Events";
/**
* Static String to pass the key for the setting for enabling joystick events to the
* savedInstanceState Bundle.
*/
public static final String ENABLE_JOYSTICK_EVENTS = "Enable_Joystick_Events";
/**
* Static String to pass the key for the setting for enabling key events to the
* savedInstanceState Bundle.
*/
public static final String ENABLE_KEY_EVENTS = "Enable_Key_Events";
/**
* Static String to pass the key for the setting for verbose logging to the
* savedInstanceState Bundle.
*/
public static final String VERBOSE_LOGGING = "Verbose_Logging";
/* Fields to contain the current position and display contents of the spinner */
private int currentPosition = 0;
private String currentSelection = "";
private List<String> classNames = new ArrayList<String>();
private List<String> exclusions = new ArrayList<String>();
private String rootPackage;
/* ListView that displays the test application class names. */
private ListView listClasses;
/* ArrayAdapter connects the spinner widget to array-based data. */
private CustomArrayAdapter arrayAdapter;
/* Buttons to start application or stop the activity. */
private Button btnOK;
private Button btnCancel;
/* Filter Edit Box */
EditText editFilterText;
/* Custom settings for the test app */
private boolean enableMouseEvents = true;
private boolean enableJoystickEvents = false;
private boolean enableKeyEvents = true;
private boolean verboseLogging = false;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
Log.d(TAG, "Restoring selections in onCreate: "
+ "position: " + savedInstanceState.getInt(SELECTED_LIST_POSITION, 0)
+ "class: " + savedInstanceState.getString(SELECTED_APP_CLASS)
);
currentPosition = savedInstanceState.getInt(SELECTED_LIST_POSITION, 0);
currentSelection = savedInstanceState.getString(SELECTED_APP_CLASS);
enableMouseEvents = savedInstanceState.getBoolean(ENABLE_MOUSE_EVENTS, true);
enableJoystickEvents = savedInstanceState.getBoolean(ENABLE_JOYSTICK_EVENTS, false);
enableKeyEvents = savedInstanceState.getBoolean(ENABLE_KEY_EVENTS, true);
verboseLogging = savedInstanceState.getBoolean(VERBOSE_LOGGING, true);
}
/* Set content view and register views */
setContentView(R.layout.test_chooser_layout);
btnOK = (Button) findViewById(R.id.btnOK);
btnCancel = (Button) findViewById(R.id.btnCancel);
listClasses = (ListView) findViewById(R.id.listClasses);
editFilterText = (EditText) findViewById(R.id.txtFilter);
/* Define the root package to start with */
rootPackage = "jme3test";
/* Create an array of Strings to define which classes to exclude */
exclusions.add("$"); // inner classes
exclusions.add("TestChooser"); // Desktop test chooser class
exclusions.add("awt"); // Desktop test chooser class
// mExclusions.add("");
/*
* Read the class names from the dex file and filter based on
* name and super class.
*/
Log.d(TAG, "Composing Test list...");
ApplicationInfo ai = this.getApplicationInfo();
String classPath = ai.sourceDir;
DexFile dex = null;
Enumeration<String> apkClassNames = null;
try {
dex = new DexFile(classPath);
apkClassNames = dex.entries();
while (apkClassNames.hasMoreElements()) {
String className = apkClassNames.nextElement();
if (checkClassName(className) && checkClassType(className)) {
classNames.add(className);
}
// classNames.add(className);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
dex.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* Create a backing Adapter for the List View from a list of the
* classes. The list is defined by array of class names.
*/
arrayAdapter = new CustomArrayAdapter(
this,
R.layout.test_chooser_row, // text view to display selection
classNames // array of strings to display
);
/* Set the resource id for selected and non selected backgrounds */
Log.d(TAG, "Setting Adapter Background Resource IDs");
arrayAdapter.setSelectedBackgroundResource(R.drawable.selected);
arrayAdapter.setNonSelectedBackgroundResource(R.drawable.nonselected);
/* Attach the Adapter to the spinner */
Log.d(TAG, "Setting ListView Adapter");
listClasses.setAdapter(arrayAdapter);
/* Set initial selection for the list */
setSelection(currentPosition);
/* Set Click and Text Changed listeners */
listClasses.setOnItemClickListener(this);
btnOK.setOnClickListener(this);
btnCancel.setOnClickListener(this);
editFilterText.addTextChangedListener(this);
}
/**
* User selected an application. Sets the current selection and redraws
* the list view to highlight the selected item.
* @param parent AdapterView tied to the list
* @param view The ListView
* @param position Selection position in the list of class names
* @param id
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setSelection(position);
}
/**
* User clicked a view on the screen. Check for the OK and Cancel buttons
* and either start the application or exit.
* @param view
*/
public void onClick(View view) {
if (view.equals(btnOK)) {
/* Get selected class, pack it in the intent and start the test app */
Log.d(TAG, "User selected OK for class: " + currentSelection);
Intent intent = new Intent(this, TestActivity.class);
// intent.putExtra(SELECTED_APP_CLASS, currentSelection);
// intent.putExtra(ENABLE_MOUSE_EVENTS, enableMouseEvents);
// intent.putExtra(ENABLE_JOYSTICK_EVENTS, enableJoystickEvents);
// intent.putExtra(ENABLE_KEY_EVENTS, enableKeyEvents);
Bundle args = new Bundle();
args.putString(MainActivity.SELECTED_APP_CLASS, currentSelection);
// Log.d(this.getClass().getSimpleName(), "AppClass="+currentSelection);
args.putBoolean(MainActivity.ENABLE_MOUSE_EVENTS, enableMouseEvents);
// Log.d(TestActivity.class.getSimpleName(), "MouseEnabled="+enableMouseEvents);
args.putBoolean(MainActivity.ENABLE_JOYSTICK_EVENTS, enableJoystickEvents);
// Log.d(TestActivity.class.getSimpleName(), "JoystickEnabled="+enableJoystickEvents);
args.putBoolean(MainActivity.ENABLE_KEY_EVENTS, enableKeyEvents);
// Log.d(TestActivity.class.getSimpleName(), "KeyEnabled="+enableKeyEvents);
args.putBoolean(MainActivity.VERBOSE_LOGGING, verboseLogging);
// Log.d(TestActivity.class.getSimpleName(), "VerboseLogging="+verboseLogging);
intent.putExtras(args);
startActivity(intent);
} else if (view.equals(btnCancel)) {
/* Exit */
Log.d(TAG, "User selected Cancel");
finish();
}
}
/**
* Check class name to see if the class is in the root package and if it
* contains any of the exclusion strings
* @param className Class name to check
* @return true if the check passes, false otherwise
*/
private boolean checkClassName(String className) {
boolean include = true;
/* check to see if the class in inside the rootPackage package */
if (className.startsWith(rootPackage)) {
/* check to see if the class contains any of the exlusion strings */
for (int i = 0; i < exclusions.size(); i++) {
if (className.contains(exclusions.get(i))) {
Log.d(TAG, "Skipping Class " + className + ". Includes exclusion string: " + exclusions.get(i) + ".");
include = false;
break;
}
}
} else {
include = false;
Log.d(TAG, "Skipping Class " + className + ". Not in the root package: " + rootPackage + ".");
}
return include;
}
/**
* Check to see if the class extends Application or SimpleApplication
* @param className Class name to check
* @return true if the check passes, false otherwise
*/
private boolean checkClassType(String className) {
boolean include = true;
try {
Class<?> clazz = Class.forName(className);
if (Application.class.isAssignableFrom(clazz)) {
Log.d(TAG, "Class " + className + " is a jME Application");
} else {
include = false;
Log.d(TAG, "Skipping Class " + className + ". Not a jME Application");
}
} catch (NoClassDefFoundError ncdf) {
include = false;
Log.d(TAG, "Skipping Class " + className + ". No Class Def found.");
} catch (ClassNotFoundException cnfe) {
include = false;
Log.d(TAG, "Skipping Class " + className + ". Class not found.");
}
return include;
}
private void setSelection(int position) {
if (position == -1) {
arrayAdapter.setSelectedPosition(-1);
currentPosition = -1;
currentSelection = "";
btnOK.setEnabled(false);
listClasses.invalidateViews();
} else {
arrayAdapter.setSelectedPosition(position);
currentPosition = position;
currentSelection = arrayAdapter.getItem(position);
btnOK.setEnabled(true);
listClasses.invalidateViews();
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.d(TAG, "Saving selections in onSaveInstanceState: "
+ "position: " + currentPosition + ", "
+ "class: " + currentSelection + ", "
+ "mouseEvents: " + enableMouseEvents + ", "
+ "joystickEvents: " + enableJoystickEvents + ", "
+ "keyEvents: " + enableKeyEvents + ", "
+ "VerboseLogging: " + verboseLogging + ", "
);
// Save current selections to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putString(SELECTED_APP_CLASS, currentSelection);
savedInstanceState.putInt(SELECTED_LIST_POSITION, currentPosition);
savedInstanceState.putBoolean(ENABLE_MOUSE_EVENTS, enableMouseEvents);
savedInstanceState.putBoolean(ENABLE_JOYSTICK_EVENTS, enableJoystickEvents);
savedInstanceState.putBoolean(ENABLE_KEY_EVENTS, enableKeyEvents);
savedInstanceState.putBoolean(VERBOSE_LOGGING, verboseLogging);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Log.i(TAG, "Restoring selections in onRestoreInstanceState: "
// + "position: " + savedInstanceState.getInt(SELECTED_LIST_POSITION, 0)
// + "class: " + savedInstanceState.getString(SELECTED_APP_CLASS)
// );
// //Restore selections from the savedInstanceState.
// // This bundle has also been passed to onCreate.
// currentPosition = savedInstanceState.getInt(SELECTED_LIST_POSITION, 0);
// currentSelection = savedInstanceState.getString(SELECTED_APP_CLASS);
}
public void beforeTextChanged(CharSequence cs, int i, int i1, int i2) {
}
public void onTextChanged(CharSequence cs, int startPos, int beforePos, int count) {
Log.d(TAG, "onTextChanged with cs: " + cs + ", startPos: " + startPos + ", beforePos: " + beforePos + ", count: " + count);
arrayAdapter.getFilter().filter(cs.toString());
setSelection(-1);
}
public void afterTextChanged(Editable edtbl) {
}
@Override
protected void onDestroy() {
super.onDestroy();
editFilterText.removeTextChangedListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_items, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
MenuItem item;
item = menu.findItem(R.id.optionMouseEvents);
if (item != null) {
Log.d(TAG, "Found EnableMouseEvents menu item");
if (enableMouseEvents) {
item.setTitle(R.string.strOptionDisableMouseEventsTitle);
} else {
item.setTitle(R.string.strOptionEnableMouseEventsTitle);
}
}
item = menu.findItem(R.id.optionJoystickEvents);
if (item != null) {
Log.d(TAG, "Found EnableJoystickEvents menu item");
if (enableJoystickEvents) {
item.setTitle(R.string.strOptionDisableJoystickEventsTitle);
} else {
item.setTitle(R.string.strOptionEnableJoystickEventsTitle);
}
}
item = menu.findItem(R.id.optionKeyEvents);
if (item != null) {
Log.d(TAG, "Found EnableKeyEvents menu item");
if (enableKeyEvents) {
item.setTitle(R.string.strOptionDisableKeyEventsTitle);
} else {
item.setTitle(R.string.strOptionEnableKeyEventsTitle);
}
}
item = menu.findItem(R.id.optionVerboseLogging);
if (item != null) {
Log.d(TAG, "Found EnableVerboseLogging menu item");
if (verboseLogging) {
item.setTitle(R.string.strOptionDisableVerboseLoggingTitle);
} else {
item.setTitle(R.string.strOptionEnableVerboseLoggingTitle);
}
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.optionMouseEvents:
enableMouseEvents = !enableMouseEvents;
Log.d(TAG, "enableMouseEvents set to: " + enableMouseEvents);
break;
case R.id.optionJoystickEvents:
enableJoystickEvents = !enableJoystickEvents;
Log.d(TAG, "enableJoystickEvents set to: " + enableJoystickEvents);
break;
case R.id.optionKeyEvents:
enableKeyEvents = !enableKeyEvents;
Log.d(TAG, "enableKeyEvents set to: " + enableKeyEvents);
break;
case R.id.optionVerboseLogging:
verboseLogging = !verboseLogging;
Log.d(TAG, "verboseLogging set to: " + verboseLogging);
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
}

@ -1,111 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.jme3.system.JmeSystem;
public class TestActivity extends AppCompatActivity {
JmeFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
fragment = new JmeFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
Bundle bundle = savedInstanceState;
if (bundle == null) {
bundle = getIntent().getExtras();
}
String appClass = bundle.getString(MainActivity.SELECTED_APP_CLASS);
args.putString(MainActivity.SELECTED_APP_CLASS, appClass);
// Log.d(TestActivity.class.getSimpleName(), "AppClass="+appClass);
boolean mouseEnabled = bundle.getBoolean(MainActivity.ENABLE_MOUSE_EVENTS, true);
args.putBoolean(MainActivity.ENABLE_MOUSE_EVENTS, mouseEnabled);
// Log.d(TestActivity.class.getSimpleName(), "MouseEnabled="+mouseEnabled);
boolean joystickEnabled = bundle.getBoolean(MainActivity.ENABLE_JOYSTICK_EVENTS, true);
args.putBoolean(MainActivity.ENABLE_JOYSTICK_EVENTS, joystickEnabled);
// Log.d(TestActivity.class.getSimpleName(), "JoystickEnabled="+joystickEnabled);
boolean keyEnabled = bundle.getBoolean(MainActivity.ENABLE_KEY_EVENTS, true);
args.putBoolean(MainActivity.ENABLE_KEY_EVENTS, keyEnabled);
// Log.d(TestActivity.class.getSimpleName(), "KeyEnabled="+keyEnabled);
boolean verboseLogging = bundle.getBoolean(MainActivity.VERBOSE_LOGGING, true);
args.putBoolean(MainActivity.VERBOSE_LOGGING, verboseLogging);
// Log.d(TestActivity.class.getSimpleName(), "VerboseLogging="+verboseLogging);
fragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.add(R.id.fragmentContainer, fragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.test_menu_items, menu);
return true;
}
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
MenuItem item;
item = menu.findItem(R.id.optionToggleKeyboard);
if (item != null) {
// Log.d(this.getClass().getSimpleName(), "Found ToggleKeyboard menu item");
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.optionToggleKeyboard:
toggleKeyboard(true);
// Log.d(this.getClass().getSimpleName(), "showing soft keyboard");
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
private void toggleKeyboard(final boolean show) {
fragment.getView().getHandler().post(new Runnable() {
@Override
public void run() {
JmeSystem.showSoftKeyboard(show);
}
});
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:keepScreenOn="true"
tools:context="org.jmonkeyengine.jme3androidexamples.TestActivity">
<!--
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="org.jmonkeyengine.jme3androidexamples.JmeFragment"
android:id="@+id/jMEFragment"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"/>
-->
</RelativeLayout>

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutTestChooser"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
>
<TextView
android:id="@+id/lblTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="@string/strLblTitle"
android:textSize="20sp"
android:textColor="#000000"
/>
<LinearLayout
android:id="@+id/layoutFilter"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/lblTitle"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/lblFindTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/strLblFindTitle"
android:textSize="20sp"
android:textColor="#000000"
/>
<EditText
android:id="@+id/txtFilter"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="@string/strTxtFilterHint"
android:inputType="text"
android:textSize="20sp"
android:textColor="#000000"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/layoutButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:layout_marginTop="20dp"
android:focusable="true"
android:focusableInTouchMode="true"
>
<Button
android:id="@+id/btnOK"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="@string/strBtnOK"
android:layout_marginRight="20dp"
android:textSize="20sp"
android:textColor="#000000"
/>
<Button
android:id="@+id/btnCancel"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="@string/strBtnCancel"
android:layout_marginLeft="20dp"
android:textSize="20sp"
android:textColor="#000000"
/>
<requestFocus/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/layoutButtons"
android:layout_below="@id/layoutFilter"
android:gravity="center"
android:background="@drawable/selected"
>
<ListView
android:id="@+id/listClasses"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:choiceMode="singleChoice"
android:listSelector="@drawable/selected"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:textFilterEnabled="true"
>
</ListView>
</LinearLayout>
</RelativeLayout>

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutTestChooserRow"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<!--
<ImageView android:id="@+id/imgIcon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_marginRight="15dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
-->
<TextView android:id="@+id/txtClassName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:textStyle="bold"
android:textSize="22sp"
android:textColor="#000000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp" />
</LinearLayout>

@ -1,33 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.jmonkeyengine.jme3androidexamples.MainActivity">
<item
android:id="@+id/optionMouseEvents"
android:orderInCategory="100"
android:title="@string/strOptionEnableMouseEventsTitle"
app:showAsAction="never" />
<item
android:id="@+id/optionJoystickEvents"
android:orderInCategory="200"
android:title="@string/strOptionEnableJoystickEventsTitle"
app:showAsAction="never" />
<item
android:id="@+id/optionKeyEvents"
android:orderInCategory="300"
android:title="@string/strOptionEnableKeyEventsTitle"
app:showAsAction="never" />
<item
android:id="@+id/optionVerboseLogging"
android:orderInCategory="300"
android:title="@string/strOptionEnableVerboseLoggingTitle"
app:showAsAction="never" />
<!--
android:icon="@mipmap/redmonkey"
android:icon="@mipmap/greenmonkey"
android:icon="@mipmap/bluemonkey"
-->
</menu>

@ -1,19 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.jmonkeyengine.jme3androidexamples.MainActivity">
<item
android:id="@+id/optionToggleKeyboard"
android:orderInCategory="100"
android:title="@string/strOptionShowKeyboard"
app:showAsAction="ifRoom"
android:icon="@drawable/keyboard"
/>
<!--
android:icon="@mipmap/redmonkey"
android:icon="@mipmap/greenmonkey"
android:icon="@mipmap/bluemonkey"
-->
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

@ -1,6 +0,0 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">0dp</dimen>
</resources>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

@ -1,5 +0,0 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">0dp</dimen>
<dimen name="activity_vertical_margin">0dp</dimen>
</resources>

@ -1,26 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Main Application Title -->
<string name="app_name">jME3 Tests Android</string>
<!-- MainActivity UIF Labels -->
<string name="strLblTitle">Choose a demo to start:</string>
<string name="strLblFindTitle">Find:</string>
<string name="strTxtFilterHint">Enter a Filter</string>
<string name="strBtnOK">OK</string>
<string name="strBtnCancel">Cancel</string>
<!-- MainActivity Menu Labels -->
<string name="strOptionEnableMouseEventsTitle">Enable Mouse Events</string>
<string name="strOptionDisableMouseEventsTitle">Disable Mouse Events</string>
<string name="strOptionEnableJoystickEventsTitle">Enable Joystick Events</string>
<string name="strOptionDisableJoystickEventsTitle">Disable Joystick Events</string>
<string name="strOptionEnableKeyEventsTitle">Enable Key Events</string>
<string name="strOptionDisableKeyEventsTitle">Disable Key Events</string>
<string name="strOptionEnableVerboseLoggingTitle">Enable Verbose Logging</string>
<string name="strOptionDisableVerboseLoggingTitle">Disable Verbose Logging</string>
<!-- TestActivity Menu Labels -->
<string name="strOptionShowKeyboard">Show Keyboard</string>
<string name="strOptionHideKeyboard">Show Keyboard</string>
</resources>
<string name="app_name">JMEAndroidTest</string>
<string name="about">About</string>
<string name="quit">Quit</string>
</resources>

@ -1,11 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

@ -1,15 +0,0 @@
package org.jmonkeyengine.jme3androidexamples;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

@ -1,2 +0,0 @@
# The headers are autogenerated and nobody should try to commit them...
src/native/headers

@ -46,4 +46,4 @@ ext {
apply from: file('openalsoft.gradle')
// apply from: file('stb_image.gradle')
// apply from: file('tremor.gradle')
apply from: file('decode.gradle')
apply from: file('decode.gradle')

@ -1,43 +1,40 @@
String tremorZipFile = "TremorAndroid.zip"
String stbiUrl = 'https://raw.githubusercontent.com/jMonkeyEngine/stb/0224a44a10564a214595797b4c88323f79a5f934/stb_image.h'
String stbiUrl = 'https://raw.githubusercontent.com/nothings/stb/master/stb_image.h'
// Working directories for the ndk build.
String decodeBuildDir = "${buildDir}" + File.separator + 'decode'
String decodeClassesBuildDir = "${buildDir}" + File.separator + 'decode_classes'
String decodeBuildJniDir = decodeBuildDir + File.separator + 'jni'
String decodeBuildLibsDir = decodeBuildDir + File.separator + 'libs'
// Pre-compiled libs directory
def rootPath = rootProject.projectDir.absolutePath
String decodePreCompiledLibsDir = rootPath + File.separator + 'build' + File.separator + 'native' + File.separator + 'android' + File.separator + 'decode'
String decodePreCompiledLibsDir = 'libs' + File.separator + 'decode'
// jME Android Native source files path
String decodeSourceDir = 'src/native/jme_decode'
String jmeHeaders = 'src/native/headers'
task downloadStbImage(type: MyDownload) {
sourceUrl = stbiUrl
target = file(decodeBuildDir + File.separator + 'stb_image.h')
target = file('stb_image.h')
}
// Copy stb_image.h to the jni directory.
// Copy stb_image.h to the source directory.
task copyStbiFiles(type: Copy) {
def sourceDir = file(decodeBuildDir + File.separator + 'stb_image.h')
def outputDir = file(decodeBuildJniDir + File.separator + "STBI")
def sourceDir = file('stb_image.h')
def outputDir = file(decodeSourceDir + File.separator + "STBI")
from sourceDir
into outputDir
}
copyStbiFiles.dependsOn {
def stbiFile = file(decodeBuildDir + File.separator + 'stb_image.h')
def stbiFile = file('stb_image.h')
if (!stbiFile.exists()) {
downloadStbImage
}
}
// Copy libtremor source to the jni directory.
// Copy libtremor source to the source directory.
task copyTremorFiles(type: Copy) {
def zipFile = file(tremorZipFile)
def outputDir = file(decodeBuildJniDir + File.separator + "Tremor")
def outputDir = file(decodeSourceDir + File.separator + "Tremor")
from (zipTree(zipFile)) {
include '*.c'
@ -47,13 +44,17 @@ task copyTremorFiles(type: Copy) {
into outputDir
}
task copyJmeHeadersDecode(type: Copy) {
from file(jmeHeaders)
into file(decodeBuildJniDir + File.separator + "headers")
// Generate headers via javah
task generateJavahHeaders(type: Exec) {
executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
args '-d', decodeSourceDir
args '-classpath', project.projectClassPath
args "com.jme3.audio.plugins.NativeVorbisFile"
args "com.jme3.texture.plugins.AndroidNativeImageLoader"
}
// Copy jME Android native files to jni directory
task copySourceToBuild(type: Copy, dependsOn:[copyTremorFiles, copyStbiFiles, copyJmeHeadersDecode]) {
task copySourceToBuild(type: Copy, dependsOn:[copyTremorFiles, copyStbiFiles, generateJavahHeaders]) {
def sourceDir = file(decodeSourceDir)
def outputDir = file(decodeBuildJniDir)

@ -1,42 +1,39 @@
// OpenAL Soft r1.16
String openALSoftUrl = 'https://github.com/jMonkeyEngine/openal-soft/archive/e5016f814a265ed592a88acea95cf912c4bfdf12.zip'
String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/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-e5016f814a265ed592a88acea95cf912c4bfdf12'
String openALSoftFolder = 'openal-soft'
//Working directories for the ndk build.
String openalsoftBuildDir = "${buildDir}" + File.separator + 'openalsoft'
String openalsoftClassesBuildDir = "${buildDir}" + File.separator + 'openalsoft_classes'
String openalsoftBuildJniDir = openalsoftBuildDir + File.separator + 'jni'
String openalsoftBuildLibsDir = openalsoftBuildDir + File.separator + 'libs'
//Pre-compiled libs directory
def rootPath = rootProject.projectDir.absolutePath
String openalsoftPreCompiledLibsDir = rootPath + File.separator + 'build' + File.separator + 'native' + File.separator + 'android' + File.separator + 'openalsoft'
String openalsoftPreCompiledLibsDir = 'libs' + File.separator + 'openalsoft'
// jME Android Native source files path
String openalsoftJmeAndroidPath = 'src/native/jme_openalsoft'
String jmeHeaders = 'src/native/headers'
// Download external source files if not available
task downloadOpenALSoft(type: MyDownload) {
sourceUrl = openALSoftUrl
target = file(openalsoftBuildDir + File.separator + openALSoftZipFile)
target = file(openALSoftZipFile)
}
// Unzip external source files
task unzipOpenALSoft(type: Copy) {
def zipFile = file(openalsoftBuildDir + File.separator + openALSoftZipFile)
def outputDir = file(openalsoftBuildDir)
def zipFile = file(openALSoftZipFile)
def outputDir = file(".")
from zipTree(zipFile)
into outputDir
}
unzipOpenALSoft.dependsOn {
def zipFilePath = openalsoftBuildDir + File.separator + openALSoftZipFile
def zipFilePath = project.projectDir.absolutePath + File.separator + openALSoftZipFile
def zipFile = new File(zipFilePath)
// println "zipFile path: " + zipFile.absolutePath
// println "zipFile exists: " + zipFile.exists()
@ -47,7 +44,7 @@ unzipOpenALSoft.dependsOn {
// Copy external source files to jni directory
task copyOpenALSoft(type: Copy) {
def sourceDir = file(openalsoftBuildDir + File.separator + openALSoftFolder)
def sourceDir = file(openALSoftFolder)
def outputDir = file(openalsoftBuildJniDir)
// println "copyOpenALSoft sourceDir: " + sourceDir
// println "copyOpenALSoft outputDir: " + outputDir
@ -64,14 +61,8 @@ copyOpenALSoft.dependsOn {
}
}
// Copy JME Headers to jni directory
task copyJmeHeadersOpenAL(type: Copy) {
from file(jmeHeaders)
into file(openalsoftBuildJniDir + File.separator + "headers")
}
// Copy jME Android native files to jni directory
task copyJmeOpenALSoft(type: Copy, dependsOn: [copyOpenALSoft, copyJmeHeadersOpenAL]) {
task copyJmeOpenALSoft(type: Copy, dependsOn:copyOpenALSoft) {
def sourceDir = file(openalsoftJmeAndroidPath)
def outputDir = file(openalsoftBuildJniDir)
// println "copyJmeOpenALSoft sourceDir: " + sourceDir
@ -81,7 +72,16 @@ task copyJmeOpenALSoft(type: Copy, dependsOn: [copyOpenALSoft, copyJmeHeadersOpe
into outputDir
}
task buildOpenAlSoftNativeLib(type: Exec, dependsOn: copyJmeOpenALSoft) {
task generateOpenAlSoftHeaders(type:Exec, dependsOn: copyJmeOpenALSoft) {
executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
args '-d', openalsoftJmeAndroidPath
args '-classpath', project.projectClassPath
args "com.jme3.audio.android.AndroidAL"
args "com.jme3.audio.android.AndroidALC"
args "com.jme3.audio.android.AndroidEFX"
}
task buildOpenAlSoftNativeLib(type: Exec, dependsOn: generateOpenAlSoftHeaders) {
// println "openalsoft build dir: " + openalsoftBuildDir
// println "ndkCommandPath: " + project.ndkCommandPath
workingDir openalsoftBuildDir

@ -4,7 +4,7 @@
#include "Tremor/ivorbisfile.h"
#include "../headers/com_jme3_audio_plugins_NativeVorbisFile.h"
#include "com_jme3_audio_plugins_NativeVorbisFile.h"
#ifndef NDEBUG
#include <android/log.h>
@ -345,4 +345,4 @@ JNIEXPORT void JNICALL Java_com_jme3_audio_plugins_NativeVorbisFile_close
free(wrapper);
free(ovf);
(*env)->SetObjectField(env, nvf, nvf_field_ovf, NULL);
}
}

@ -1,4 +1,4 @@
#include "../headers/com_jme3_texture_plugins_AndroidNativeImageLoader.h"
#include "com_jme3_texture_plugins_AndroidNativeImageLoader.h"
#include <assert.h>
#ifndef NDEBUG

@ -1,4 +1,4 @@
#include "../headers/com_jme3_audio_android_AndroidAL.h"
#include "com_jme3_audio_android_AndroidAL.h"
#include "AL/al.h"
#include "AL/alext.h"

@ -0,0 +1,173 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jme3_audio_android_AndroidAL */
#ifndef _Included_com_jme3_audio_android_AndroidAL
#define _Included_com_jme3_audio_android_AndroidAL
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alGetString
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jme3_audio_android_AndroidAL_alGetString
(JNIEnv *, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alGenSources
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jme3_audio_android_AndroidAL_alGenSources
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alGetError
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_jme3_audio_android_AndroidAL_alGetError
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alDeleteSources
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alDeleteSources
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alGenBuffers
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alGenBuffers
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alDeleteBuffers
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alDeleteBuffers
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourceStop
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourceStop
(JNIEnv *, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourcei
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourcei
(JNIEnv *, jobject, jint, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alBufferData
* Signature: (IILjava/nio/ByteBuffer;II)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alBufferData
(JNIEnv *, jobject, jint, jint, jobject, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourcePlay
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourcePlay
(JNIEnv *, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourcePause
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourcePause
(JNIEnv *, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourcef
* Signature: (IIF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourcef
(JNIEnv *, jobject, jint, jint, jfloat);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSource3f
* Signature: (IIFFF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSource3f
(JNIEnv *, jobject, jint, jint, jfloat, jfloat, jfloat);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alGetSourcei
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_jme3_audio_android_AndroidAL_alGetSourcei
(JNIEnv *, jobject, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourceUnqueueBuffers
* Signature: (IILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourceUnqueueBuffers
(JNIEnv *, jobject, jint, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSourceQueueBuffers
* Signature: (IILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSourceQueueBuffers
(JNIEnv *, jobject, jint, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alListener
* Signature: (ILjava/nio/FloatBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alListener
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alListenerf
* Signature: (IF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alListenerf
(JNIEnv *, jobject, jint, jfloat);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alListener3f
* Signature: (IFFF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alListener3f
(JNIEnv *, jobject, jint, jfloat, jfloat, jfloat);
/*
* Class: com_jme3_audio_android_AndroidAL
* Method: alSource3i
* Signature: (IIIII)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidAL_alSource3i
(JNIEnv *, jobject, jint, jint, jint, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

@ -1,5 +1,5 @@
#include "util.h"
#include "../headers/com_jme3_audio_android_AndroidALC.h"
#include "com_jme3_audio_android_AndroidALC.h"
#include "AL/alc.h"
#include "AL/alext.h"
@ -171,4 +171,4 @@ JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_alcDeviceResumeSOF
if (device == NULL) return;
alcDeviceResumeSOFT(device);
}
}

@ -0,0 +1,77 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jme3_audio_android_AndroidALC */
#ifndef _Included_com_jme3_audio_android_AndroidALC
#define _Included_com_jme3_audio_android_AndroidALC
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: createALC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_createALC
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: destroyALC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_destroyALC
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: isCreated
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_jme3_audio_android_AndroidALC_isCreated
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: alcGetString
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jme3_audio_android_AndroidALC_alcGetString
(JNIEnv *, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: alcIsExtensionPresent
* Signature: (Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL Java_com_jme3_audio_android_AndroidALC_alcIsExtensionPresent
(JNIEnv *, jobject, jstring);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: alcGetInteger
* Signature: (ILjava/nio/IntBuffer;I)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_alcGetInteger
(JNIEnv *, jobject, jint, jobject, jint);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: alcDevicePauseSOFT
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_alcDevicePauseSOFT
(JNIEnv *, jobject);
/*
* Class: com_jme3_audio_android_AndroidALC
* Method: alcDeviceResumeSOFT
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidALC_alcDeviceResumeSOFT
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

@ -1,5 +1,5 @@
#include "util.h"
#include "../headers/com_jme3_audio_android_AndroidEFX.h"
#include "com_jme3_audio_android_AndroidEFX.h"
#include "AL/alext.h"
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenAuxiliaryEffectSlots
@ -72,4 +72,4 @@ JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alEffectf
(JNIEnv* env, jobject obj, jint effect, jint param, jfloat value)
{
alEffectf((ALuint)effect, (ALenum)param, (ALfloat)value);
}
}

@ -0,0 +1,101 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jme3_audio_android_AndroidEFX */
#ifndef _Included_com_jme3_audio_android_AndroidEFX
#define _Included_com_jme3_audio_android_AndroidEFX
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alGenAuxiliaryEffectSlots
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenAuxiliaryEffectSlots
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alGenEffects
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenEffects
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alEffecti
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alEffecti
(JNIEnv *, jobject, jint, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alAuxiliaryEffectSloti
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alAuxiliaryEffectSloti
(JNIEnv *, jobject, jint, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alDeleteEffects
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alDeleteEffects
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alDeleteAuxiliaryEffectSlots
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alDeleteAuxiliaryEffectSlots
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alGenFilters
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenFilters
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alFilteri
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alFilteri
(JNIEnv *, jobject, jint, jint, jint);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alFilterf
* Signature: (IIF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alFilterf
(JNIEnv *, jobject, jint, jint, jfloat);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alDeleteFilters
* Signature: (ILjava/nio/IntBuffer;)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alDeleteFilters
(JNIEnv *, jobject, jint, jobject);
/*
* Class: com_jme3_audio_android_AndroidEFX
* Method: alEffectf
* Signature: (IIF)V
*/
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alEffectf
(JNIEnv *, jobject, jint, jint, jfloat);
#ifdef __cplusplus
}
#endif
#endif

@ -1,5 +1,3 @@
apply plugin: 'java'
if (!hasProperty('mainClass')) {
ext.mainClass = ''
}
@ -7,10 +5,5 @@ if (!hasProperty('mainClass')) {
dependencies {
compile project(':jme3-core')
compile project(':jme3-plugins')
compileOnly 'android:android'
}
compileJava {
// The Android-Native Project requires the jni headers to be generated, so we do that here
options.compilerArgs += ["-h", "${project.rootDir}/jme3-android-native/src/native/headers"]
compile files('../lib/android.jar')
}

@ -3,6 +3,7 @@ package com.jme3.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.opengl.GLSurfaceView;
@ -88,7 +89,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
protected int eglStencilBits = 0;
/**
* Set the desired frame rate. If frameRate higher than 0, the application
* Set the desired frame rate. If frameRate > 0, the application
* will be capped at the desired frame rate.
* (default = -1, no frame rate cap)
*/
@ -239,8 +240,9 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
// Create application instance
try {
if (app == null) {
Class clazz = Class.forName(appClass);
app = (LegacyApplication)clazz.newInstance();
@SuppressWarnings("unchecked")
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}
app.setSettings(settings);
@ -361,7 +363,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* @param dialog
* @param whichButton
*/
@Override
public void onClick(DialogInterface dialog, int whichButton) {
if (whichButton != -2) {
if (app != null) {
@ -473,7 +474,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
handler.setLevel(Level.ALL);
}
@Override
public void initialize() {
app.initialize();
if (handleExitHook) {
@ -489,12 +489,10 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
}
}
@Override
public void reshape(int width, int height) {
app.reshape(width, height);
}
@Override
public void update() {
app.update();
// call to remove the splash screen, if present.
@ -506,12 +504,10 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
}
}
@Override
public void requestClose(boolean esc) {
app.requestClose(esc);
}
@Override
public void destroy() {
if (app != null) {
app.destroy();
@ -521,7 +517,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
}
}
@Override
public void gainFocus() {
logger.fine("gainFocus");
if (view != null) {
@ -553,7 +548,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
}
}
@Override
public void loseFocus() {
logger.fine("loseFocus");
if (app != null) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2020 jMonkeyEngine
* Copyright (c) 2009-2015 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -116,7 +116,7 @@ public class AndroidHarnessFragment extends Fragment implements
protected int eglStencilBits = 0;
/**
* Set the desired frame rate. If frameRate higher than 0, the application
* Set the desired frame rate. If frameRate > 0, the application
* will be capped at the desired frame rate.
* (default = -1, no frame rate cap)
*/
@ -125,11 +125,11 @@ public class AndroidHarnessFragment extends Fragment implements
/**
* Set the maximum resolution for the surfaceview in either the
* width or height screen direction depending on the screen size.
* If the surfaceview is rectangular, the longest side (width or height)
* If the surfaceview is retangular, the longest side (width or height)
* will have the resolution set to a maximum of maxResolutionDimension.
* The other direction will be set to a value that maintains the aspect
* ratio of the surfaceview. </br>
* Any value less than 0 (default = -1) will result in the surfaceview having the
* Any value < 0 (default = -1) will result in the surfaceview having the
* same resolution as the view layout (ie. no max resolution).
*/
protected int maxResolutionDimension = -1;
@ -257,8 +257,9 @@ public class AndroidHarnessFragment extends Fragment implements
// Create application instance
try {
if (app == null) {
Class clazz = Class.forName(appClass);
app = (LegacyApplication)clazz.newInstance();
@SuppressWarnings("unchecked")
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}
app.setSettings(settings);
@ -275,17 +276,17 @@ public class AndroidHarnessFragment extends Fragment implements
}
/**
* Called by the system to create the View hierarchy associated with this
* Called by the system to create the View hierchy associated with this
* Fragment. For jME, this is a FrameLayout that contains the GLSurfaceView
* and an overlaying SplashScreen Image (if used). The View that is returned
* will be placed on the screen within the boundaries of the View borders defined
* will be placed on the screen within the boundries of the View borders defined
* by the Activity's layout parameters for this Fragment. For jME, we also
* update the application reference to the new view.
*
* @param inflater
* @param container
* @param savedInstanceState
* @return the new view
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -683,10 +684,10 @@ public class AndroidHarnessFragment extends Fragment implements
if (viewWidth > viewHeight && viewWidth > maxResolutionDimension) {
// landscape
fixedSizeWidth = maxResolutionDimension;
fixedSizeHeight = (int)(maxResolutionDimension * (viewHeight / (float)viewWidth));
fixedSizeHeight = (int)(maxResolutionDimension * ((float)viewHeight / (float)viewWidth));
} else if (viewHeight > viewWidth && viewHeight > maxResolutionDimension) {
// portrait
fixedSizeWidth = (int)(maxResolutionDimension * (viewWidth / (float)viewHeight));
fixedSizeWidth = (int)(maxResolutionDimension * ((float)viewWidth / (float)viewHeight));
fixedSizeHeight = maxResolutionDimension;
} else if (viewWidth == viewHeight && viewWidth > maxResolutionDimension) {
fixedSizeWidth = maxResolutionDimension;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2020 jMonkeyEngine
* Copyright (c) 2014 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,8 +33,8 @@
package com.jme3.app;
import android.os.Build;
import com.jme3.profile.*;
import com.jme3.profile.AppProfiler;
import com.jme3.profile.AppStep;
import static com.jme3.profile.AppStep.BeginFrame;
import static com.jme3.profile.AppStep.EndFrame;
import static com.jme3.profile.AppStep.ProcessAudio;
@ -47,6 +47,7 @@ import static com.jme3.profile.AppStep.RenderPreviewViewPorts;
import static com.jme3.profile.AppStep.SpatialUpdate;
import static com.jme3.profile.AppStep.StateManagerRender;
import static com.jme3.profile.AppStep.StateManagerUpdate;
import com.jme3.profile.VpStep;
import static com.jme3.profile.VpStep.BeginRender;
import static com.jme3.profile.VpStep.EndRender;
import static com.jme3.profile.VpStep.FlushQueue;
@ -63,7 +64,7 @@ import com.jme3.renderer.queue.RenderQueue;
*
* <p>This profiler uses the Android Trace class which is only supported
* on Android SDK rev 18 and higher (ver 4.3 and higher). If the
* device is running a version less than rev 18, the logging will
* device is running a version < rev 18, the logging will
* be skipped.</p>
*
* <p>In the MainActivity class, add the following:</p>
@ -82,7 +83,6 @@ import com.jme3.renderer.queue.RenderQueue;
public class DefaultAndroidProfiler implements AppProfiler {
private int androidApiLevel = Build.VERSION.SDK_INT;
@Override
public void appStep(AppStep appStep) {
if (androidApiLevel >= 18) {
switch(appStep) {
@ -136,12 +136,6 @@ public class DefaultAndroidProfiler implements AppProfiler {
}
}
@Override
public void appSubStep(String... additionalInfo) {
}
@Override
public void vpStep(VpStep vpStep, ViewPort vp, RenderQueue.Bucket bucket) {
if (androidApiLevel >= 18) {
switch (vpStep) {
@ -170,10 +164,4 @@ public class DefaultAndroidProfiler implements AppProfiler {
}
}
}
@Override
public void spStep(SpStep step, String... additionalInfo) {
}
}

@ -0,0 +1,20 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.jme3.app;
public final class R {
public static final class attr {
}
public static final class layout {
public static final int main=0x7f020000;
}
public static final class string {
public static final int app_name=0x7f030000;
public static final int jme3_appclass=0x7f030001;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2020 jMonkeyEngine
* Copyright (c) 2009-2012 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 = ind.get(i);
AVIIndex in = (AVIIndex) ind.get(i);
baos.write(in.toBytes());
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2020 jMonkeyEngine
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,7 +34,6 @@ package com.jme3.app.state;
import android.graphics.Bitmap;
import com.jme3.app.Application;
import com.jme3.post.SceneProcessor;
import com.jme3.profile.AppProfiler;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer;
@ -73,7 +72,6 @@ public class VideoRecorderAppState extends AbstractAppState {
private Application app;
private ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread th = new Thread(r);
th.setName("jME3 Video Processor");
@ -124,6 +122,7 @@ public class VideoRecorderAppState extends AbstractAppState {
* This constructor allows you to specify the output file of the video as well as the quality
* @param file the video file
* @param quality the quality of the jpegs in the video stream (0.0 smallest file - 1.0 largest file)
* @param framerate the frame rate of the resulting video, the application will be locked to this framerate
*/
public VideoRecorderAppState(File file, float quality) {
this.file = file;
@ -227,7 +226,6 @@ public class VideoRecorderAppState extends AbstractAppState {
private LinkedBlockingQueue<WorkItem> usedItems = new LinkedBlockingQueue<WorkItem>();
private MjpegFileWriter writer;
private boolean fastMode = true;
private AppProfiler prof;
public void addImage(Renderer renderer, FrameBuffer out) {
if (freeItems == null) {
@ -240,7 +238,6 @@ public class VideoRecorderAppState extends AbstractAppState {
renderer.readFrameBufferWithFormat(out, item.buffer, Image.Format.BGRA8);
executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
if (fastMode) {
item.data = item.buffer.array();
@ -262,7 +259,6 @@ public class VideoRecorderAppState extends AbstractAppState {
}
}
@Override
public void initialize(RenderManager rm, ViewPort viewPort) {
logger.log(Level.INFO, "initialize in VideoProcessor");
this.camera = viewPort.getCamera();
@ -278,16 +274,13 @@ public class VideoRecorderAppState extends AbstractAppState {
}
}
@Override
public void reshape(ViewPort vp, int w, int h) {
}
@Override
public boolean isInitialized() {
return this.isInitilized;
}
@Override
public void preFrame(float tpf) {
if (null == writer) {
try {
@ -298,17 +291,14 @@ public class VideoRecorderAppState extends AbstractAppState {
}
}
@Override
public void postQueue(RenderQueue rq) {
}
@Override
public void postFrame(FrameBuffer out) {
numFrames++;
addImage(renderManager.getRenderer(), out);
}
@Override
public void cleanup() {
logger.log(Level.INFO, "cleanup in VideoProcessor");
logger.log(Level.INFO, "VideoProcessor numFrames: {0}", numFrames);
@ -323,11 +313,6 @@ public class VideoRecorderAppState extends AbstractAppState {
}
writer = null;
}
@Override
public void setProfiler(AppProfiler profiler) {
this.prof = profiler;
}
}
public static final class IsoTimer extends com.jme3.system.Timer {
@ -341,27 +326,22 @@ public class VideoRecorderAppState extends AbstractAppState {
this.ticks = 0;
}
@Override
public long getTime() {
return (long) (this.ticks * (1.0f / this.framerate) * 1000f);
}
@Override
public long getResolution() {
return 1000L;
}
@Override
public float getFrameRate() {
return this.framerate;
}
@Override
public float getTimePerFrame() {
return 1.0f / this.framerate;
return (float) (1.0f / this.framerate);
}
@Override
public void update() {
long time = System.currentTimeMillis();
long difference = time - lastTime;
@ -378,7 +358,6 @@ public class VideoRecorderAppState extends AbstractAppState {
this.ticks++;
}
@Override
public void reset() {
this.ticks = 0;
}

@ -6,6 +6,7 @@ import com.jme3.asset.*;
import com.jme3.system.android.JmeAndroidSystem;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AndroidLocator implements AssetLocator {
@ -17,7 +18,6 @@ public class AndroidLocator implements AssetLocator {
public AndroidLocator() {
}
@Override
public void setRootPath(String rootPath) {
this.rootPath = rootPath;
}

@ -10,64 +10,44 @@ public final class AndroidAL implements AL {
public AndroidAL() {
}
@Override
public native String alGetString(int parameter);
@Override
public native int alGenSources();
@Override
public native int alGetError();
@Override
public native void alDeleteSources(int numSources, IntBuffer sources);
@Override
public native void alGenBuffers(int numBuffers, IntBuffer buffers);
@Override
public native void alDeleteBuffers(int numBuffers, IntBuffer buffers);
@Override
public native void alSourceStop(int source);
@Override
public native void alSourcei(int source, int param, int value);
@Override
public native void alBufferData(int buffer, int format, ByteBuffer data, int size, int frequency);
@Override
public native void alSourcePlay(int source);
@Override
public native void alSourcePause(int source);
@Override
public native void alSourcef(int source, int param, float value);
@Override
public native void alSource3f(int source, int param, float value1, float value2, float value3);
@Override
public native int alGetSourcei(int source, int param);
@Override
public native void alSourceUnqueueBuffers(int source, int numBuffers, IntBuffer buffers);
@Override
public native void alSourceQueueBuffers(int source, int numBuffers, IntBuffer buffers);
@Override
public native void alListener(int param, FloatBuffer data);
@Override
public native void alListenerf(int param, float value);
@Override
public native void alListener3f(int param, float value1, float value2, float value3);
@Override
public native void alSource3i(int source, int param, int value1, int value2, int value3);
}

@ -12,27 +12,19 @@ public final class AndroidALC implements ALC {
public AndroidALC() {
}
@Override
public native void createALC();
@Override
public native void destroyALC();
@Override
public native boolean isCreated();
@Override
public native String alcGetString(int parameter);
@Override
public native boolean alcIsExtensionPresent(String extension);
@Override
public native void alcGetInteger(int param, IntBuffer buffer, int size);
@Override
public native void alcDevicePauseSOFT();
@Override
public native void alcDeviceResumeSOFT();
}

@ -8,36 +8,25 @@ public class AndroidEFX implements EFX {
public AndroidEFX() {
}
@Override
public native void alGenAuxiliaryEffectSlots(int numSlots, IntBuffer buffers);
@Override
public native void alGenEffects(int numEffects, IntBuffer buffers);
@Override
public native void alEffecti(int effect, int param, int value);
@Override
public native void alAuxiliaryEffectSloti(int effectSlot, int param, int value);
@Override
public native void alDeleteEffects(int numEffects, IntBuffer buffers);
@Override
public native void alDeleteAuxiliaryEffectSlots(int numEffectSlots, IntBuffer buffers);
@Override
public native void alGenFilters(int numFilters, IntBuffer buffers);
@Override
public native void alFilteri(int filter, int param, int value);
@Override
public native void alFilterf(int filter, int param, float value);
@Override
public native void alDeleteFilters(int numFilters, IntBuffer buffers);
@Override
public native void alEffectf(int effect, int param, float value);
}

@ -46,7 +46,6 @@ public class NativeVorbisLoader implements AssetLoader {
throw new IOException("Not supported for audio streams");
}
@Override
public void setTime(float time) {
try {
file.seekTime(time);

@ -36,6 +36,7 @@ import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import com.jme3.input.event.TouchEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
/**

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

Loading…
Cancel
Save