Compare commits

..

92 Commits

Author SHA1 Message Date
Kirill Vainer
74a1d8b219 Merge branch 'master' into experimental
Conflicts:
	jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
	jme3-core/src/main/java/com/jme3/scene/Node.java
	jme3-core/src/main/java/com/jme3/scene/Spatial.java
	jme3-core/src/main/java/com/jme3/shader/ShaderGenerator.java
2016-04-02 18:05:06 -04:00
Kirill Vainer
3bb01d6963 Merge remote-tracking branch 'origin/master' into experimental 2016-04-02 14:38:04 -04:00
Kirill Vainer
4fcd575c47 MPO: fix unit test 2016-04-02 14:31:23 -04:00
Kirill Vainer
60d9d1b4d8 unit test: more descriptive failure message 2016-04-02 14:18:08 -04:00
Kirill Vainer
4ab5a9f7dd SkeletonControl: fix syntax error 2016-04-02 14:04:36 -04:00
Kirill Vainer
452c307d59 fix misc unit test issues due to merge 2016-04-02 13:58:32 -04:00
Kirill Vainer
a8fca2bcf6 Merge branch 'master' into experimental 2016-03-29 14:26:33 -04:00
Kirill Vainer
2fc4e5b607 jinput: fix native loading 2016-03-19 14:18:54 -04:00
Kirill Vainer
f28d74a1f6 joystick: use jinput backend for lwjgl3 2016-03-19 12:57:30 -04:00
Kirill Vainer
87af1f30b0 MPO: clone MPOs instead of sharing references 2016-03-08 19:36:40 -05:00
Kirill Vainer
e691de4459 fix null checks 2016-03-08 19:34:43 -05:00
Kirill Vainer
2dafd1e485 MPO: add null override list check 2016-03-08 19:33:51 -05:00
Kirill Vainer
c586bacbb0 MPO: clear param for null textures 2016-03-08 19:32:19 -05:00
Kirill Vainer
fde095458e MPO: add javadoc 2016-03-08 15:16:55 -05:00
Kirill Vainer
e8fd22223a MPO: use List instead of ArrayList
Also rename get*Overrides to get*MatParamOverrides to be more specific.
2016-03-08 15:15:53 -05:00
Kirill Vainer
53d3b72478 MPO: add ability to disable an override 2016-03-08 15:14:00 -05:00
Kirill Vainer
644b8167b8 MPO: add example 2016-03-05 19:32:21 -05:00
Kirill Vainer
2cdb4a8486 spatial: fix bug in remove/clear MPO
add unit test for those methods
2016-03-05 19:31:26 -05:00
Kirill Vainer
152a7638cd material: fix sort id unit test failure 2016-03-05 19:30:28 -05:00
Kirill Vainer
adc5084f5d MPO: implement overrides on uniforms and add test 2016-03-05 19:05:36 -05:00
Kirill Vainer
42d76cfd29 MPO: implement propagation and add test 2016-03-05 19:02:16 -05:00
Kirill Vainer
ba22487c38 material: move technique logic into its own package 2016-03-05 18:59:04 -05:00
Kirill Vainer
00b6d904af add StaticPassLightingLogic 2016-03-05 17:33:16 -05:00
Kirill Vainer
2d2c394b42 Merge remote-tracking branch 'origin/master' into experimental 2016-03-05 12:42:54 -05:00
Kirill Vainer
655457ab6a Merge branch 'master' into experimental 2016-03-04 19:55:01 -05:00
Kirill Vainer
7639657fc1 initial implementation of MPO (untested!) 2016-03-04 16:59:15 -05:00
Kirill Vainer
e87f008244 build: fix missing version tag 2016-03-02 16:59:10 -05:00
Kirill Vainer
12b3c4a140 build: fix build error 2016-03-02 16:42:55 -05:00
Kirill Vainer
ae7fb6984c lwjgl3: re-enable native loading for native bullet 2016-03-02 16:36:12 -05:00
Kirill Vainer
3b9e412f80 build: fix build errors 2016-03-02 16:35:45 -05:00
Kirill Vainer
0aaa28e66b Merge branch 'master' into experimental 2016-03-02 13:56:17 -05:00
Kirill Vainer
9b45189f48 lwjgl3: start jME3 on main thread (needed for mac) 2016-03-02 13:49:28 -05:00
Kirill Vainer
69eaf39da9 lwjgl3: fix syntax error 2016-03-02 13:47:17 -05:00
Kirill Vainer
8024babb47 lwjgl3: use lwjgl's native loader 2016-03-02 13:45:50 -05:00
Kirill Vainer
c7da1c4efd desktop: don't show dialogs when headless 2016-03-02 13:44:12 -05:00
Kirill Vainer
ab8527770c GLRenderer: support VBO without VAO 2016-03-02 13:41:46 -05:00
Kirill Vainer
c6b568c125 test: disable NativeLibraryLoaderIT
using the filesystem on Travis-CI causes issues
2016-03-02 00:00:03 -05:00
Kirill Vainer
772330c308 test: delete ApplicationTest
doesn't work, causes a timeout error
2016-03-01 23:53:20 -05:00
Kirill Vainer
8413ed715c point particles: various fixes
* support any number of particles by re-using temp buffer
 * fix exception when changing particle count
2016-02-29 21:54:50 -05:00
Kirill Vainer
d76cb99772 point particles: improve performance by x3
* Use an interleaved VBO to reduce BufferData calls
 * Preload the VBO before rendering
 * Store the results into an intermediate float array to speed up copy
2016-02-27 17:57:00 -05:00
Kirill Vainer
454e210d3d native library: don't run unit test
It causes Travis-CI to freeze
2016-02-27 17:00:35 -05:00
Kirill Vainer
c6336c0781 version: new versioning scheme for tags 2016-02-21 22:15:00 -05:00
Kirill Vainer
fda40563c5 build: don't build SDK or javadoc 2016-02-21 22:03:21 -05:00
Kirill Vainer
34aa21bfd9 Get rid of TestAwtPanels (it sucks) 2016-02-21 21:57:50 -05:00
Kirill Vainer
f9969008c3 syntax error fixes 2016-02-21 21:53:48 -05:00
Kirill Vainer
2893ac9156 DDSLoader: fix syntax error 2016-02-21 20:49:28 -05:00
Kirill Vainer
a3638f3e0c Merge branch 'master' into experimental
Conflicts:
	jme3-core/src/main/java/com/jme3/renderer/RenderManager.java
2016-02-21 20:48:18 -05:00
Kirill Vainer
27041e1341 LWJGL3 improvements
* Added key remapping for GLFW key constants
 * Rename AppSettings.getGammaCorrection() to isGammaCorrection()
 * Use LWJGL3 artifacts from maven
 * Minor compatibility changes for LWJGL 3.0.0b
 * Fixed some minor bugs in LwjglWindow
2015-12-28 23:53:36 -05:00
Kirill Vainer
962ab22ef4 Merge branch 'fbx-import-animation' into experimental 2015-12-07 22:09:30 -05:00
Kirill Vainer
f9500f955f Merge branch 'renderer-rgtc' into experimental 2015-12-07 22:05:33 -05:00
Kirill Vainer
c50839796f Merge branch 'renderer-fbreadasync' into experimental 2015-12-07 22:05:02 -05:00
Kirill Vainer
ff6b1be725 Merge branch 'renderer-improvements' into experimental 2015-12-07 21:58:56 -05:00
Kirill Vainer
97281de5c4 Merge branch 'new_material_system' into experimental 2015-12-07 21:54:06 -05:00
Kirill Vainer
8f54af3263 Merge remote-tracking branch 'origin/master' into experimental 2015-12-07 21:52:55 -05:00
Kirill Vainer
79125f2f63 remove useless TestNativeLoader
It has a proper integration test now
2015-12-07 21:52:07 -05:00
Kirill Vainer
908b37350d remove XXX HACK from native library loader
also add additional integration tests for
AppSettings, Application, and NativeLibraryLoader
2015-12-07 21:49:04 -05:00
Kirill Vainer
f986043745 minor formatting changes 2015-12-07 21:34:51 -05:00
Kirill Vainer
961bf92734 lwjgl test: fix build exceed timeout 2015-11-26 14:42:19 -05:00
Kirill Vainer
3d82f5c459 lwjgl: add unit test 2015-11-26 14:17:40 -05:00
Kirill Vainer
4a646de49d gitignore: more cleanup 2015-11-26 14:16:10 -05:00
Kirill Vainer
06e8210e5d gitignore: cleanup 2015-11-26 14:09:28 -05:00
Kirill Vainer
85feb305ef SDK: fix build error 2015-11-26 13:54:37 -05:00
Kirill Vainer
15465a020f Merge branch 'master' into expermiental 2015-11-26 13:38:07 -05:00
Kirill Vainer
f005c05f8d OffscreenBuffer: check needClose after runLoop
To be consistent with other context types.
2015-11-26 13:28:25 -05:00
Kirill Vainer
42729b2302 FastMathTest: ignore failing test (for now) 2015-11-26 13:27:31 -05:00
Kirill Vainer
30855f5bb4 TestShaderNodes: fix build error 2015-11-24 21:54:01 -05:00
Kirill Vainer
352c02db8a DefineList: fix build error
Also add additional unit tests for DefineList.
2015-11-24 21:33:26 -05:00
Kirill Vainer
ea4d750d52 RM: per-pass render method 2015-11-22 19:01:41 -05:00
Kirill Vainer
6db1d15045 Image: support for RGTC format 2015-11-22 19:00:18 -05:00
Kirill Vainer
f9ce9e246c FBX: add ear clipping triangulator 2015-11-22 13:33:29 -05:00
Kirill Vainer
18db26292f Add the new material system
Also includes some unrelated tests
2015-11-22 13:13:00 -05:00
Kirill Vainer
0d3ebf75bd GLRenderer: fix NPE when using mesh without index buffer 2015-09-12 17:53:18 -04:00
Kirill Vainer
4e572605a8 GLRenderer: merge changes from master 2015-09-12 17:52:56 -04:00
Kirill Vainer
28e2b5650c GLRenderer: disable global VAO, since VAO is now supported 2015-09-12 17:51:42 -04:00
Kirill Vainer
3d2a9b83e9 JOGL: fix syntax error due to missing renderer 2015-09-12 17:51:19 -04:00
Kirill Vainer
618c8d02eb JOGL: delete old / broken renderer 2015-09-12 17:50:18 -04:00
Kirill Vainer
3a00aff886 GLRenderer: clear VBO bind state after bounding VAO 2015-09-10 23:19:14 -04:00
Kirill Vainer
fc680ea121 GLRenderer: use luminance instead of intensity in compare R to texture 2015-09-10 23:19:14 -04:00
Kirill Vainer
12c001addc Uniform: fix crash when using vector4array 2015-09-10 23:19:14 -04:00
Kirill Vainer
7b147171bf VAO: changes to test 2015-09-10 23:19:14 -04:00
Kirill Vainer
2e9a9f9f9e Add test for VAO 2015-09-10 23:19:14 -04:00
Kirill Vainer
c72b036c9f VirtualIndexBuffer: fix compile error 2015-09-10 23:19:14 -04:00
Kirill Vainer
81a76fdf69 Mesh: preliminary work to use ubyte weights for hardware skinning 2015-09-10 23:19:14 -04:00
Kirill Vainer
7b64e91681 GLRenderer: remaining portion of VAO support 2015-09-10 23:19:13 -04:00
Kirill Vainer
d2f38f8adb GLRenderer: added fast uniforms - still need to fix Uniform.clear() 2015-09-10 23:19:13 -04:00
Kirill Vainer
937d97b8d7 GLRenderer: initial VAO support (still buggy) 2015-09-10 23:19:13 -04:00
Kirill Vainer
9e17f39cfb FBX: include main folder for shared plugins API 2015-08-21 21:43:45 -04:00
Kirill Vainer
2ced7653a7 FBX: more work on importing skeletal animation 2015-08-21 21:41:47 -04:00
Kirill Vainer
f0b63e7910 GLRenderer: the actual async FB read changes 2015-08-21 21:34:43 -04:00
Kirill Vainer
860de88298 GLRenderer: initial commit of async FB read (including jme panels) 2015-08-21 21:27:54 -04:00
Kirill Vainer
e8f344a0db GLRenderer: remaining portion of VAO support 2015-08-21 21:21:31 -04:00
Kirill Vainer
bee759bddc GLRenderer: initial VAO support (still buggy) 2015-08-21 20:32:27 -04:00
2083 changed files with 64537 additions and 252321 deletions

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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
View File

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

59
.travis.yml Normal file
View File

@ -0,0 +1,59 @@
language: java
sudo: false
env:
- GRADLE_USER_HOME=gradle-cache
cache:
directories:
- gradle-cache
- netbeans
# branches:
# only:
# - master
notifications:
slack:
on_success: change
on_failure: always
rooms:
secure: "PWEk4+VL986c3gAjWp12nqyifvxCjBqKoESG9d7zWh1uiTLadTHhZJRMdsye36FCpz/c/Jt7zCRO/5y7FaubQptnRrkrRfjp5f99MJRzQVXnUAM+y385qVkXKRKd/PLpM7XPm4AvjvxHCyvzX2wamRvul/TekaXKB9Ti5FCN87s="
install:
- ./gradlew assemble
script:
- ./gradlew check
- ./gradlew createZipDistribution
before_deploy:
- 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:
- '[ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives || :'
- '[ -n "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives bintrayUpload || :'

View File

@ -9,8 +9,6 @@ Communication always comes first. **All** code changes and other contributions s
### New Contributors ### 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). 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. - 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. 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”. Dont 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 ## Building the engine
1. Install [Gradle](http://www.gradle.org/) 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 ## Documentation
- How to edit the [wiki](https://github.com/jMonkeyEngine/wiki). - How to edit the wiki - WIP
- How to edit JavaDocs - WIP - How to edit JavaDocs - WIP

29
LICENSE
View File

@ -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.

View File

@ -1,33 +1,29 @@
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. Its 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. Its 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: 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) - [jME powered games on IndieDB](http://www.indiedb.com/engines/jmonkeyengine/games)
- [Maker's Tale](http://steamcommunity.com/sharedfiles/filedetails/?id=93461954t) - [Maker's Tale](http://steamcommunity.com/sharedfiles/filedetails/?id=93461954t)
- [Boardtastic 2](https://boardtastic-2.fileplanet.com/apk) - [Boardtastic 2](https://play.google.com/store/apps/details?id=com.boardtastic.skateboarding)
- [Attack of the Gelatinous Blob](https://attack-gelatinous-blob.softwareandgames.com/) - [Copod](http://herebeben.com/copod)
- [Mythruna](http://mythruna.com/) - [Attack of the Gelatinous Blob](http://attackofthegelatinousblob.com/)
- [PirateHell (on Steam)](https://store.steampowered.com/app/321080/Pirate_Hell/) - [Chaos](http://4realms.net/)
- [3089 (on Steam)](http://store.steampowered.com/app/263360/) - [Mythruna](https://mythruna.com/)
- [3079 (on Steam)](http://store.steampowered.com/app/259620/) - [PirateHell](http://www.desura.com/games/piratehell)
- [Lightspeed Frontier (on Steam)](https://store.steampowered.com/app/548650/Lightspeed_Frontier/) - [3089 (on steam)](http://store.steampowered.com/app/263360/)
- [Skullstone](http://www.skullstonegame.com/) - [3079 (on steam)](http://store.steampowered.com/app/259620/)
- [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/)
## Getting started ## Getting started
Go to https://github.com/jMonkeyEngine/sdk/releases to download the jMonkeyEngine SDK. Go to http://hub.jmonkeyengine.org/downloads/ to download the jMonkeyEngine SDK.
[Read the wiki](https://jmonkeyengine.github.io/wiki) for a complete install guide. Power up with some SDK Plugins and AssetPacks and you are off to the races. At this point you're gonna want to [join the forum](http://hub.jmonkeyengine.org/) so our tribe can grow stronger. [Read the wiki](http://hub.jmonkeyengine.org/wiki/doku.php) for a complete install guide. Power up with some SDK Plugins and AssetPacks and you are off to the races. At this point you're gonna want to [join the forum](http://hub.jmonkeyengine.org/) so our tribe can grow stronger.
Note: The master branch on GitHub is a development version of the engine and is NOT MEANT TO BE USED IN PRODUCTION, it will break constantly during development of the stable jME versions! Note: The master branch on GitHub is a development version of the engine and is NOT MEANT TO BE USED IN PRODUCTION, it will break constantly during development of the stable jME versions!
@ -37,11 +33,11 @@ Note: The master branch on GitHub is a development version of the engine and is
- NetBeans Platform - NetBeans Platform
- Gradle - 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 ### Documentation
Did you miss it? Don't sweat it, [here it is again](https://jmonkeyengine.github.io/wiki). Did you miss it? Don't sweat it, [here it is again](http://hub.jmonkeyengine.org/wiki/doku.php).
### Contributing ### Contributing
@ -50,4 +46,3 @@ Read our [contribution guide](https://github.com/jMonkeyEngine/jmonkeyengine/blo
### License ### License
New BSD (3-clause) License. In other words, you do whatever makes you happy! New BSD (3-clause) License. In other words, you do whatever makes you happy!

View File

@ -1,35 +1,24 @@
import java.nio.file.Files; import org.gradle.api.artifacts.*
import java.nio.file.StandardCopyOption;
buildscript { buildscript {
repositories { repositories {
google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.5'
classpath 'me.tatarka:gradle-retrolambda:3.7.1'
}
}
allprojects {
repositories {
google()
jcenter()
} }
} }
apply plugin: 'base' apply plugin: 'base'
apply from: file('version.gradle') apply from: file('version.gradle')
apply from: file('upload.gradle')
apply plugin: 'me.tatarka.retrolambda'
// This is applied to all sub projects // This is applied to all sub projects
subprojects { subprojects {
if(!project.name.equals('jme3-android-examples')) { if(!project.name.equals('jme3-android-examples')) {
apply from: rootProject.file('common.gradle') 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') apply from: rootProject.file('bintray.gradle')
} }
} else { } else {
@ -43,8 +32,8 @@ task run(dependsOn: ':jme3-examples:run') {
defaultTasks 'run' defaultTasks 'run'
task libDist(dependsOn: subprojects.build, description: 'Builds and copies the engine binaries, sources and javadoc to build/libDist') { task libDist(dependsOn: subprojects.build) << {
doLast { // description 'Builds and copies the engine binaries, sources and javadoc to build/libDist'
File libFolder = mkdir("$buildDir/libDist/lib") File libFolder = mkdir("$buildDir/libDist/lib")
File sourceFolder = mkdir("$buildDir/libDist/sources") File sourceFolder = mkdir("$buildDir/libDist/sources")
File javadocFolder = mkdir("$buildDir/libDist/javadoc") File javadocFolder = mkdir("$buildDir/libDist/javadoc")
@ -73,7 +62,6 @@ task libDist(dependsOn: subprojects.build, description: 'Builds and copies the e
} }
} }
} }
}
} }
task createZipDistribution(type:Zip,dependsOn:["dist","libDist"], description:"Package the nightly zip distribution"){ task createZipDistribution(type:Zip,dependsOn:["dist","libDist"], description:"Package the nightly zip distribution"){
@ -115,8 +103,8 @@ task mergedJavadoc(type: Javadoc, description: 'Creates Javadoc from all the pro
source subprojects.collect {project -> source subprojects.collect {project ->
project.sourceSets*.allJava project.sourceSets*.allJava
} }
classpath = files(subprojects.collect {project -> // classpath = files(subprojects.collect {project ->
project.sourceSets*.compileClasspath}) // project.sourceSets*.compileClasspath})
// source { // source {
// subprojects*.sourceSets*.main*.allSource // subprojects*.sourceSets*.main*.allSource
// } // }
@ -125,15 +113,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 mergedSource(type: Copy){
} }
task wrapper(type: Wrapper, description: 'Creates and deploys the Gradle wrapper to the current directory.') {
gradleVersion = '2.2.1'
}
ext { ext {
ndkCommandPath = "" ndkCommandPath = ""
ndkExists = false ndkExists = false
@ -159,62 +146,6 @@ task configureAndroidNDK {
} }
} }
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 { //class IncrementalReverseTask extends DefaultTask {
// @InputDirectory // @InputDirectory
// def File inputDir // def File inputDir
@ -250,14 +181,3 @@ if (skipPrebuildLibraries != "true" && buildNativeProjects != "true") {
// enableAssertions = true // true by default // enableAssertions = true // true by default
// } // }
//} //}
wrapper {
gradleVersion = '5.6.4'
}
retrolambda {
javaVersion JavaVersion.VERSION_1_7
incremental true
jvmArgs '-noverify'
}

View File

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

View File

@ -3,50 +3,33 @@
// //
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'maven' apply plugin: 'maven'
group = 'org.jmonkeyengine' group = 'org.jmonkeyengine'
version = jmeFullVersion version = jmePomVersion
sourceCompatibility = '1.8' sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
gradle.projectsEvaluated {
tasks.withType(JavaCompile) { // compile-time options:
options.compilerArgs << '-Xlint:unchecked'
}
}
repositories { repositories {
mavenCentral() mavenCentral()
maven { maven {
url "http://nifty-gui.sourceforge.net/nifty-maven-repo" url "http://nifty-gui.sourceforge.net/nifty-maven-repo"
} }
flatDir { }
dirs rootProject.file('lib')
} configurations {
deployerJars
} }
dependencies { dependencies {
// Adding dependencies here will add the dependencies to each subproject. // Adding dependencies here will add the dependencies to each subproject.
testCompile group: 'junit', name: 'junit', version: '4.12' 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 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 { jar {
manifest { manifest {
attributes 'Implementation-Title': 'jMonkeyEngine', attributes 'Implementation-Title': 'jMonkeyEngine',
@ -57,13 +40,11 @@ jar {
javadoc { javadoc {
failOnError = false failOnError = false
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
options.docTitle = "jMonkeyEngine ${jmeFullVersion} ${project.name} Javadoc" options.docTitle = "jMonkeyEngine ${jmeMainVersion} ${project.name} Javadoc"
options.windowTitle = "jMonkeyEngine ${jmeFullVersion} ${project.name} Javadoc" options.windowTitle = "jMonkeyEngine ${jmeMainVersion} ${project.name} Javadoc"
options.header = "<b>jMonkeyEngine ${jmeFullVersion} ${project.name}</b>" options.header = "<b>jMonkeyEngine ${jmeMainVersion} ${project.name}</b>"
options.author = "true" options.author = "true"
options.use = "true" options.use = "true"
options.charSet = "UTF-8"
options.encoding = "UTF-8"
//disable doclint for JDK8, more quiet output //disable doclint for JDK8, more quiet output
if (JavaVersion.current().isJava8Compatible()){ if (JavaVersion.current().isJava8Compatible()){
options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('Xdoclint:none', '-quiet')
@ -86,11 +67,11 @@ task javadocJar(type: Jar, dependsOn: javadoc, description: 'Creates a jar from
from javadoc.destinationDir from javadoc.destinationDir
} }
ext.pomConfig = { def pomConfig = {
name POM_NAME name POM_NAME
description POM_DESCRIPTION description POM_DESCRIPTION
url POM_URL url POM_URL
inceptionYear POM_INCEPTION_YEAR inceptionYear '2016'
scm { scm {
url POM_SCM_URL url POM_SCM_URL
connection POM_SCM_CONNECTION connection POM_SCM_CONNECTION
@ -103,6 +84,7 @@ ext.pomConfig = {
distribution POM_LICENSE_DISTRIBUTION distribution POM_LICENSE_DISTRIBUTION
} }
} }
// from http://hub.jmonkeyengine.org/introduction/team/
developers { developers {
developer { developer {
name 'jMonkeyEngine Team' name 'jMonkeyEngine Team'
@ -121,7 +103,6 @@ task writeFullPom {
}.writeTo(pomFile) }.writeTo(pomFile)
} }
} }
assemble.dependsOn(writeFullPom) assemble.dependsOn(writeFullPom)
install.dependsOn(writeFullPom) install.dependsOn(writeFullPom)
uploadArchives.dependsOn(writeFullPom) uploadArchives.dependsOn(writeFullPom)
@ -129,9 +110,32 @@ uploadArchives.dependsOn(writeFullPom)
artifacts { artifacts {
archives jar archives jar
archives sourcesJar archives sourcesJar
if (buildJavaDoc == "true") { if(buildJavaDoc == "true"){
archives javadocJar archives javadocJar
} }
archives writeFullPom.outputs.files[0] 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
}
}
task createFolders(description: 'Creates the source folders if they do not exist.') doLast {
// sourceSets*.allSource*.srcDirs*.each { File srcDir ->
// if (!srcDir.isDirectory()) {
// println "Creating source folder: ${srcDir}"
// srcDir.mkdirs()
// }
// }
}

View File

@ -1,40 +1,32 @@
# Version number: Major.Minor.SubMinor (e.g. 3.3.0) # Version number used for plugins, only 3 numbers (e.g. 3.1.3)
jmeVersion = 3.4.0 jmeVersion = 3.1.0
# Version used for application and settings folder, no spaces!
# Leave empty to autogenerate jmeMainVersion = 3.1
# (use -PjmeVersionName="myVersion" from commandline to specify a custom version name ) # Increment this each time jmeVersionTag changes but jmeVersion stays the same
jmeVersionName = jmeVersionTagID = 0
# If true, the version name will contain the commit hash
useCommitHashAsVersionName = false
# Set to true if a non-master branch name should be included in the automatically
# generated version.
includeBranchInVersion = false
# specify if JavaDoc should be built # specify if JavaDoc should be built
buildJavaDoc = true buildJavaDoc = false
# specify if SDK and Native libraries get built # specify if SDK and Native libraries get built
buildNativeProjects = false buildNativeProjects = false
buildAndroidExamples = false buildAndroidExamples = false
buildForPlatforms = Linux64,Linux32,Windows64,Windows32,Mac64
# Forcefully ignore prebuilt libraries
skipPrebuildLibraries=false
# Path to android NDK for building native libraries # Path to android NDK for building native libraries
#ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7 #ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7
ndkPath = /opt/android-ndk-r16b ndkPath = /opt/android-ndk-r10c
# Path for downloading native Bullet # Path for downloading native Bullet
# 2.89+ (circa 26 April 2020, to avoid jMonkeyEngine issue #1283) bulletUrl = http://bullet.googlecode.com/files/bullet-2.82-r2704.zip
bulletUrl = https://github.com/bulletphysics/bullet3/archive/cd8cf7521cbb8b7808126a6adebd47bb83ea166a.zip bulletFolder = bullet-2.82-r2704
bulletFolder = bullet3-cd8cf7521cbb8b7808126a6adebd47bb83ea166a bulletZipFile = bullet.zip
bulletZipFile = bullet3.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 settings
POM_NAME=jMonkeyEngine 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_URL=http://jmonkeyengine.org
POM_SCM_URL=https://github.com/jMonkeyEngine/jmonkeyengine POM_SCM_URL=https://github.com/jMonkeyEngine/jmonkeyengine
POM_SCM_CONNECTION=scm:git:git://github.com/jMonkeyEngine/jmonkeyengine.git POM_SCM_CONNECTION=scm:git:git://github.com/jMonkeyEngine/jmonkeyengine.git
@ -42,10 +34,7 @@ POM_SCM_DEVELOPER_CONNECTION=scm:git:git@github.com:jMonkeyEngine/jmonkeyengine.
POM_LICENSE_NAME=New BSD (3-clause) License POM_LICENSE_NAME=New BSD (3-clause) License
POM_LICENSE_URL=http://opensource.org/licenses/BSD-3-Clause POM_LICENSE_URL=http://opensource.org/licenses/BSD-3-Clause
POM_LICENSE_DISTRIBUTION=repo POM_LICENSE_DISTRIBUTION=repo
POM_INCEPTION_YEAR=2009
# Bintray settings to override in $HOME/.gradle/gradle.properties or ENV or commandline # Bintray settings to override in $HOME/.gradle/gradle.properties or ENV or commandline
bintray_user= bintray_user=
bintray_api_key= bintray_api_key=
PREBUILD_NATIVES_URL=https://dl.bintray.com/jmonkeyengine/files/${natives.snapshot}/jme3-natives.zip

Binary file not shown.

View File

@ -1,5 +1,6 @@
#Mon Dec 01 20:04:11 EST 2014
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip

130
gradlew vendored
View File

@ -1,20 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env bash
#
# 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.
#
############################################################################## ##############################################################################
## ##
@ -22,6 +6,47 @@
## ##
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" PRG="$0"
@ -36,49 +61,9 @@ while [ -h "$PRG" ] ; do
fi fi
done done
SAVED="`pwd`" SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`" APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null cd "$SAVED" >&-
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"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -105,7 +90,7 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n` MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -125,11 +110,10 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@ -170,19 +154,11 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
esac esac
fi fi
# Escape application args # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
save () { function splitJvmOpts() {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done JVM_OPTS=("$@")
echo " "
} }
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 exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
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" "$@"

30
gradlew.bat vendored
View File

@ -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 @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@ -24,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@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=
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% 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"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
@ -62,9 +46,10 @@ echo location of your Java installation.
goto fail goto fail
:init :init
@rem Get command-line arguments, handling Windows variants @rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@ -75,6 +60,11 @@ set _SKIP=2
if "x%~1" == "x" goto execute if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line

View File

@ -1 +0,0 @@
/build

View File

@ -1,57 +1,6 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
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
versionCode 1
versionName "1.0" // TODO: from settings.gradle
}
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'
}
}
}
}
dependencies { 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-core')
compile project(':jme3-android') compile project(':jme3-android')
compile project(':jme3-android-native')
compile project(':jme3-effects') compile project(':jme3-effects')
compile project(':jme3-bullet') compile project(':jme3-bullet')
compile project(':jme3-bullet-native-android') compile project(':jme3-bullet-native-android')
@ -59,6 +8,33 @@ dependencies {
compile project(':jme3-niftygui') compile project(':jme3-niftygui')
compile project(':jme3-plugins') compile project(':jme3-plugins')
compile project(':jme3-terrain') compile project(':jme3-terrain')
compile fileTree(dir: '../jme3-examples/build/libs', include: ['*.jar'], exclude: ['*sources*.*']) compile project(':jme3-testdata')
// compile project(':jme3-examples') }
android {
compileSdkVersion 10
buildToolsVersion "22.0.1"
lintOptions {
// Fix nifty gui referencing "java.awt" package.
disable 'InvalidPackage'
}
defaultConfig {
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
}
buildTypes {
release {
minifyEnabled false
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
} }

View File

@ -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 *;
#}

View File

@ -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);
}
}

View File

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

View File

@ -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);
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -1,26 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Main Application Title --> <string name="app_name">JMEAndroidTest</string>
<string name="app_name">jME3 Tests Android</string> <string name="about">About</string>
<string name="quit">Quit</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> </resources>

View File

@ -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>

View File

@ -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);
}
}

View File

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

View File

@ -1,43 +1,40 @@
String tremorZipFile = "TremorAndroid.zip" 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. // Working directories for the ndk build.
String decodeBuildDir = "${buildDir}" + File.separator + 'decode' String decodeBuildDir = "${buildDir}" + File.separator + 'decode'
String decodeClassesBuildDir = "${buildDir}" + File.separator + 'decode_classes'
String decodeBuildJniDir = decodeBuildDir + File.separator + 'jni' String decodeBuildJniDir = decodeBuildDir + File.separator + 'jni'
String decodeBuildLibsDir = decodeBuildDir + File.separator + 'libs' String decodeBuildLibsDir = decodeBuildDir + File.separator + 'libs'
// Pre-compiled libs directory // Pre-compiled libs directory
def rootPath = rootProject.projectDir.absolutePath String decodePreCompiledLibsDir = 'libs' + File.separator + 'decode'
String decodePreCompiledLibsDir = rootPath + File.separator + 'build' + File.separator + 'native' + File.separator + 'android' + File.separator + 'decode'
// jME Android Native source files path // jME Android Native source files path
String decodeSourceDir = 'src/native/jme_decode' String decodeSourceDir = 'src/native/jme_decode'
String jmeHeaders = 'src/native/headers'
task downloadStbImage(type: MyDownload) { task downloadStbImage(type: MyDownload) {
sourceUrl = stbiUrl 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) { task copyStbiFiles(type: Copy) {
def sourceDir = file(decodeBuildDir + File.separator + 'stb_image.h') def sourceDir = file('stb_image.h')
def outputDir = file(decodeBuildJniDir + File.separator + "STBI") def outputDir = file(decodeSourceDir + File.separator + "STBI")
from sourceDir from sourceDir
into outputDir into outputDir
} }
copyStbiFiles.dependsOn { copyStbiFiles.dependsOn {
def stbiFile = file(decodeBuildDir + File.separator + 'stb_image.h') def stbiFile = file('stb_image.h')
if (!stbiFile.exists()) { if (!stbiFile.exists()) {
downloadStbImage downloadStbImage
} }
} }
// Copy libtremor source to the jni directory. // Copy libtremor source to the source directory.
task copyTremorFiles(type: Copy) { task copyTremorFiles(type: Copy) {
def zipFile = file(tremorZipFile) def zipFile = file(tremorZipFile)
def outputDir = file(decodeBuildJniDir + File.separator + "Tremor") def outputDir = file(decodeSourceDir + File.separator + "Tremor")
from (zipTree(zipFile)) { from (zipTree(zipFile)) {
include '*.c' include '*.c'
@ -47,13 +44,17 @@ task copyTremorFiles(type: Copy) {
into outputDir into outputDir
} }
task copyJmeHeadersDecode(type: Copy) { // Generate headers via javah
from file(jmeHeaders) task generateJavahHeaders(type: Exec) {
into file(decodeBuildJniDir + File.separator + "headers") 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 // 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 sourceDir = file(decodeSourceDir)
def outputDir = file(decodeBuildJniDir) def outputDir = file(decodeBuildJniDir)
@ -84,9 +85,7 @@ task copyPreCompiledLibs(type: Copy) {
into outputDir into outputDir
} }
// ndkExists is a boolean from the build.gradle in the root project if (rootProject.ndkExists && rootProject.buildNativeProjects) {
// buildNativeProjects is a string set to "true"
if (ndkExists && buildNativeProjects == "true") {
// build native libs and update stored pre-compiled libs to commit // build native libs and update stored pre-compiled libs to commit
compileJava.dependsOn { updatePreCompiledLibs } compileJava.dependsOn { updatePreCompiledLibs }
} else { } else {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,42 +1,39 @@
// OpenAL Soft r1.16 // 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' String openALSoftZipFile = 'OpenALSoft.zip'
// OpenAL Soft directory the download is extracted into // OpenAL Soft directory the download is extracted into
// Typically, the downloaded OpenAL Soft zip file will extract to a directory // Typically, the downloaded OpenAL Soft zip file will extract to a directory
// called "openal-soft" // called "openal-soft"
String openALSoftFolder = 'openal-soft-e5016f814a265ed592a88acea95cf912c4bfdf12' String openALSoftFolder = 'openal-soft'
//Working directories for the ndk build. //Working directories for the ndk build.
String openalsoftBuildDir = "${buildDir}" + File.separator + 'openalsoft' String openalsoftBuildDir = "${buildDir}" + File.separator + 'openalsoft'
String openalsoftClassesBuildDir = "${buildDir}" + File.separator + 'openalsoft_classes'
String openalsoftBuildJniDir = openalsoftBuildDir + File.separator + 'jni' String openalsoftBuildJniDir = openalsoftBuildDir + File.separator + 'jni'
String openalsoftBuildLibsDir = openalsoftBuildDir + File.separator + 'libs' String openalsoftBuildLibsDir = openalsoftBuildDir + File.separator + 'libs'
//Pre-compiled libs directory //Pre-compiled libs directory
def rootPath = rootProject.projectDir.absolutePath String openalsoftPreCompiledLibsDir = 'libs' + File.separator + 'openalsoft'
String openalsoftPreCompiledLibsDir = rootPath + File.separator + 'build' + File.separator + 'native' + File.separator + 'android' + File.separator + 'openalsoft'
// jME Android Native source files path // jME Android Native source files path
String openalsoftJmeAndroidPath = 'src/native/jme_openalsoft' String openalsoftJmeAndroidPath = 'src/native/jme_openalsoft'
String jmeHeaders = 'src/native/headers'
// Download external source files if not available // Download external source files if not available
task downloadOpenALSoft(type: MyDownload) { task downloadOpenALSoft(type: MyDownload) {
sourceUrl = openALSoftUrl sourceUrl = openALSoftUrl
target = file(openalsoftBuildDir + File.separator + openALSoftZipFile) target = file(openALSoftZipFile)
} }
// Unzip external source files // Unzip external source files
task unzipOpenALSoft(type: Copy) { task unzipOpenALSoft(type: Copy) {
def zipFile = file(openalsoftBuildDir + File.separator + openALSoftZipFile) def zipFile = file(openALSoftZipFile)
def outputDir = file(openalsoftBuildDir) def outputDir = file(".")
from zipTree(zipFile) from zipTree(zipFile)
into outputDir into outputDir
} }
unzipOpenALSoft.dependsOn { unzipOpenALSoft.dependsOn {
def zipFilePath = openalsoftBuildDir + File.separator + openALSoftZipFile def zipFilePath = project.projectDir.absolutePath + File.separator + openALSoftZipFile
def zipFile = new File(zipFilePath) def zipFile = new File(zipFilePath)
// println "zipFile path: " + zipFile.absolutePath // println "zipFile path: " + zipFile.absolutePath
// println "zipFile exists: " + zipFile.exists() // println "zipFile exists: " + zipFile.exists()
@ -47,7 +44,7 @@ unzipOpenALSoft.dependsOn {
// Copy external source files to jni directory // Copy external source files to jni directory
task copyOpenALSoft(type: Copy) { task copyOpenALSoft(type: Copy) {
def sourceDir = file(openalsoftBuildDir + File.separator + openALSoftFolder) def sourceDir = file(openALSoftFolder)
def outputDir = file(openalsoftBuildJniDir) def outputDir = file(openalsoftBuildJniDir)
// println "copyOpenALSoft sourceDir: " + sourceDir // println "copyOpenALSoft sourceDir: " + sourceDir
// println "copyOpenALSoft outputDir: " + outputDir // 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 // 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 sourceDir = file(openalsoftJmeAndroidPath)
def outputDir = file(openalsoftBuildJniDir) def outputDir = file(openalsoftBuildJniDir)
// println "copyJmeOpenALSoft sourceDir: " + sourceDir // println "copyJmeOpenALSoft sourceDir: " + sourceDir
@ -81,7 +72,16 @@ task copyJmeOpenALSoft(type: Copy, dependsOn: [copyOpenALSoft, copyJmeHeadersOpe
into outputDir 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 "openalsoft build dir: " + openalsoftBuildDir
// println "ndkCommandPath: " + project.ndkCommandPath // println "ndkCommandPath: " + project.ndkCommandPath
workingDir openalsoftBuildDir workingDir openalsoftBuildDir
@ -111,9 +111,7 @@ task copyPreCompiledOpenAlSoftLibs(type: Copy) {
into outputDir into outputDir
} }
// ndkExists is a boolean from the build.gradle in the root project if (rootProject.ndkExists && rootProject.buildNativeProjects) {
// buildNativeProjects is a string set to "true"
if (ndkExists && buildNativeProjects == "true") {
// build native libs and update stored pre-compiled libs to commit // build native libs and update stored pre-compiled libs to commit
compileJava.dependsOn { updatePreCompiledOpenAlSoftLibs } compileJava.dependsOn { updatePreCompiledOpenAlSoftLibs }
} else { } else {

View File

@ -4,7 +4,7 @@
#include "Tremor/ivorbisfile.h" #include "Tremor/ivorbisfile.h"
#include "../headers/com_jme3_audio_plugins_NativeVorbisFile.h" #include "com_jme3_audio_plugins_NativeVorbisFile.h"
#ifndef NDEBUG #ifndef NDEBUG
#include <android/log.h> #include <android/log.h>

View File

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

View File

@ -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/al.h"
#include "AL/alext.h" #include "AL/alext.h"

View File

@ -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

View File

@ -1,5 +1,5 @@
#include "util.h" #include "util.h"
#include "../headers/com_jme3_audio_android_AndroidALC.h" #include "com_jme3_audio_android_AndroidALC.h"
#include "AL/alc.h" #include "AL/alc.h"
#include "AL/alext.h" #include "AL/alext.h"

View File

@ -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

View File

@ -1,5 +1,5 @@
#include "util.h" #include "util.h"
#include "../headers/com_jme3_audio_android_AndroidEFX.h" #include "com_jme3_audio_android_AndroidEFX.h"
#include "AL/alext.h" #include "AL/alext.h"
JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenAuxiliaryEffectSlots JNIEXPORT void JNICALL Java_com_jme3_audio_android_AndroidEFX_alGenAuxiliaryEffectSlots

View File

@ -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

View File

@ -1,5 +1,3 @@
apply plugin: 'java'
if (!hasProperty('mainClass')) { if (!hasProperty('mainClass')) {
ext.mainClass = '' ext.mainClass = ''
} }
@ -7,10 +5,5 @@ if (!hasProperty('mainClass')) {
dependencies { dependencies {
compile project(':jme3-core') compile project(':jme3-core')
compile project(':jme3-plugins') compile project(':jme3-plugins')
compileOnly 'android:android' compile files('../lib/android.jar')
}
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"]
} }

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2020 jMonkeyEngine * Copyright (c) 2014 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,8 +33,8 @@
package com.jme3.app; package com.jme3.app;
import android.os.Build; 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.BeginFrame;
import static com.jme3.profile.AppStep.EndFrame; import static com.jme3.profile.AppStep.EndFrame;
import static com.jme3.profile.AppStep.ProcessAudio; 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.SpatialUpdate;
import static com.jme3.profile.AppStep.StateManagerRender; import static com.jme3.profile.AppStep.StateManagerRender;
import static com.jme3.profile.AppStep.StateManagerUpdate; 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.BeginRender;
import static com.jme3.profile.VpStep.EndRender; import static com.jme3.profile.VpStep.EndRender;
import static com.jme3.profile.VpStep.FlushQueue; 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 * <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 * 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> * be skipped.</p>
* *
* <p>In the MainActivity class, add the following:</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 { public class DefaultAndroidProfiler implements AppProfiler {
private int androidApiLevel = Build.VERSION.SDK_INT; private int androidApiLevel = Build.VERSION.SDK_INT;
@Override
public void appStep(AppStep appStep) { public void appStep(AppStep appStep) {
if (androidApiLevel >= 18) { if (androidApiLevel >= 18) {
switch(appStep) { 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) { public void vpStep(VpStep vpStep, ViewPort vp, RenderQueue.Bucket bucket) {
if (androidApiLevel >= 18) { if (androidApiLevel >= 18) {
switch (vpStep) { switch (vpStep) {
@ -170,10 +164,4 @@ public class DefaultAndroidProfiler implements AppProfiler {
} }
} }
} }
@Override
public void spStep(SpStep step, String... additionalInfo) {
}
} }

View File

@ -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;
}
}

View File

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

View File

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

View File

@ -0,0 +1,136 @@
package com.jme3.asset;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import com.jme3.math.ColorRGBA;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.image.ImageRaster;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* <code>AndroidImageInfo</code> is set in a jME3 image via the {@link Image#setEfficentData(java.lang.Object) }
* method to retrieve a {@link Bitmap} when it is needed by the renderer.
* User code may extend <code>AndroidImageInfo</code> and provide their own implementation of the
* {@link AndroidImageInfo#loadBitmap()} method to acquire a bitmap by their own means.
*
* @author Kirill Vainer
*/
@Deprecated
public class AndroidImageInfo extends ImageRaster {
private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
protected AssetInfo assetInfo;
protected Bitmap bitmap;
protected Format format;
public AndroidImageInfo(AssetInfo assetInfo) {
this.assetInfo = assetInfo;
}
public Bitmap getBitmap(){
if (bitmap == null || bitmap.isRecycled()){
try {
loadBitmap();
} catch (IOException ex) {
// If called first inside AssetManager, the error will propagate
// correctly. Assuming that if the first calls succeeds
// then subsequent calls will as well.
throw new AssetLoadException("Failed to load image " + assetInfo.getKey(), ex);
}
}
return bitmap;
}
public void notifyBitmapUploaded() {
// Default function is to recycle the bitmap.
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
logger.log(Level.FINE, "Bitmap was deleted. ");
}
}
public Format getFormat(){
return format;
}
@Override
public int getWidth() {
return getBitmap().getWidth();
}
@Override
public int getHeight() {
return getBitmap().getHeight();
}
@Override
public void setPixel(int x, int y, ColorRGBA color) {
getBitmap().setPixel(x, y, color.asIntARGB());
}
@Override
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
if (store == null) {
store = new ColorRGBA();
}
store.fromIntARGB(getBitmap().getPixel(x, y));
return store;
}
/**
* Loads the bitmap directly from the asset info, possibly updating
* or creating the image object.
*/
protected void loadBitmap() throws IOException{
InputStream in = null;
try {
in = assetInfo.openStream();
bitmap = BitmapFactory.decodeStream(in);
if (bitmap == null) {
throw new IOException("Failed to load image: " + assetInfo.getKey().getName());
}
} finally {
if (in != null) {
in.close();
}
}
switch (bitmap.getConfig()) {
case ALPHA_8:
format = Image.Format.Alpha8;
break;
case ARGB_8888:
format = Image.Format.RGBA8;
break;
case RGB_565:
format = Image.Format.RGB565;
break;
default:
// This should still work as long
// as renderer doesn't check format
// but just loads bitmap directly.
format = null;
}
TextureKey texKey = (TextureKey) assetInfo.getKey();
if (texKey.isFlipY()) {
// Flip the image, then delete the old one.
Matrix flipMat = new Matrix();
flipMat.preScale(1.0f, -1.0f);
Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false);
bitmap.recycle();
bitmap = newBitmap;
if (bitmap == null) {
throw new IOException("Failed to flip image: " + texKey);
}
}
}
}

View File

@ -1,101 +1,37 @@
package com.jme3.asset.plugins; package com.jme3.asset.plugins;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import com.jme3.asset.*; import com.jme3.asset.*;
import com.jme3.system.android.JmeAndroidSystem; import com.jme3.system.android.JmeAndroidSystem;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
public class AndroidLocator implements AssetLocator { public class AndroidLocator implements AssetLocator {
private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName()); private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
private android.content.res.AssetManager androidManager;
private String rootPath = ""; private String rootPath = "";
public AndroidLocator() {
}
@Override
public void setRootPath(String rootPath) {
this.rootPath = rootPath;
}
@Override
public AssetInfo locate(AssetManager manager, AssetKey key) {
String assetPath = rootPath + key.getName();
// Fix path issues
if (assetPath.startsWith("/")) {
// Remove leading /
assetPath = assetPath.substring(1);
}
assetPath = assetPath.replace("//", "/");
// Not making this a property and storing for future use in case the view stored in JmeAndroidSystem
// is replaced due to device orientation change. Not sure it is necessary to do this yet, but am for now.
android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
String androidPackageName = JmeAndroidSystem.getView().getContext().getPackageName();
// logger.log(Level.INFO, "Asset Key: {0}", key);
// logger.log(Level.INFO, "Asset Name: {0}", key.getName());
// logger.log(Level.INFO, "Asset Path: {0}", assetPath);
// logger.log(Level.INFO, "Asset Extension: {0}", key.getExtension());
// logger.log(Level.INFO, "Asset Key Class: {0}", key.getClass().getName());
// logger.log(Level.INFO, "androidPackageName: {0}", androidPackageName);
// logger.log(Level.INFO, "Resource Name: {0}", getResourceName(assetPath));
// check the assets directory for the asset using assetPath
try {
InputStream in = androidResources.getAssets().open(assetPath);
if (in != null){
return new AndroidAssetInfo(manager, key, assetPath, in, 0);
}
} catch (IOException ex) {
// allow to fall through to the other checks in the resources directories.
// logger.log(Level.INFO, "Resource[{0}] not found in assets directory.", assetPath);
}
// if not found in the assets directory, check the drawable and mipmap directories (only valid for images)
String resourceName = getResourceName(assetPath);
int resourceId = androidResources.getIdentifier(resourceName, "drawable", androidPackageName);
// logger.log(Level.INFO, "drawable resourceId: {0}", resourceId);
if (resourceId == 0) { // drawable resource not found, check mipmap resource type
resourceId = androidResources.getIdentifier(resourceName, "mipmap", androidPackageName);
// logger.log(Level.INFO, "mipmap resourceId: {0}", resourceId);
}
if (resourceId == 0) { // not found in resource directories, return null;
return null;
}
// try to open a stream with the resourceId returned by Android
try {
InputStream in = androidResources.openRawResource(resourceId);
if (in != null){
// logger.log(Level.INFO, "Creating new AndroidResourceInfo.");
return new AndroidAssetInfo(manager, key, assetPath, in, resourceId);
}
} catch (Resources.NotFoundException ex) {
// input stream failed to open, return null
return null;
}
return null;
}
public class AndroidAssetInfo extends AssetInfo { public class AndroidAssetInfo extends AssetInfo {
private InputStream in; private InputStream in;
private final String assetPath; private final String assetPath;
private int resourceId;
AndroidAssetInfo(AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in, int resourceId) { public AndroidAssetInfo(com.jme3.asset.AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in) {
super(assetManager, key); super(assetManager, key);
this.assetPath = assetPath; this.assetPath = assetPath;
this.in = in; this.in = in;
this.resourceId = resourceId; }
public AssetFileDescriptor openFileDescriptor() {
try {
return androidManager.openFd(assetPath);
} catch (IOException ex) {
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
}
} }
@Override @Override
@ -107,47 +43,55 @@ public class AndroidLocator implements AssetLocator {
return in2; return in2;
}else{ }else{
// Create a new stream for subsequent invocations. // Create a new stream for subsequent invocations.
android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
if (resourceId == 0) {
try { try {
return androidResources.getAssets().open(assetPath); return androidManager.open(assetPath);
} catch (IOException ex) { } catch (IOException ex) {
throw new AssetLoadException("Failed to open asset " + assetPath, ex); throw new AssetLoadException("Failed to open asset " + assetPath, ex);
} }
} else {
try {
return androidResources.openRawResource(resourceId);
} catch (Resources.NotFoundException ex) {
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
}
} }
} }
} }
public AssetFileDescriptor openFileDescriptor() { private AndroidAssetInfo create(AssetManager assetManager, AssetKey key, String assetPath) throws IOException {
android.content.res.Resources androidResources = JmeAndroidSystem.getView().getContext().getResources();
if (resourceId == 0) {
try { try {
return androidResources.getAssets().openFd(assetPath); InputStream in = androidManager.open(assetPath);
if (in == null){
return null;
}else{
return new AndroidAssetInfo(assetManager, key, assetPath, in);
}
} catch (IOException ex) { } catch (IOException ex) {
throw new AssetLoadException("Failed to open asset " + assetPath, ex); // XXX: Prefer to show warning here?
} // Should only surpress exceptions for "file missing" type errors.
} else { return null;
try {
return androidResources.openRawResourceFd(resourceId);
} catch (Resources.NotFoundException ex) {
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
}
}
} }
} }
private String getResourceName(String name) { public AndroidLocator() {
int idx = name.lastIndexOf('.'); androidManager = JmeAndroidSystem.getView().getContext().getAssets();
if (idx <= 0 || idx == name.length() - 1) { }
return name;
} else { public void setRootPath(String rootPath) {
return name.substring(0, idx).toLowerCase(); this.rootPath = rootPath;
}
@SuppressWarnings("rawtypes")
@Override
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) {
String assetPath = rootPath + key.getName();
// Fix path issues
if (assetPath.startsWith("/")) {
// Remove leading /
assetPath = assetPath.substring(1);
}
assetPath = assetPath.replace("//", "/");
try {
return create(manager, key, assetPath);
} catch (IOException ex) {
// This is different handling than URL locator
// since classpath locating would return null at the getResource()
// call, otherwise there's a more critical error...
throw new AssetLoadException("Failed to open asset " + assetPath, ex);
} }
} }
} }

View File

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

View File

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

View File

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

View File

@ -0,0 +1,533 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.audio.android;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import com.jme3.asset.AssetKey;
import com.jme3.audio.*;
import com.jme3.audio.AudioSource.Status;
import com.jme3.audio.openal.ALAudioRenderer;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This class is the android implementation for {@link AudioRenderer}
*
* @author larynx
* @author plan_rich
*
* @deprecated No longer supported due to too many limitations.
* Please use the generic {@link ALAudioRenderer} instead.
*/
@Deprecated
public class AndroidMediaPlayerAudioRenderer implements AudioRenderer,
SoundPool.OnLoadCompleteListener, MediaPlayer.OnCompletionListener {
private static final Logger logger = Logger.getLogger(AndroidMediaPlayerAudioRenderer.class.getName());
private final static int MAX_NUM_CHANNELS = 16;
private final HashMap<AudioSource, MediaPlayer> musicPlaying = new HashMap<AudioSource, MediaPlayer>();
private SoundPool soundPool = null;
private final Vector3f listenerPosition = new Vector3f();
// For temp use
private final Vector3f distanceVector = new Vector3f();
private final AssetManager assetManager;
private HashMap<Integer, AudioSource> soundpoolStillLoading = new HashMap<Integer, AudioSource>();
private Listener listener;
private boolean audioDisabled = false;
private final AudioManager manager;
public AndroidMediaPlayerAudioRenderer(Activity context) {
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
assetManager = context.getAssets();
}
@Override
public void initialize() {
soundPool = new SoundPool(MAX_NUM_CHANNELS, AudioManager.STREAM_MUSIC,
0);
soundPool.setOnLoadCompleteListener(this);
}
@Override
public void updateSourceParam(AudioSource src, AudioParam param) {
if (audioDisabled) {
return;
}
if (src.getChannel() < 0) {
return;
}
switch (param) {
case Position:
if (!src.isPositional()) {
return;
}
Vector3f pos = src.getPosition();
break;
case Velocity:
if (!src.isPositional()) {
return;
}
Vector3f vel = src.getVelocity();
break;
case MaxDistance:
if (!src.isPositional()) {
return;
}
break;
case RefDistance:
if (!src.isPositional()) {
return;
}
break;
case ReverbFilter:
if (!src.isPositional() || !src.isReverbEnabled()) {
return;
}
break;
case ReverbEnabled:
if (!src.isPositional()) {
return;
}
if (src.isReverbEnabled()) {
updateSourceParam(src, AudioParam.ReverbFilter);
}
break;
case IsPositional:
break;
case Direction:
if (!src.isDirectional()) {
return;
}
Vector3f dir = src.getDirection();
break;
case InnerAngle:
if (!src.isDirectional()) {
return;
}
break;
case OuterAngle:
if (!src.isDirectional()) {
return;
}
break;
case IsDirectional:
if (src.isDirectional()) {
updateSourceParam(src, AudioParam.Direction);
updateSourceParam(src, AudioParam.InnerAngle);
updateSourceParam(src, AudioParam.OuterAngle);
} else {
}
break;
case DryFilter:
if (src.getDryFilter() != null) {
Filter f = src.getDryFilter();
if (f.isUpdateNeeded()) {
// updateFilter(f);
}
}
break;
case Looping:
if (src.isLooping()) {
}
break;
case Volume:
MediaPlayer mp = musicPlaying.get(src);
if (mp != null) {
mp.setVolume(src.getVolume(), src.getVolume());
} else {
soundPool.setVolume(src.getChannel(), src.getVolume(),
src.getVolume());
}
break;
case Pitch:
break;
}
}
@Override
public void updateListenerParam(Listener listener, ListenerParam param) {
if (audioDisabled) {
return;
}
switch (param) {
case Position:
listenerPosition.set(listener.getLocation());
break;
case Rotation:
Vector3f dir = listener.getDirection();
Vector3f up = listener.getUp();
break;
case Velocity:
Vector3f vel = listener.getVelocity();
break;
case Volume:
// alListenerf(AL_GAIN, listener.getVolume());
break;
}
}
@Override
public void update(float tpf) {
float distance;
float volume;
// Loop over all mediaplayers
for (AudioSource src : musicPlaying.keySet()) {
MediaPlayer mp = musicPlaying.get(src);
// Calc the distance to the listener
distanceVector.set(listenerPosition);
distanceVector.subtractLocal(src.getPosition());
distance = FastMath.abs(distanceVector.length());
if (distance < src.getRefDistance()) {
distance = src.getRefDistance();
}
if (distance > src.getMaxDistance()) {
distance = src.getMaxDistance();
}
volume = src.getRefDistance() / distance;
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
if (FastMath.abs(audioData.getCurrentVolume() - volume) > FastMath.FLT_EPSILON) {
// Left / Right channel get the same volume by now, only
// positional
mp.setVolume(volume, volume);
audioData.setCurrentVolume(volume);
}
}
}
public void setListener(Listener listener) {
if (audioDisabled) {
return;
}
if (this.listener != null) {
// previous listener no longer associated with current
// renderer
this.listener.setRenderer(null);
}
this.listener = listener;
this.listener.setRenderer(this);
}
@Override
public void cleanup() {
// Cleanup sound pool
if (soundPool != null) {
soundPool.release();
soundPool = null;
}
// Cleanup media player
for (AudioSource src : musicPlaying.keySet()) {
MediaPlayer mp = musicPlaying.get(src);
{
mp.stop();
mp.release();
src.setStatus(Status.Stopped);
}
}
musicPlaying.clear();
}
@Override
public void onCompletion(MediaPlayer mp) {
if (mp.isPlaying()) {
mp.seekTo(0);
mp.stop();
}
// XXX: This has bad performance -> maybe change overall structure of
// mediaplayer in this audiorenderer?
for (AudioSource src : musicPlaying.keySet()) {
if (musicPlaying.get(src) == mp) {
src.setStatus(Status.Stopped);
break;
}
}
}
/**
* Plays using the {@link SoundPool} of Android. Due to hard limitation of
* the SoundPool: After playing more instances of the sound you only have
* the channel of the last played instance.
*
* It is not possible to get information about the state of the soundpool of
* a specific streamid, so removing is not possilbe -&gt; noone knows when
* sound finished.
*/
public void playSourceInstance(AudioSource src) {
if (audioDisabled) {
return;
}
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
if (!(audioData.getAssetKey() instanceof AudioKey)) {
throw new IllegalArgumentException("Asset is not a AudioKey");
}
AudioKey assetKey = (AudioKey) audioData.getAssetKey();
try {
if (audioData.getId() < 0) { // found something to load
int soundId = soundPool.load(
assetManager.openFd(assetKey.getName()), 1);
audioData.setId(soundId);
}
int channel = soundPool.play(audioData.getId(), 1f, 1f, 1, 0, 1f);
if (channel == 0) {
soundpoolStillLoading.put(audioData.getId(), src);
} else {
if (src.getStatus() != Status.Stopped) {
soundPool.stop(channel);
src.setStatus(Status.Stopped);
}
src.setChannel(channel); // receive a channel at the last
setSourceParams(src);
// playing at least
}
} catch (IOException e) {
logger.log(Level.SEVERE,
"Failed to load sound " + assetKey.getName(), e);
audioData.setId(-1);
}
}
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
AudioSource src = soundpoolStillLoading.remove(sampleId);
if (src == null) {
logger.warning("Something went terribly wrong! onLoadComplete"
+ " had sampleId which was not in the HashMap of loading items");
return;
}
AudioData audioData = src.getAudioData();
// load was successfull
if (status == 0) {
int channelIndex;
channelIndex = soundPool.play(audioData.getId(), 1f, 1f, 1, 0, 1f);
src.setChannel(channelIndex);
setSourceParams(src);
}
}
public void playSource(AudioSource src) {
if (audioDisabled) {
return;
}
AndroidAudioData audioData = (AndroidAudioData) src.getAudioData();
MediaPlayer mp = musicPlaying.get(src);
if (mp == null) {
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
try {
if (src.getStatus() == Status.Stopped) {
mp.reset();
AssetKey<?> key = audioData.getAssetKey();
AssetFileDescriptor afd = assetManager.openFd(key.getName()); // assetKey.getName()
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
mp.prepare();
setSourceParams(src, mp);
src.setChannel(0);
src.setStatus(Status.Playing);
musicPlaying.put(src, mp);
mp.start();
} else {
mp.start();
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setSourceParams(AudioSource src, MediaPlayer mp) {
mp.setLooping(src.isLooping());
mp.setVolume(src.getVolume(), src.getVolume());
//src.getDryFilter();
}
private void setSourceParams(AudioSource src) {
soundPool.setLoop(src.getChannel(), src.isLooping() ? -1 : 0);
soundPool.setVolume(src.getChannel(), src.getVolume(), src.getVolume());
}
/**
* Pause the current playing sounds. Both from the {@link SoundPool} and the
* active {@link MediaPlayer}s
*/
public void pauseAll() {
if (soundPool != null) {
soundPool.autoPause();
for (MediaPlayer mp : musicPlaying.values()) {
if(mp.isPlaying()){
mp.pause();
}
}
}
}
/**
* Resume all paused sounds.
*/
public void resumeAll() {
if (soundPool != null) {
soundPool.autoResume();
for (MediaPlayer mp : musicPlaying.values()) {
mp.start(); //no resume -> api says call start to resume
}
}
}
public void pauseSource(AudioSource src) {
if (audioDisabled) {
return;
}
MediaPlayer mp = musicPlaying.get(src);
if (mp != null) {
mp.pause();
src.setStatus(Status.Paused);
} else {
int channel = src.getChannel();
if (channel != -1) {
soundPool.pause(channel); // is not very likley to make
} // something useful :)
}
}
public void stopSource(AudioSource src) {
if (audioDisabled) {
return;
}
// can be stream or buffer -> so try to get mediaplayer
// if there is non try to stop soundpool
MediaPlayer mp = musicPlaying.get(src);
if (mp != null) {
mp.stop();
mp.reset();
src.setStatus(Status.Stopped);
} else {
int channel = src.getChannel();
if (channel != -1) {
soundPool.pause(channel); // is not very likley to make
// something useful :)
}
}
}
@Override
public void deleteAudioData(AudioData ad) {
for (AudioSource src : musicPlaying.keySet()) {
if (src.getAudioData() == ad) {
MediaPlayer mp = musicPlaying.remove(src);
mp.stop();
mp.release();
src.setStatus(Status.Stopped);
src.setChannel(-1);
ad.setId(-1);
break;
}
}
if (ad.getId() > 0) {
soundPool.unload(ad.getId());
ad.setId(-1);
}
}
@Override
public void setEnvironment(Environment env) {
// not yet supported
}
@Override
public void deleteFilter(Filter filter) {
}
@Override
public float getSourcePlaybackTime(AudioSource src) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

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

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