Add in game project. Setup bow asset. Working on Quaternion....

master
sigonasr2 6 years ago
parent f3806b3733
commit 32b29e4434
  1. 4
      .gitignore
  2. 3231
      Ar_SmallBow_mimiyala_D_00.obj
  3. 128
      Archer/Archer_finalrig.material
  4. BIN
      Archer/Archer_finalrig.mesh
  5. 137
      Archer/Archer_finalrig.mesh.material
  6. 16133
      Archer/Archer_finalrig.mesh.xml
  7. 66
      Archer/Archer_finalrig.mtl
  8. 5821
      Archer/Archer_finalrig.obj
  9. BIN
      Archer/Archer_finalrig.skeleton
  10. 1847
      Archer/Archer_finalrig.skeleton.xml
  11. BIN
      Archer/Archer_finalrig.ugh
  12. 100
      Archer/OgreXMLConverter.log
  13. BIN
      JmeTests/OpenAL64.dll
  14. 1
      JmeTests/assets/.keep
  15. 0
      JmeTests/assets/Interface/.keep
  16. 0
      JmeTests/assets/MatDefs/.keep
  17. 0
      JmeTests/assets/Materials/.keep
  18. 0
      JmeTests/assets/Models/.keep
  19. 0
      JmeTests/assets/Scenes/.keep
  20. 0
      JmeTests/assets/Shaders/.keep
  21. 0
      JmeTests/assets/Sounds/.keep
  22. 0
      JmeTests/assets/Textures/.keep
  23. 73
      JmeTests/build.xml
  24. BIN
      JmeTests/bulletjme.dll
  25. BIN
      JmeTests/lwjgl64.dll
  26. 880
      JmeTests/nbproject/build-impl.xml
  27. 8
      JmeTests/nbproject/genfiles.properties
  28. 84
      JmeTests/nbproject/project.properties
  29. 13
      JmeTests/nbproject/project.xml
  30. 2
      JmeTests/src/META-INF/MANIFEST.MF
  31. 504
      JmeTests/src/jme3test/TestChooser.java
  32. 64
      JmeTests/src/jme3test/animation/SubtitleTrack.java
  33. 208
      JmeTests/src/jme3test/animation/TestCameraMotionPath.java
  34. 337
      JmeTests/src/jme3test/animation/TestCinematic.java
  35. 229
      JmeTests/src/jme3test/animation/TestJaime.java
  36. 202
      JmeTests/src/jme3test/animation/TestMotionPath.java
  37. 126
      JmeTests/src/jme3test/app/TestAppStateLifeCycle.java
  38. 75
      JmeTests/src/jme3test/app/TestApplication.java
  39. 90
      JmeTests/src/jme3test/app/TestBareBonesApp.java
  40. 75
      JmeTests/src/jme3test/app/TestChangeAppIcon.java
  41. 228
      JmeTests/src/jme3test/app/TestCloneSpatial.java
  42. 367
      JmeTests/src/jme3test/app/TestCloner.java
  43. 59
      JmeTests/src/jme3test/app/TestContextRestart.java
  44. 88
      JmeTests/src/jme3test/app/TestCustomAppSettings.java
  45. 72
      JmeTests/src/jme3test/app/TestEnqueueRunnable.java
  46. 164
      JmeTests/src/jme3test/app/TestIDList.java
  47. 70
      JmeTests/src/jme3test/app/TestReleaseDirectMemory.java
  48. 87
      JmeTests/src/jme3test/app/TestResizableApp.java
  49. 114
      JmeTests/src/jme3test/app/TestTempVars.java
  50. 84
      JmeTests/src/jme3test/app/TestUseAfterFree.java
  51. 54
      JmeTests/src/jme3test/app/state/RootNodeState.java
  52. 100
      JmeTests/src/jme3test/app/state/TestAppStates.java
  53. 71
      JmeTests/src/jme3test/asset/TestAbsoluteLocators.java
  54. 228
      JmeTests/src/jme3test/asset/TestAssetCache.java
  55. 50
      JmeTests/src/jme3test/asset/TestCustomLoader.java
  56. 90
      JmeTests/src/jme3test/asset/TestManyLocators.java
  57. 85
      JmeTests/src/jme3test/asset/TestOnlineJar.java
  58. 80
      JmeTests/src/jme3test/asset/TestUrlLoading.java
  59. 25
      JmeTests/src/jme3test/asset/TextLoader.java
  60. 87
      JmeTests/src/jme3test/audio/TestAmbient.java
  61. 94
      JmeTests/src/jme3test/audio/TestDoppler.java
  62. 117
      JmeTests/src/jme3test/audio/TestMusicPlayer.form
  63. 298
      JmeTests/src/jme3test/audio/TestMusicPlayer.java
  64. 60
      JmeTests/src/jme3test/audio/TestMusicStreaming.java
  65. 70
      JmeTests/src/jme3test/audio/TestOgg.java
  66. 81
      JmeTests/src/jme3test/audio/TestReverb.java
  67. 62
      JmeTests/src/jme3test/audio/TestWav.java
  68. 150
      JmeTests/src/jme3test/awt/AppHarness.java
  69. 145
      JmeTests/src/jme3test/awt/TestApplet.java
  70. 112
      JmeTests/src/jme3test/awt/TestAwtPanels.java
  71. 270
      JmeTests/src/jme3test/awt/TestCanvas.java
  72. 69
      JmeTests/src/jme3test/awt/TestSafeCanvas.java
  73. 175
      JmeTests/src/jme3test/batching/TestBatchNode.java
  74. 372
      JmeTests/src/jme3test/batching/TestBatchNodeCluster.java
  75. 252
      JmeTests/src/jme3test/batching/TestBatchNodeTower.java
  76. 83
      JmeTests/src/jme3test/blender/TestBlenderLoader.java
  77. 65
      JmeTests/src/jme3test/bounding/TestRayCollision.java
  78. 217
      JmeTests/src/jme3test/bullet/BombControl.java
  79. 245
      JmeTests/src/jme3test/bullet/PhysicsHoverControl.java
  80. 242
      JmeTests/src/jme3test/bullet/PhysicsTestHelper.java
  81. 294
      JmeTests/src/jme3test/bullet/TestAttachDriver.java
  82. 130
      JmeTests/src/jme3test/bullet/TestAttachGhostObject.java
  83. 295
      JmeTests/src/jme3test/bullet/TestBetterCharacter.java
  84. 357
      JmeTests/src/jme3test/bullet/TestBoneRagdoll.java
  85. 251
      JmeTests/src/jme3test/bullet/TestBrickTower.java
  86. 205
      JmeTests/src/jme3test/bullet/TestBrickWall.java
  87. 152
      JmeTests/src/jme3test/bullet/TestCcd.java
  88. 107
      JmeTests/src/jme3test/bullet/TestCollisionGroups.java
  89. 98
      JmeTests/src/jme3test/bullet/TestCollisionListener.java
  90. 137
      JmeTests/src/jme3test/bullet/TestCollisionShapeFactory.java
  91. 259
      JmeTests/src/jme3test/bullet/TestFancyCar.java
  92. 117
      JmeTests/src/jme3test/bullet/TestGhostObject.java
  93. 301
      JmeTests/src/jme3test/bullet/TestHoveringTank.java
  94. 93
      JmeTests/src/jme3test/bullet/TestIK.java
  95. 148
      JmeTests/src/jme3test/bullet/TestIssue877.java
  96. 87
      JmeTests/src/jme3test/bullet/TestIssue883.java
  97. 87
      JmeTests/src/jme3test/bullet/TestIssue889.java
  98. 81
      JmeTests/src/jme3test/bullet/TestIssue918.java
  99. 72
      JmeTests/src/jme3test/bullet/TestIssue919.java
  100. 80
      JmeTests/src/jme3test/bullet/TestIssue928.java
  101. Some files were not shown because too many files have changed in this diff Show More

4
.gitignore vendored

@ -0,0 +1,4 @@
/SigDN/nbproject/private/
/SigDN/build/
/JmeTests/nbproject/private/
/JmeTests/build/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,128 @@
material archer_arms
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_glove.png
filtering point point point
}
}
}
}
material archer_body
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_body.png
filtering point point point
}
}
}
}
material archer_boots
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_boots.png
filtering point point point
}
}
}
}
material archer_face
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_head01.png
filtering point point point
}
}
}
}
material archer_hair
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.423529 0.423529 0.423529 0
emissive 0 0 0
texture_unit
{
texture ar_hair01_yellow.png
filtering point point point
}
}
}
}
material archer_legs
{
technique
{
pass
{
ambient 0 0 0
diffuse 0.509804 0.509804 0.509804
specular 0.137255 0.137255 0.137255 20
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_leg.png.png
filtering point point point
}
}
}
}
material default
{
technique
{
pass
{
ambient 0 0 0
diffuse 0.788235 0.811765 0.690196
specular 0.168627 0.168627 0.156863 20
emissive 0 0 0
}
}
}

Binary file not shown.

@ -0,0 +1,137 @@
material
{
technique
{
pass
{
}
}
}
material archer_arms
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_glove.png
filtering point point point
}
}
}
}
material archer_body
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_body.png
filtering point point point
}
}
}
}
material archer_boots
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_boots.png
filtering point point point
}
}
}
}
material archer_face
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.0980392 0.0980392 0.0980392 0
emissive 0 0 0
texture_unit
{
texture ar_head01.png
filtering point point point
}
}
}
}
material archer_hair
{
technique
{
pass
{
ambient 0 0 0
diffuse 1 1 1
specular 0.423529 0.423529 0.423529 0
emissive 0 0 0
texture_unit
{
texture ar_hair01_yellow.png
filtering point point point
}
}
}
}
material archer_legs
{
technique
{
pass
{
ambient 0 0 0
diffuse 0.509804 0.509804 0.509804
specular 0.137255 0.137255 0.137255 20
emissive 0 0 0
texture_unit
{
texture ar_ropie_d01_leg.png.png
filtering point point point
}
}
}
}
material default
{
technique
{
pass
{
ambient 0 0 0
diffuse 0.788235 0.811765 0.690196
specular 0.168627 0.168627 0.156863 20
emissive 0 0 0
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,66 @@
# Wavefront MTL
# Created by fragMOTION 1.3.5
# http://www.fragmosoft.com
newmtl archer_arms
illum 2
d 1
ka 0 0 0
kd 1 1 1
ks 0.0980392 0.0980392 0.0980392
ke 0 0 0
ns 0
map_kd ar_ropie_d01_glove.png
newmtl archer_body
illum 2
d 1
ka 0 0 0
kd 1 1 1
ks 0.0980392 0.0980392 0.0980392
ke 0 0 0
ns 0
map_kd ar_ropie_d01_body.png
newmtl archer_boots
illum 2
d 1
ka 0 0 0
kd 1 1 1
ks 0.0980392 0.0980392 0.0980392
ke 0 0 0
ns 0
map_kd ar_ropie_d01_boots.png
newmtl archer_face
illum 2
d 1
ka 0 0 0
kd 1 1 1
ks 0.0980392 0.0980392 0.0980392
ke 0 0 0
ns 0
map_kd ar_head01.png
newmtl archer_hair
illum 2
d 1
ka 0 0 0
kd 1 1 1
ks 0.423529 0.423529 0.423529
ke 0 0 0
ns 0
map_kd ar_hair01_yellow.png
newmtl archer_legs
illum 2
d 1
ka 0 0 0
kd 0.509804 0.509804 0.509804
ks 0.137255 0.137255 0.137255
ke 0 0 0
ns 20
map_kd ar_ropie_d01_leg.png.png
newmtl default
illum 2
d 1
ka 0 0 0
kd 0.788235 0.811765 0.690196
ks 0.168627 0.168627 0.156863
ke 0 0 0
ns 20

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -0,0 +1,100 @@
03:07:19: Creating resource group General
03:07:19: Creating resource group Internal
03:07:19: Creating resource group Autodetect
03:07:19: Registering ResourceManager for type Mesh
03:07:19: Registering ResourceManager for type Material
03:07:19: Registering ResourceManager for type Skeleton
03:07:19: XMLMeshSerializer reading mesh data from D:\Documents\DN\Archer\Archer_finalrig.mesh.xml...
03:07:19: Reading submeshes...
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Reading geometry...
03:07:19: Geometry done...
03:07:19: Reading bone assignments...
03:07:19: Bone assignments done.
03:07:19: Submeshes done.
03:07:19: Skeleton: Loading Archer_finalrig.skeleton
03:07:19: OGRE EXCEPTION(6:FileNotFoundException): Cannot locate resource Archer_finalrig.skeleton in resource group General or any other group. in ResourceGroupManager::openResource at ..\..\..\..\OgreMain\src\OgreResourceGroupManager.cpp (line 753)
03:07:19: Unable to load skeleton Archer_finalrig.skeleton for Mesh conversion. This Mesh will not be animated. You can ignore this message if you are using an offline tool.
03:07:19: XMLMeshSerializer import successful.
03:07:19: Reorganising vertex buffers to automatic layout..
03:07:19: MeshSerializer writing mesh data to D:\Documents\DN\Archer\Archer_finalrig.mesh...
03:07:19: File header written.
03:07:19: Writing mesh data...
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Writing submesh...
03:07:19: Exporting submesh texture aliases...
03:07:19: Submesh texture aliases exported.
03:07:19: Exporting dedicated geometry bone assignments...
03:07:19: Dedicated geometry bone assignments exported.
03:07:19: Submesh exported.
03:07:19: Exporting skeleton link...
03:07:19: Skeleton link exported.
03:07:19: Exporting bounds information....
03:07:19: Bounds information exported.
03:07:19: Exporting submesh name table...
03:07:19: Submesh name table exported.
03:07:19: Exporting edge lists...
03:07:19: Edge lists exported
03:07:19: Mesh data exported.
03:07:19: MeshSerializer export successful.
03:07:19: Unregistering ResourceManager for type Skeleton
03:07:19: Unregistering ResourceManager for type Material
03:07:19: Unregistering ResourceManager for type Mesh

Binary file not shown.

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="JmeTests" default="default" basedir=".">
<description>Builds, tests, and runs the project JmeTests.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="JmeTests-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

Binary file not shown.

Binary file not shown.

@ -0,0 +1,880 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- compilation
- jar
- execution
- debugging
- javadoc
- junit compilation
- junit execution
- junit debugging
- applet
- cleanup
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="JME3TestsTemplate-impl">
<fail message="Please build using Ant 1.7.1 or higher.">
<condition>
<not>
<antversion atleast="1.7.1"/>
</not>
</condition>
</fail>
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<available file="${application.splash}" property="splashscreen.available"/>
<condition property="main.class.available">
<and>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class">
<and>
<isset property="manifest.available"/>
<isset property="main.class.available"/>
</and>
</condition>
<condition property="do.mkdist">
<and>
<isset property="libs.CopyLibs.classpath"/>
<not>
<istrue value="${mkdist.disabled}"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
<isset property="do.mkdist"/>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available+splashscreen.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available}"/>
<istrue value="${splashscreen.available}"/>
</and>
</condition>
<condition property="do.archive">
<not>
<istrue value="${jar.archive.disabled}"/>
</not>
</condition>
<condition property="do.archive+manifest.available">
<and>
<isset property="manifest.available"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class">
<and>
<istrue value="${manifest.available+main.class}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available">
<and>
<istrue value="${manifest.available+main.class+mkdist.available+splashscreen.available}"/>
<istrue value="${do.archive}"/>
</and>
</condition>
<condition property="have.tests">
<or/>
</condition>
<condition property="have.sources">
<or>
<available file="${src.dir}"/>
</or>
</condition>
<condition property="netbeans.home+have.tests">
<and>
<isset property="netbeans.home"/>
<isset property="have.tests"/>
</and>
</condition>
<condition property="no.javadoc.preview">
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
<property name="work.dir" value="${basedir}"/>
<condition property="no.deps">
<and>
<istrue value="${no.dependencies}"/>
</and>
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<property name="runtime.encoding" value="${source.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
<condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
<length length="0" string="${endorsed.classpath}" when="greater"/>
</condition>
<property name="javac.fork" value="false"/>
<property name="jar.index" value="false"/>
<available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
<fail unless="dist.dir">Must set dist.dir</fail>
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
<fail unless="dist.jar">Must set dist.jar</fail>
</target>
<target name="-init-macrodef-property">
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
</target>
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${javac.processorpath}" name="processorpath"/>
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<mkdir dir="@{apgeneratedsrcdir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
<src>
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
<compilerarg line="${javac.compilerargs}"/>
<compilerarg value="-processorpath"/>
<compilerarg path="@{processorpath}:${empty.dir}"/>
<compilerarg line="${ap.processors.internal}"/>
<compilerarg line="${annotation.processing.processor.options}"/>
<compilerarg value="-s"/>
<compilerarg path="@{apgeneratedsrcdir}"/>
<compilerarg line="${ap.proc.none.internal}"/>
<customize/>
</javac>
</sequential>
</macrodef>
</target>
<target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${javac.processorpath}" name="processorpath"/>
<attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="${empty.dir}" name="sourcepath"/>
<attribute default="${empty.dir}" name="gensrcdir"/>
<element name="customize" optional="true"/>
<sequential>
<property location="${build.dir}/empty" name="empty.dir"/>
<mkdir dir="${empty.dir}"/>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
<src>
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</src>
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
<compilerarg line="${javac.compilerargs}"/>
<customize/>
</javac>
</sequential>
</macrodef>
</target>
<target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="," property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<delete>
<files includes="${javac.includes.binary}"/>
</delete>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
<batchtest todir="${build.test.results.dir}"/>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
</macrodef>
</target>
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</nbjpdastart>
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset dir="@{dir}" includes="${fix.classes}">
<include name="${fix.includes}*.class"/>
</fileset>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
<os family="windows"/>
</condition>
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
<isset property="debug.transport"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
<attribute default="${run.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-copylibs">
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
<element name="customize" optional="true"/>
<sequential>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath}"/>
<customize/>
</manifest>
</copylibs>
</sequential>
</macrodef>
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target name="-init-ap-cmdline-properties">
<property name="annotation.processing.enabled" value="true"/>
<property name="annotation.processing.processors.list" value=""/>
<property name="annotation.processing.processor.options" value=""/>
<property name="annotation.processing.run.all.processors" value="true"/>
<property name="javac.processorpath" value="${javac.classpath}"/>
<property name="javac.test.processorpath" value="${javac.test.classpath}"/>
<condition property="ap.supported.internal" value="true">
<not>
<matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
</not>
</condition>
</target>
<target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
<condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
<isfalse value="${annotation.processing.run.all.processors}"/>
</condition>
<condition else="" property="ap.proc.none.internal" value="-proc:none">
<isfalse value="${annotation.processing.enabled}"/>
</condition>
</target>
<target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
<property name="ap.cmd.line.internal" value=""/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target name="-deps-jar-init" unless="built-jar.properties">
<property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
<delete file="${built-jar.properties}" quiet="true"/>
</target>
<target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
<echo level="warn" message="Cycle detected: JME3TestsTemplate was already built"/>
</target>
<target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
<mkdir dir="${build.dir}"/>
<touch file="${built-jar.properties}" verbose="false"/>
<property file="${built-jar.properties}" prefix="already.built.jar."/>
<antcall target="-warn-already-built-jar"/>
<propertyfile file="${built-jar.properties}">
<entry key="${basedir}" value=""/>
</propertyfile>
</target>
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
<target depends="init" name="-check-automatic-build">
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
</target>
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
<antcall target="clean"/>
</target>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
<pathconvert property="build.generated.subdirs">
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="*"/>
</dirset>
</pathconvert>
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target if="has.persistence.xml" name="-copy-persistence-xml">
<mkdir dir="${build.classes.dir}/META-INF"/>
<copy todir="${build.classes.dir}/META-INF">
<fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available" name="-do-jar-with-libraries-and-splashscreen">
<basename file="${application.splash}" property="splashscreen.basename"/>
<mkdir dir="${build.classes.dir}/META-INF"/>
<copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
<j2seproject3:copylibs>
<customize>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries" unless="splashscreen.available">
<j2seproject3:copylibs>
<customize>
<attribute name="Main-Class" value="${main.class}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries-and-splashscreen,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<target depends="init,compile-test-single" name="run-test-with-main">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
</target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
</target>
<target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target depends="init" if="have.sources" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/*.java"/>
</fileset>
</javadoc>
<copy todir="${dist.javadoc.dir}">
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/doc-files/**"/>
</fileset>
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
<include name="**/doc-files/**"/>
</fileset>
</copy>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
<copy todir="${build.test.classes.dir}"/>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
<copy todir="${build.test.classes.dir}"/>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target name="-deps-clean-init" unless="built-clean.properties">
<property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
<delete file="${built-clean.properties}" quiet="true"/>
</target>
<target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
<echo level="warn" message="Cycle detected: JME3TestsTemplate was already built"/>
</target>
<target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
<mkdir dir="${build.dir}"/>
<touch file="${built-clean.properties}" verbose="false"/>
<property file="${built-clean.properties}" prefix="already.built.clean."/>
<antcall target="-warn-already-built-clean"/>
<propertyfile file="${built-clean.properties}">
<entry key="${basedir}" value=""/>
</propertyfile>
</target>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
</target>
<target name="-post-clean">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
<target name="-check-call-dep">
<property file="${call.built.properties}" prefix="already.built."/>
<condition property="should.call.dep">
<not>
<isset property="already.built.${call.subproject}"/>
</not>
</condition>
</target>
<target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
<ant antfile="${call.script}" inheritall="false" target="${call.target}">
<propertyset>
<propertyref prefix="transfer."/>
<mapper from="transfer.*" to="*" type="glob"/>
</propertyset>
</ant>
</target>
</project>

@ -0,0 +1,8 @@
build.xml.data.CRC32=3af791c6
build.xml.script.CRC32=fc2bfcc3
build.xml.stylesheet.CRC32=8064a381@1.80.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=0f706f4a
nbproject/build-impl.xml.script.CRC32=46d1a69a
nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45

@ -0,0 +1,84 @@
application.title=JME3TestsTemplate
application.vendor=jMonkeyEngine
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/JME3TestsTemplate.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
javac.classpath=\
${libs.jme3-jogg.classpath}:\
${libs.jme3-blender.classpath}:\
${libs.jme3-networking.classpath}:\
${libs.jme3-plugins.classpath}:\
${libs.jme3-core.classpath}:\
${libs.jme3-desktop.classpath}:\
${libs.jme3-lwjgl.classpath}:\
${libs.jme3-niftygui.classpath}:\
${libs.jme3-effects.classpath}:\
${libs.jme3-terrain.classpath}:\
${libs.jme3-bullet.classpath}:\
${libs.jme3-bullet-native.classpath}:\
${libs.jme3-test-data.classpath}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.source=1.7
javac.target=1.7
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
jnlp.applet.class=jme3test.awt.TestApplet
jnlp.applet.height=300
jnlp.applet.width=300
jnlp.codebase.type=local
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
main.class=jme3test.TestChooser
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>JmeTests</name>
<source-roots>
<root id="src.dir" name="JME3 Examples"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>

@ -0,0 +1,2 @@
Manifest-Version: 1.0

@ -0,0 +1,504 @@
/*
* 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 jme3test;
import com.jme3.app.LegacyApplication;
import com.jme3.app.SimpleApplication;
import com.jme3.system.JmeContext;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Vector;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
* Class with a main method that displays a dialog to choose any jME demo to be
* started.
*/
public class TestChooser extends JDialog {
private static final Logger logger = Logger.getLogger(TestChooser.class
.getName());
private static final long serialVersionUID = 1L;
/**
* Only accessed from EDT
*/
private java.util.List selectedClass = null;
private boolean showSetting = true;
/**
* Constructs a new TestChooser that is initially invisible.
*/
public TestChooser() throws HeadlessException {
super((JFrame) null, "TestChooser");
/** This listener ends application when window is closed (x button on top right corner of test chooser).
* @see issue#85 https://github.com/jMonkeyEngine/jmonkeyengine/issues/85
*/
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
/**
* @param classes
* vector that receives the found classes
* @return classes vector, list of all the classes in a given package (must
* be found in classpath).
*/
protected Vector<Class> find(String pckgname, boolean recursive,
Vector<Class> classes) {
URL url;
// Translate the package name into an absolute path
String name = pckgname;
if (!name.startsWith("/")) {
name = "/" + name;
}
name = name.replace('.', '/');
// Get a File object for the package
// URL url = UPBClassLoader.get().getResource(name);
url = this.getClass().getResource(name);
// URL url = ClassLoader.getSystemClassLoader().getResource(name);
pckgname = pckgname + ".";
File directory;
try {
directory = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // should never happen
}
if (directory.exists()) {
logger.fine("Searching for Demo classes in \""
+ directory.getName() + "\".");
addAllFilesInDirectory(directory, classes, pckgname, recursive);
} else {
try {
// It does not work with the filesystem: we must
// be in the case of a package contained in a jar file.
logger.fine("Searching for Demo classes in \"" + url + "\".");
URLConnection urlConnection = url.openConnection();
if (urlConnection instanceof JarURLConnection) {
JarURLConnection conn = (JarURLConnection) urlConnection;
JarFile jfile = conn.getJarFile();
Enumeration e = jfile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
Class result = load(entry.getName());
if (result != null && !classes.contains(result)) {
classes.add(result);
}
}
}
} catch (IOException e) {
logger.logp(Level.SEVERE, this.getClass().toString(),
"find(pckgname, recursive, classes)", "Exception", e);
} catch (Exception e) {
logger.logp(Level.SEVERE, this.getClass().toString(),
"find(pckgname, recursive, classes)", "Exception", e);
}
}
return classes;
}
/**
* Load a class specified by a file- or entry-name
*
* @param name
* name of a file or entry
* @return class file that was denoted by the name, null if no class or does
* not contain a main method
*/
private Class load(String name) {
if (name.endsWith(".class")
&& name.indexOf("Test") >= 0
&& name.indexOf('$') < 0) {
String classname = name.substring(0, name.length()
- ".class".length());
if (classname.startsWith("/")) {
classname = classname.substring(1);
}
classname = classname.replace('/', '.');
try {
final Class<?> cls = Class.forName(classname);
cls.getMethod("main", new Class[] { String[].class });
if (!getClass().equals(cls)) {
return cls;
}
} catch (NoClassDefFoundError e) {
// class has unresolved dependencies
return null;
} catch (ClassNotFoundException e) {
// class not in classpath
return null;
} catch (NoSuchMethodException e) {
// class does not have a main method
return null;
} catch (UnsupportedClassVersionError e){
// unsupported version
return null;
}
}
return null;
}
/**
* Used to descent in directories, loads classes via {@link #load}
*
* @param directory
* where to search for class files
* @param allClasses
* add loaded classes to this collection
* @param packageName
* current package name for the diven directory
* @param recursive
* true to descent into subdirectories
*/
private void addAllFilesInDirectory(File directory,
Collection<Class> allClasses, String packageName, boolean recursive) {
// Get the list of the files contained in the package
File[] files = directory.listFiles(getFileFilter());
if (files != null) {
for (int i = 0; i < files.length; i++) {
// we are only interested in .class files
if (files[i].isDirectory()) {
if (recursive) {
addAllFilesInDirectory(files[i], allClasses,
packageName + files[i].getName() + ".", true);
}
} else {
Class result = load(packageName + files[i].getName());
if (result != null && !allClasses.contains(result)) {
allClasses.add(result);
}
}
}
}
}
/**
* @return FileFilter for searching class files (no inner classes, only
* those with "Test" in the name)
*/
private FileFilter getFileFilter() {
return new FileFilter() {
public boolean accept(File pathname) {
return (pathname.isDirectory() && !pathname.getName().startsWith("."))
|| (pathname.getName().endsWith(".class")
&& (pathname.getName().indexOf("Test") >= 0)
&& pathname.getName().indexOf('$') < 0);
}
};
}
private void startApp(final java.util.List appClass){
if (appClass == null){
JOptionPane.showMessageDialog(rootPane,
"Please select a test from the list",
"Error",
JOptionPane.ERROR_MESSAGE);
return;
}
new Thread(new Runnable(){
public void run(){
for (int i = 0; i < appClass.size(); i++) {
Class<?> clazz = (Class)appClass.get(i);
try {
if (LegacyApplication.class.isAssignableFrom(clazz)) {
Object app = clazz.newInstance();
if (app instanceof SimpleApplication) {
final Method settingMethod = clazz.getMethod("setShowSettings", boolean.class);
settingMethod.invoke(app, showSetting);
}
final Method mainMethod = clazz.getMethod("start");
mainMethod.invoke(app);
Field contextField = LegacyApplication.class.getDeclaredField("context");
contextField.setAccessible(true);
JmeContext context = null;
while (context == null) {
context = (JmeContext) contextField.get(app);
Thread.sleep(100);
}
while (!context.isCreated()) {
Thread.sleep(100);
}
while (context.isCreated()) {
Thread.sleep(100);
}
} else {
final Method mainMethod = clazz.getMethod("main", (new String[0]).getClass());
mainMethod.invoke(clazz, new Object[]{new String[0]});
}
// wait for destroy
System.gc();
} catch (IllegalAccessException ex) {
logger.log(Level.SEVERE, "Cannot access constructor: "+clazz.getName(), ex);
} catch (IllegalArgumentException ex) {
logger.log(Level.SEVERE, "main() had illegal argument: "+clazz.getName(), ex);
} catch (InvocationTargetException ex) {
logger.log(Level.SEVERE, "main() method had exception: "+clazz.getName(), ex);
} catch (InstantiationException ex) {
logger.log(Level.SEVERE, "Failed to create app: "+clazz.getName(), ex);
} catch (NoSuchMethodException ex){
logger.log(Level.SEVERE, "Test class doesn't have main method: "+clazz.getName(), ex);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Cannot start test: "+clazz.getName(), ex);
ex.printStackTrace();
}
}
}
}).start();
}
/**
* Code to create components and action listeners.
*
* @param classes
* what Classes to show in the list box
*/
private void setup(Vector<Class> classes) {
final JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
getContentPane().setLayout(new BorderLayout());
getContentPane().add(mainPanel, BorderLayout.CENTER);
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
final FilteredJList list = new FilteredJList();
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
DefaultListModel model = new DefaultListModel();
for (Class c : classes) {
model.addElement(c);
}
list.setModel(model);
mainPanel.add(createSearchPanel(list), BorderLayout.NORTH);
mainPanel.add(new JScrollPane(list), BorderLayout.CENTER);
list.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
selectedClass = list.getSelectedValuesList();
}
});
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && selectedClass != null) {
startApp(selectedClass);
}
}
});
list.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
startApp(selectedClass);
} else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
dispose();
}
}
});
final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
mainPanel.add(buttonPanel, BorderLayout.PAGE_END);
final JButton okButton = new JButton("Ok");
okButton.setMnemonic('O');
buttonPanel.add(okButton);
getRootPane().setDefaultButton(okButton);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
startApp(selectedClass);
}
});
final JButton cancelButton = new JButton("Cancel");
cancelButton.setMnemonic('C');
buttonPanel.add(cancelButton);
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
pack();
center();
}
private class FilteredJList extends JList {
private static final long serialVersionUID = 1L;
private String filter;
private ListModel originalModel;
public void setModel(ListModel m) {
originalModel = m;
super.setModel(m);
}
private void update() {
if (filter == null || filter.length() == 0) {
super.setModel(originalModel);
}
DefaultListModel v = new DefaultListModel();
for (int i = 0; i < originalModel.getSize(); i++) {
Object o = originalModel.getElementAt(i);
String s = String.valueOf(o).toLowerCase();
if (s.contains(filter)) {
v.addElement(o);
}
}
super.setModel(v);
if (v.getSize() == 1) {
setSelectedIndex(0);
}
revalidate();
}
public String getFilter() {
return filter;
}
public void setFilter(String filter) {
this.filter = filter.toLowerCase();
update();
}
}
/**
* center the frame.
*/
private void center() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
this.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
}
/**
* Start the chooser.
*
* @param args
* command line parameters
*/
public static void main(final String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
new TestChooser().start(args);
}
protected void start(String[] args) {
final Vector<Class> classes = new Vector<Class>();
logger.fine("Composing Test list...");
addDisplayedClasses(classes);
setup(classes);
Class<?> cls;
setVisible(true);
}
protected void addDisplayedClasses(Vector<Class> classes) {
find("jme3test", true, classes);
}
private JPanel createSearchPanel(final FilteredJList classes) {
JPanel search = new JPanel();
search.setLayout(new BorderLayout());
search.add(new JLabel("Choose a Demo to start: Find: "),
BorderLayout.WEST);
final javax.swing.JTextField jtf = new javax.swing.JTextField();
jtf.getDocument().addDocumentListener(new DocumentListener() {
public void removeUpdate(DocumentEvent e) {
classes.setFilter(jtf.getText());
}
public void insertUpdate(DocumentEvent e) {
classes.setFilter(jtf.getText());
}
public void changedUpdate(DocumentEvent e) {
classes.setFilter(jtf.getText());
}
});
jtf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
selectedClass = classes.getSelectedValuesList();
startApp(selectedClass);
}
});
final JCheckBox showSettingCheck = new JCheckBox("Show Setting");
showSettingCheck.setSelected(true);
showSettingCheck.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showSetting = showSettingCheck.isSelected();
}
});
jtf.setPreferredSize(new Dimension(100, 25));
search.add(jtf, BorderLayout.CENTER);
search.add(showSettingCheck, BorderLayout.EAST);
return search;
}
}

@ -0,0 +1,64 @@
/*
* 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 jme3test.animation;
import com.jme3.cinematic.events.GuiEvent;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.elements.render.TextRenderer;
/**
*
* @author Nehon
*/
public class SubtitleTrack extends GuiEvent{
private String text="";
public SubtitleTrack(Nifty nifty, String screen,float initialDuration, String text) {
super(nifty, screen, initialDuration);
this.text=text;
}
@Override
public void onPlay() {
super.onPlay();
nifty.getScreen(screen).findElementById("text")
.getRenderer(TextRenderer.class).setText(text);
}
}

@ -0,0 +1,208 @@
/*
* 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 jme3test.animation;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.MotionPathListener;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Spline.SplineType;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.shape.Box;
public class TestCameraMotionPath extends SimpleApplication {
private Spatial teapot;
private boolean active = true;
private boolean playing = false;
private MotionPath path;
private MotionEvent cameraMotionControl;
private ChaseCamera chaser;
private CameraNode camNode;
public static void main(String[] args) {
TestCameraMotionPath app = new TestCameraMotionPath();
app.start();
}
@Override
public void simpleInitApp() {
createScene();
cam.setLocation(new Vector3f(8.4399185f, 11.189463f, 14.267577f));
camNode = new CameraNode("Motion cam", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);
camNode.setEnabled(false);
path = new MotionPath();
path.setCycle(true);
path.addWayPoint(new Vector3f(20, 3, 0));
path.addWayPoint(new Vector3f(0, 3, 20));
path.addWayPoint(new Vector3f(-20, 3, 0));
path.addWayPoint(new Vector3f(0, 3, -20));
path.setCurveTension(0.83f);
path.enableDebugShape(assetManager, rootNode);
cameraMotionControl = new MotionEvent(camNode, path);
cameraMotionControl.setLoopMode(LoopMode.Loop);
//cameraMotionControl.setDuration(15f);
cameraMotionControl.setLookAt(teapot.getWorldTranslation(), Vector3f.UNIT_Y);
cameraMotionControl.setDirectionType(MotionEvent.Direction.LookAt);
rootNode.attachChild(camNode);
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
final BitmapText wayPointsText = new BitmapText(guiFont, false);
wayPointsText.setSize(guiFont.getCharSet().getRenderedSize());
guiNode.attachChild(wayPointsText);
path.addListener(new MotionPathListener() {
public void onWayPointReach(MotionEvent control, int wayPointIndex) {
if (path.getNbWayPoints() == wayPointIndex + 1) {
wayPointsText.setText(control.getSpatial().getName() + " Finish!!! ");
} else {
wayPointsText.setText(control.getSpatial().getName() + " Reached way point " + wayPointIndex);
}
wayPointsText.setLocalTranslation((cam.getWidth() - wayPointsText.getLineWidth()) / 2, cam.getHeight(), 0);
}
});
flyCam.setEnabled(false);
chaser = new ChaseCamera(cam, teapot);
chaser.registerWithInput(inputManager);
chaser.setSmoothMotion(true);
chaser.setMaxDistance(50);
chaser.setDefaultDistance(50);
initInputs();
}
private void createScene() {
Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
mat.setFloat("Shininess", 1f);
mat.setBoolean("UseMaterialColors", true);
mat.setColor("Ambient", ColorRGBA.Black);
mat.setColor("Diffuse", ColorRGBA.DarkGray);
mat.setColor("Specular", ColorRGBA.White.mult(0.6f));
Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
matSoil.setBoolean("UseMaterialColors", true);
matSoil.setColor("Ambient", ColorRGBA.Gray);
matSoil.setColor("Diffuse", ColorRGBA.Gray);
matSoil.setColor("Specular", ColorRGBA.Black);
teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
teapot.setLocalScale(3);
teapot.setMaterial(mat);
rootNode.attachChild(teapot);
Geometry soil = new Geometry("soil", new Box(50, 1, 50));
soil.setLocalTranslation(0, -1, 0);
soil.setMaterial(matSoil);
rootNode.attachChild(soil);
DirectionalLight light = new DirectionalLight();
light.setDirection(new Vector3f(0, -1, 0).normalizeLocal());
light.setColor(ColorRGBA.White.mult(1.5f));
rootNode.addLight(light);
}
private void initInputs() {
inputManager.addMapping("display_hidePath", new KeyTrigger(KeyInput.KEY_P));
inputManager.addMapping("SwitchPathInterpolation", new KeyTrigger(KeyInput.KEY_I));
inputManager.addMapping("tensionUp", new KeyTrigger(KeyInput.KEY_U));
inputManager.addMapping("tensionDown", new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping("play_stop", new KeyTrigger(KeyInput.KEY_SPACE));
ActionListener acl = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("display_hidePath") && keyPressed) {
if (active) {
active = false;
path.disableDebugShape();
} else {
active = true;
path.enableDebugShape(assetManager, rootNode);
}
}
if (name.equals("play_stop") && keyPressed) {
if (playing) {
playing = false;
cameraMotionControl.stop();
chaser.setEnabled(true);
camNode.setEnabled(false);
} else {
playing = true;
chaser.setEnabled(false);
camNode.setEnabled(true);
cameraMotionControl.play();
}
}
if (name.equals("SwitchPathInterpolation") && keyPressed) {
if (path.getPathSplineType() == SplineType.CatmullRom) {
path.setPathSplineType(SplineType.Linear);
} else {
path.setPathSplineType(SplineType.CatmullRom);
}
}
if (name.equals("tensionUp") && keyPressed) {
path.setCurveTension(path.getCurveTension() + 0.1f);
System.err.println("Tension : " + path.getCurveTension());
}
if (name.equals("tensionDown") && keyPressed) {
path.setCurveTension(path.getCurveTension() - 0.1f);
System.err.println("Tension : " + path.getCurveTension());
}
}
};
inputManager.addListener(acl, "display_hidePath", "play_stop", "SwitchPathInterpolation", "tensionUp", "tensionDown");
}
}

@ -0,0 +1,337 @@
/*
* 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 jme3test.animation;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimationFactory;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.cinematic.Cinematic;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.PlayState;
import com.jme3.cinematic.events.*;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FadeFilter;
import com.jme3.renderer.Caps;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import de.lessvoid.nifty.Nifty;
public class TestCinematic extends SimpleApplication {
private Spatial model;
private Spatial teapot;
private MotionPath path;
private MotionEvent cameraMotionEvent;
private Cinematic cinematic;
private ChaseCamera chaseCam;
private FilterPostProcessor fpp;
private FadeFilter fade;
private float time = 0;
public static void main(String[] args) {
TestCinematic app = new TestCinematic();
app.start();
}
@Override
public void simpleInitApp() {
//just some text
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(getAssetManager(),
getInputManager(),
getAudioRenderer(),
getGuiViewPort());
Nifty nifty;
nifty = niftyDisplay.getNifty();
nifty.fromXmlWithoutStartScreen("Interface/Nifty/CinematicTest.xml");
getGuiViewPort().addProcessor(niftyDisplay);
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
final BitmapText text = new BitmapText(guiFont, false);
text.setSize(guiFont.getCharSet().getRenderedSize());
text.setText("Press enter to play/pause cinematic");
text.setLocalTranslation((cam.getWidth() - text.getLineWidth()) / 2, cam.getHeight(), 0);
guiNode.attachChild(text);
createScene();
cinematic = new Cinematic(rootNode, 20);
stateManager.attach(cinematic);
createCameraMotion();
//creating spatial animation for the teapot
AnimationFactory factory = new AnimationFactory(20, "teapotAnim");
factory.addTimeTranslation(0, new Vector3f(10, 0, 10));
factory.addTimeTranslation(20, new Vector3f(10, 0, -10));
factory.addTimeScale(10, new Vector3f(4, 4, 4));
factory.addTimeScale(20, new Vector3f(1, 1, 1));
factory.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
AnimControl control = new AnimControl();
control.addAnim(factory.buildAnimation());
teapot.addControl(control);
//fade in
cinematic.addCinematicEvent(0, new FadeEvent(true));
// cinematic.activateCamera(0, "aroundCam");
cinematic.addCinematicEvent(0, new AnimationEvent(teapot, "teapotAnim", LoopMode.DontLoop));
cinematic.addCinematicEvent(0, cameraMotionEvent);
cinematic.addCinematicEvent(0, new SoundEvent("Sound/Environment/Nature.ogg", LoopMode.Loop));
cinematic.addCinematicEvent(3f, new SoundEvent("Sound/Effects/kick.wav"));
cinematic.addCinematicEvent(3, new SubtitleTrack(nifty, "start", 3, "jMonkey engine really kicks A..."));
cinematic.addCinematicEvent(5.1f, new SoundEvent("Sound/Effects/Beep.ogg", 1));
cinematic.addCinematicEvent(2, new AnimationEvent(model, "Walk", LoopMode.Loop));
cinematic.activateCamera(0, "topView");
// cinematic.activateCamera(10, "aroundCam");
//fade out
cinematic.addCinematicEvent(19, new FadeEvent(false));
// cinematic.addCinematicEvent(19, new AbstractCinematicEvent() {
//
// @Override
// public void onPlay() {
// fade.setDuration(1f / cinematic.getSpeed());
// fade.fadeOut();
//
// }
//
// @Override
// public void onUpdate(float tpf) {
// }
//
// @Override
// public void onStop() {
// }
//
// @Override
// public void onPause() {
// }
// });
cinematic.addListener(new CinematicEventListener() {
public void onPlay(CinematicEvent cinematic) {
chaseCam.setEnabled(false);
System.out.println("play");
}
public void onPause(CinematicEvent cinematic) {
System.out.println("pause");
}
public void onStop(CinematicEvent cinematic) {
chaseCam.setEnabled(true);
fade.setValue(1);
System.out.println("stop");
}
});
//cinematic.setSpeed(2);
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, model, inputManager);
initInputs();
}
private void createCameraMotion() {
CameraNode camNode = cinematic.bindCamera("topView", cam);
camNode.setLocalTranslation(new Vector3f(0, 50, 0));
camNode.lookAt(teapot.getLocalTranslation(), Vector3f.UNIT_Y);
CameraNode camNode2 = cinematic.bindCamera("aroundCam", cam);
path = new MotionPath();
path.setCycle(true);
path.addWayPoint(new Vector3f(20, 3, 0));
path.addWayPoint(new Vector3f(0, 3, 20));
path.addWayPoint(new Vector3f(-20, 3, 0));
path.addWayPoint(new Vector3f(0, 3, -20));
path.setCurveTension(0.83f);
cameraMotionEvent = new MotionEvent(camNode2, path);
cameraMotionEvent.setLoopMode(LoopMode.Loop);
cameraMotionEvent.setLookAt(model.getWorldTranslation(), Vector3f.UNIT_Y);
cameraMotionEvent.setDirectionType(MotionEvent.Direction.LookAt);
}
private void createScene() {
model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
model.center();
model.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(model);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Cyan);
teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
teapot.setLocalTranslation(10, 0, 10);
teapot.setMaterial(mat);
teapot.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(teapot);
Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
matSoil.setBoolean("UseMaterialColors", true);
matSoil.setColor("Ambient", ColorRGBA.Gray);
matSoil.setColor("Diffuse", ColorRGBA.Green);
matSoil.setColor("Specular", ColorRGBA.Black);
Geometry soil = new Geometry("soil", new Box(50, 1, 50));
soil.setLocalTranslation(0, -6, 0);
soil.setMaterial(matSoil);
soil.setShadowMode(ShadowMode.Receive);
rootNode.attachChild(soil);
DirectionalLight light = new DirectionalLight();
light.setDirection(new Vector3f(0, -1, -1).normalizeLocal());
light.setColor(ColorRGBA.White.mult(1.5f));
rootNode.addLight(light);
fpp = new FilterPostProcessor(assetManager);
fade = new FadeFilter();
fpp.addFilter(fade);
if (renderer.getCaps().contains(Caps.GLSL100)) {
DirectionalLightShadowRenderer dlsr
= new DirectionalLightShadowRenderer(assetManager, 512, 1);
dlsr.setLight(light);
dlsr.setShadowIntensity(0.4f);
viewPort.addProcessor(dlsr);
viewPort.addProcessor(fpp);
}
}
private void initInputs() {
inputManager.addMapping("togglePause", new KeyTrigger(keyInput.KEY_RETURN));
inputManager.addMapping("navFwd", new KeyTrigger(keyInput.KEY_RIGHT));
inputManager.addMapping("navBack", new KeyTrigger(keyInput.KEY_LEFT));
ActionListener acl = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("togglePause") && keyPressed) {
if (cinematic.getPlayState() == PlayState.Playing) {
cinematic.pause();
time = cinematic.getTime();
} else {
cinematic.play();
}
}
if (cinematic.getPlayState() != PlayState.Playing) {
if (name.equals("navFwd") && keyPressed) {
time += 0.25;
FastMath.clamp(time, 0, cinematic.getInitialDuration());
cinematic.setTime(time);
}
if (name.equals("navBack") && keyPressed) {
time -= 0.25;
FastMath.clamp(time, 0, cinematic.getInitialDuration());
cinematic.setTime(time);
}
}
}
};
inputManager.addListener(acl, "togglePause", "navFwd", "navBack");
}
private class FadeEvent extends AbstractCinematicEvent {
boolean in = true;
float value = 0;
public FadeEvent(boolean in) {
super(1);
this.in = in;
value = in ? 0 : 1;
}
@Override
public void onPlay() {
fade.setDuration(1f / cinematic.getSpeed());
if (in) {
fade.fadeIn();
} else {
fade.fadeOut();
}
fade.setValue(value);
}
@Override
public void setTime(float time) {
super.setTime(time);
if (time >= fade.getDuration()) {
value = in ? 1 : 0;
fade.setValue(value);
} else {
value = time;
if (in) {
fade.setValue(time / cinematic.getSpeed());
} else {
fade.setValue(1 - time / cinematic.getSpeed());
}
}
}
@Override
public void onUpdate(float tpf) {
}
@Override
public void onStop() {
}
@Override
public void onPause() {
value = fade.getValue();
fade.pause();
}
}
}

@ -0,0 +1,229 @@
/*
* 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 jme3test.animation;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimationFactory;
import com.jme3.animation.LoopMode;
import com.jme3.app.DebugKeysAppState;
import com.jme3.app.FlyCamAppState;
import com.jme3.app.ResetStatsState;
import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.cinematic.Cinematic;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.PlayState;
import com.jme3.cinematic.events.AnimationEvent;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.PointLight;
import com.jme3.light.SpotLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FXAAFilter;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.shadow.SpotLightShadowRenderer;
/**
*
* @author Nehon
*/
public class TestJaime extends SimpleApplication {
Cinematic cinematic;
public static void main(String... argv){
TestJaime app = new TestJaime();
app.start();
}
@Override
public void simpleInitApp() {
stateManager.detach(stateManager.getState(FlyCamAppState.class));
stateManager.detach(stateManager.getState(ResetStatsState.class));
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
stateManager.detach(stateManager.getState(StatsAppState.class));
final Node jaime = LoadModel();
setupLights();
setupCamera();
setupFloor();
setupCinematic(jaime);
setupInput();
}
public Node LoadModel() {
Node jaime = (Node)assetManager.loadModel("Models/Jaime/Jaime.j3o");
jaime.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
rootNode.attachChild(jaime);
return jaime;
}
public void setupLights() {
AmbientLight al = new AmbientLight();
al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1));
rootNode.addLight(al);
SpotLight sl = new SpotLight();
sl.setColor(ColorRGBA.White.mult(1.0f));
sl.setPosition(new Vector3f(1.2074411f, 10.6868908f, 4.1489987f));
sl.setDirection(sl.getPosition().mult(-1));
sl.setSpotOuterAngle(0.1f);
sl.setSpotInnerAngle(0.004f);
rootNode.addLight(sl);
//pointlight to fake indirect light coming from the ground
PointLight pl = new PointLight();
pl.setColor(ColorRGBA.White.mult(1.5f));
pl.setPosition(new Vector3f(0, 0, 1));
pl.setRadius(2);
rootNode.addLight(pl);
SpotLightShadowRenderer shadows = new SpotLightShadowRenderer(assetManager, 1024);
shadows.setLight(sl);
shadows.setShadowIntensity(0.3f);
shadows.setEdgeFilteringMode(EdgeFilteringMode.PCF8);
viewPort.addProcessor(shadows);
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
SSAOFilter filter = new SSAOFilter(0.10997847f,0.440001f,0.39999998f,-0.008000026f);;
fpp.addFilter(filter);
fpp.addFilter(new FXAAFilter());
fpp.addFilter(new FXAAFilter());
viewPort.addProcessor(fpp);
}
public void setupCamera() {
flyCam.setEnabled(false);
}
public void setupCinematic(final Node jaime) {
cinematic = new Cinematic(rootNode, 60);
stateManager.attach(cinematic);
jaime.move(0, 0, -3);
AnimationFactory af = new AnimationFactory(0.7f, "JumpForward");
af.addTimeTranslation(0, new Vector3f(0, 0, -3));
af.addTimeTranslation(0.35f, new Vector3f(0, 1, -1.5f));
af.addTimeTranslation(0.7f, new Vector3f(0, 0, 0));
jaime.getControl(AnimControl.class).addAnim(af.buildAnimation());
cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "Idle",3, LoopMode.DontLoop));
float jumpStart = cinematic.enqueueCinematicEvent(new AnimationEvent(jaime, "JumpStart", LoopMode.DontLoop));
cinematic.addCinematicEvent(jumpStart+0.2f, new AnimationEvent(jaime, "JumpForward", LoopMode.DontLoop,1));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "JumpEnd", LoopMode.DontLoop));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "Punches", LoopMode.DontLoop));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "SideKick", LoopMode.DontLoop));
float camStart = cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "Taunt", LoopMode.DontLoop));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "Idle",1, LoopMode.DontLoop));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "Wave", LoopMode.DontLoop));
cinematic.enqueueCinematicEvent( new AnimationEvent(jaime, "Idle", LoopMode.DontLoop));
CameraNode camNode = cinematic.bindCamera("cam", cam);
camNode.setLocalTranslation(new Vector3f(1.1f, 1.2f, 2.9f));
camNode.lookAt(new Vector3f(0, 0.5f, 0), Vector3f.UNIT_Y);
MotionPath path = new MotionPath();
path.addWayPoint(new Vector3f(1.1f, 1.2f, 2.9f));
path.addWayPoint(new Vector3f(0f, 1.2f, 3.0f));
path.addWayPoint(new Vector3f(-1.1f, 1.2f, 2.9f));
path.enableDebugShape(assetManager, rootNode);
path.setCurveTension(0.8f);
MotionEvent camMotion = new MotionEvent(camNode, path,6);
camMotion.setDirectionType(MotionEvent.Direction.LookAt);
camMotion.setLookAt(new Vector3f(0, 0.5f, 0), Vector3f.UNIT_Y);
cinematic.addCinematicEvent(camStart, camMotion);
cinematic.activateCamera(0, "cam");
cinematic.fitDuration();
cinematic.setSpeed(1.2f);
cinematic.setLoopMode(LoopMode.Loop);
cinematic.play();
}
public void setupFloor() {
Quad q = new Quad(20, 20);
q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10));
Geometry geom = new Geometry("floor", q);
Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
mat.setColor("Diffuse", ColorRGBA.White);
mat.setColor("Specular", ColorRGBA.White);
mat.setColor("Ambient", ColorRGBA.Black);
mat.setBoolean("UseMaterialColors", true);
mat.setFloat("Shininess", 0);
geom.setMaterial(mat);
geom.rotate(-FastMath.HALF_PI, 0, 0);
geom.center();
geom.setShadowMode(RenderQueue.ShadowMode.Receive);
rootNode.attachChild(geom);
}
public void setupInput() {
inputManager.addMapping("start", new KeyTrigger(KeyInput.KEY_PAUSE));
inputManager.addListener(new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) {
if(name.equals("start") && isPressed){
if(cinematic.getPlayState() != PlayState.Playing){
cinematic.play();
}else{
cinematic.pause();
}
}
}
}, "start");
}
}

@ -0,0 +1,202 @@
/*
* 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 jme3test.animation;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.MotionPathListener;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Spline.SplineType;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
public class TestMotionPath extends SimpleApplication {
private Spatial teapot;
private boolean active = true;
private boolean playing = false;
private MotionPath path;
private MotionEvent motionControl;
public static void main(String[] args) {
TestMotionPath app = new TestMotionPath();
app.start();
}
@Override
public void simpleInitApp() {
createScene();
cam.setLocation(new Vector3f(8.4399185f, 11.189463f, 14.267577f));
path = new MotionPath();
path.addWayPoint(new Vector3f(10, 3, 0));
path.addWayPoint(new Vector3f(10, 3, 10));
path.addWayPoint(new Vector3f(-40, 3, 10));
path.addWayPoint(new Vector3f(-40, 3, 0));
path.addWayPoint(new Vector3f(-40, 8, 0));
path.addWayPoint(new Vector3f(10, 8, 0));
path.addWayPoint(new Vector3f(10, 8, 10));
path.addWayPoint(new Vector3f(15, 8, 10));
path.enableDebugShape(assetManager, rootNode);
motionControl = new MotionEvent(teapot,path);
motionControl.setDirectionType(MotionEvent.Direction.PathAndRotation);
motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));
motionControl.setInitialDuration(10f);
motionControl.setSpeed(2f);
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
final BitmapText wayPointsText = new BitmapText(guiFont, false);
wayPointsText.setSize(guiFont.getCharSet().getRenderedSize());
guiNode.attachChild(wayPointsText);
path.addListener(new MotionPathListener() {
public void onWayPointReach(MotionEvent control, int wayPointIndex) {
if (path.getNbWayPoints() == wayPointIndex + 1) {
wayPointsText.setText(control.getSpatial().getName() + "Finished!!! ");
} else {
wayPointsText.setText(control.getSpatial().getName() + " Reached way point " + wayPointIndex);
}
wayPointsText.setLocalTranslation((cam.getWidth() - wayPointsText.getLineWidth()) / 2, cam.getHeight(), 0);
}
});
flyCam.setEnabled(false);
ChaseCamera chaser = new ChaseCamera(cam, teapot);
// motionControl.setSpeed(-3f);
// motionControl.setLoopMode(LoopMode.Loop);
// path.setCycle(true);
// chaser.setEnabled(false);
chaser.registerWithInput(inputManager);
initInputs();
}
private void createScene() {
Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
mat.setFloat("Shininess", 1f);
mat.setBoolean("UseMaterialColors", true);
mat.setColor("Ambient", ColorRGBA.Black);
mat.setColor("Diffuse", ColorRGBA.DarkGray);
mat.setColor("Specular", ColorRGBA.White.mult(0.6f));
Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
matSoil.setBoolean("UseMaterialColors", true);
matSoil.setColor("Ambient", ColorRGBA.Black);
matSoil.setColor("Diffuse", ColorRGBA.Black);
matSoil.setColor("Specular", ColorRGBA.Black);
teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
teapot.setName("Teapot");
teapot.setLocalScale(3);
teapot.setMaterial(mat);
rootNode.attachChild(teapot);
Geometry soil = new Geometry("soil", new Box(50, 1, 50));
soil.setLocalTranslation(0, -1, 0);
soil.setMaterial(matSoil);
rootNode.attachChild(soil);
DirectionalLight light = new DirectionalLight();
light.setDirection(new Vector3f(0, -1, 0).normalizeLocal());
light.setColor(ColorRGBA.White.mult(1.5f));
rootNode.addLight(light);
}
private void initInputs() {
inputManager.addMapping("display_hidePath", new KeyTrigger(KeyInput.KEY_P));
inputManager.addMapping("SwitchPathInterpolation", new KeyTrigger(KeyInput.KEY_I));
inputManager.addMapping("tensionUp", new KeyTrigger(KeyInput.KEY_U));
inputManager.addMapping("tensionDown", new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping("play_stop", new KeyTrigger(KeyInput.KEY_SPACE));
ActionListener acl = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("display_hidePath") && keyPressed) {
if (active) {
active = false;
path.disableDebugShape();
} else {
active = true;
path.enableDebugShape(assetManager, rootNode);
}
}
if (name.equals("play_stop") && keyPressed) {
if (playing) {
playing = false;
motionControl.stop();
} else {
playing = true;
motionControl.play();
}
}
if (name.equals("SwitchPathInterpolation") && keyPressed) {
if (path.getPathSplineType() == SplineType.CatmullRom){
path.setPathSplineType(SplineType.Linear);
} else {
path.setPathSplineType(SplineType.CatmullRom);
}
}
if (name.equals("tensionUp") && keyPressed) {
path.setCurveTension(path.getCurveTension() + 0.1f);
System.err.println("Tension : " + path.getCurveTension());
}
if (name.equals("tensionDown") && keyPressed) {
path.setCurveTension(path.getCurveTension() - 0.1f);
System.err.println("Tension : " + path.getCurveTension());
}
}
};
inputManager.addListener(acl, "display_hidePath", "play_stop", "SwitchPathInterpolation", "tensionUp", "tensionDown");
}
}

@ -0,0 +1,126 @@
/*
* 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 jme3test.app;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
* Tests the app state lifecycles.
*
* @author Paul Speed
*/
public class TestAppStateLifeCycle extends SimpleApplication {
public static void main(String[] args){
TestAppStateLifeCycle app = new TestAppStateLifeCycle();
app.start();
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
System.out.println("Attaching test state.");
stateManager.attach(new TestState());
}
@Override
public void simpleUpdate(float tpf) {
if(stateManager.getState(TestState.class) != null) {
System.out.println("Detaching test state.");
stateManager.detach(stateManager.getState(TestState.class));
System.out.println("Done");
}
}
public class TestState extends AbstractAppState {
@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
System.out.println("Initialized");
}
@Override
public void stateAttached(AppStateManager stateManager) {
super.stateAttached(stateManager);
System.out.println("Attached");
}
@Override
public void update(float tpf) {
super.update(tpf);
System.out.println("update");
}
@Override
public void render(RenderManager rm) {
super.render(rm);
System.out.println("render");
}
@Override
public void postRender() {
super.postRender();
System.out.println("postRender");
}
@Override
public void stateDetached(AppStateManager stateManager) {
super.stateDetached(stateManager);
System.out.println("Detached");
}
@Override
public void cleanup() {
super.cleanup();
System.out.println("Cleanup");
}
}
}

@ -0,0 +1,75 @@
/*
* 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 jme3test.app;
import com.jme3.app.LegacyApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext.Type;
/**
* Test LegacyApplication functionality, such as create, restart, destroy, etc.
* @author Kirill
*/
public class TestApplication {
public static void main(String[] args) throws InterruptedException{
System.out.println("Creating application..");
LegacyApplication app = new LegacyApplication();
System.out.println("Starting application in LWJGL mode..");
app.start();
System.out.println("Waiting 5 seconds");
Thread.sleep(5000);
System.out.println("Closing application..");
app.stop();
Thread.sleep(2000);
System.out.println("Starting in fullscreen mode");
app = new LegacyApplication();
AppSettings settings = new AppSettings(true);
settings.setFullscreen(true);
settings.setResolution(-1,-1); // current width/height
app.setSettings(settings);
app.start();
Thread.sleep(5000);
app.stop();
Thread.sleep(2000);
System.out.println("Creating offscreen buffer application");
app = new LegacyApplication();
app.start(Type.OffscreenSurface);
Thread.sleep(3000);
System.out.println("Destroying offscreen buffer");
app.stop();
}
}

@ -0,0 +1,90 @@
/*
* 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 jme3test.app;
import com.jme3.app.LegacyApplication;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
* Test a bare-bones application, without SimpleApplication.
*/
public class TestBareBonesApp extends LegacyApplication {
private Geometry boxGeom;
public static void main(String[] args){
TestBareBonesApp app = new TestBareBonesApp();
app.start();
}
@Override
public void initialize(){
super.initialize();
System.out.println("Initialize");
// create a box
boxGeom = new Geometry("Box", new Box(2, 2, 2));
// load some default material
boxGeom.setMaterial(assetManager.loadMaterial("Interface/Logo/Logo.j3m"));
// attach box to display in primary viewport
viewPort.attachScene(boxGeom);
}
@Override
public void update(){
super.update();
// do some animation
float tpf = timer.getTimePerFrame();
boxGeom.rotate(tpf * 2, tpf * 4, tpf * 3);
// dont forget to update the scenes
boxGeom.updateLogicalState(tpf);
boxGeom.updateGeometricState();
// render the viewports
renderManager.render(tpf, context.isRenderable());
}
@Override
public void destroy(){
super.destroy();
System.out.println("Destroy");
}
}

@ -0,0 +1,75 @@
/*
* 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 jme3test.app;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.system.AppSettings;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class TestChangeAppIcon extends SimpleApplication {
private static final Logger log=Logger.getLogger(TestChangeAppIcon.class.getName());
public static void main(String[] args) {
TestChangeAppIcon app = new TestChangeAppIcon();
AppSettings settings = new AppSettings(true);
try {
Class<TestChangeAppIcon> clazz = TestChangeAppIcon.class;
settings.setIcons(new BufferedImage[]{
ImageIO.read(clazz.getResourceAsStream("/Interface/icons/SmartMonkey256.png")),
ImageIO.read(clazz.getResourceAsStream("/Interface/icons/SmartMonkey128.png")),
ImageIO.read(clazz.getResourceAsStream("/Interface/icons/SmartMonkey32.png")),
ImageIO.read(clazz.getResourceAsStream("/Interface/icons/SmartMonkey16.png")),
});
} catch (IOException e) {
log.log(java.util.logging.Level.WARNING, "Unable to load program icons", e);
}
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
// Write text on the screen (HUD)
setDisplayStatView(false);
BitmapText helloText = new BitmapText(guiFont);
helloText.setText("The icon of the app should be a smart monkey!");
helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
guiNode.attachChild(helloText);
}
}

@ -0,0 +1,228 @@
/*
* Copyright (c) 2016 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 jme3test.app;
import java.lang.reflect.*;
import java.util.*;
import com.jme3.asset.*;
import com.jme3.font.*;
import com.jme3.light.*;
import com.jme3.material.*;
import com.jme3.math.*;
import com.jme3.scene.*;
import com.jme3.scene.control.*;
import com.jme3.scene.shape.*;
import com.jme3.util.clone.*;
/**
*
*
* @author Paul Speed
*/
public class TestCloneSpatial {
public static void main( String... args ) throws Exception {
// Setup a test node with some children, controls, etc.
Node root = new Node("rootNode");
// A root light
DirectionalLight rootLight = new DirectionalLight();
root.addLight(rootLight);
Box sharedBox = new Box(1, 1, 1);
Geometry geom1 = new Geometry("box1", sharedBox);
Material sharedMaterial = new Material(); // not a valid material, just for testing
geom1.setMaterial(sharedMaterial);
Geometry geom2 = new Geometry("box2", sharedBox);
geom2.setMaterial(sharedMaterial);
root.attachChild(geom1);
root.attachChild(geom2);
// Add some controls
geom1.addControl(new BillboardControl());
geom2.addControl(new BillboardControl());
// A light that will only affect the children and be controlled
// by one child
PointLight childLight = new PointLight();
geom1.addLight(childLight);
geom2.addLight(childLight);
geom1.addControl(new LightControl(childLight));
// Set some shared user data also
Vector3f sharedUserData = new Vector3f(1, 2, 3);
geom1.setUserData("shared", sharedUserData);
geom2.setUserData("shared", sharedUserData);
dump("", root);
System.out.println("-------- cloning spatial --------------");
Node clone = root.clone(true);
dump("", clone);
System.out.println("-------- cloning spatial without cloning material --------------");
clone = root.clone(false);
dump("", clone);
System.out.println("-------- cloning BitmapText ------------");
DesktopAssetManager assets = new DesktopAssetManager(true);
BitmapFont font = assets.loadFont("Interface/Fonts/Console.fnt");
BitmapText text1 = new BitmapText(font);
text1.setText("Testing");
System.out.println("Original:");
dump("", text1);
System.out.println("Clone:");
clone = text1.clone();
dump("", clone);
}
/**
* Debug dump to check structure and identity
*/
public static void dump( String indent, Spatial s ) {
if( s instanceof Node ) {
dump(indent, (Node)s);
} else if( s instanceof Geometry ) {
dump(indent, (Geometry)s);
}
}
public static void dump( String indent, Node n ) {
System.out.println(indent + objectToString(n));
dumpSpatialProperties(indent + " ", n);
if( !n.getChildren().isEmpty() ) {
System.out.println(indent + " children:");
for( Spatial s : n.getChildren() ) {
dump(indent + " ", s);
}
}
}
public static void dump( String indent, Geometry g ) {
System.out.println(indent + objectToString(g));
//System.out.println(indent + " mesh:" + objectToString(g.getMesh()));
//System.out.println(indent + " material:" + objectToString(g.getMaterial()));
dumpSpatialProperties(indent + " ", g);
}
public static void dump( String indent, Control ctl ) {
System.out.println(indent + objectToString(ctl));
if( ctl instanceof AbstractControl ) {
System.out.println(indent + " spatial:" + objectToString(((AbstractControl)ctl).getSpatial()));
}
}
private static void dumpSpatialProperties( String indent, Spatial s ) {
dumpProperties(indent, s, "children");
if( !s.getUserDataKeys().isEmpty() ) {
System.out.println(indent + "userData:");
for( String key : s.getUserDataKeys() ) {
System.out.println(indent + " " + key + ":" + objectToString(s.getUserData(key)));
}
}
if( s.getNumControls() > 0 ) {
System.out.println(indent + "controls:");
for( int i = 0; i < s.getNumControls(); i++ ) {
Control ctl = s.getControl(i);
//dump(indent + " ", ctl);
dumpObject(indent + " ", ctl);
}
}
LightList lights = s.getLocalLightList();
if( lights.size() > 0 ) {
System.out.println(indent + "lights:");
for( Light l : lights ) {
dumpObject(indent + " ", l);
}
}
}
private static void dumpObject( String indent, Object o ) {
System.out.println(indent + objectToString(o));
dumpProperties(indent + " ", o);
}
private static void dumpProperties( String indent, Object o, String... skip ) {
if( o == null ) {
return;
}
Set<String> skipSet = new HashSet<>(Arrays.asList(skip));
for( Method m : o.getClass().getMethods() ) {
if( m.getParameterTypes().length > 0 ) {
continue;
}
String name = m.getName();
if( "getClass".equals(name) ) {
continue;
}
if( !name.startsWith("get") ) {
continue;
}
Class type = m.getReturnType();
if( type.isPrimitive() || type.isEnum() ) {
continue;
}
name = name.substring(3);
if( skipSet.contains(name.toLowerCase()) ) {
continue;
}
try {
Object value = m.invoke(o);
System.out.println(indent + name + ":" + objectToString(value));
} catch( Exception e ) {
throw new RuntimeException("Error with method:" + m, e);
}
}
}
private static String objectToString( Object o ) {
if( o == null ) {
return null;
}
String s = o + "@" + System.identityHashCode(o);
s = s.replaceAll("\\r?\\n", "");
return s;
}
}

@ -0,0 +1,367 @@
/*
* Copyright (c) 2016 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 jme3test.app;
import java.util.*;
import com.jme3.util.clone.*;
/**
*
*
* @author Paul Speed
*/
public class TestCloner {
public static void main( String... args ) {
System.out.println("Clone test:");
Cloner cloner = new Cloner();
RegularObject ro = new RegularObject(42);
System.out.println("Regular Object:" + ro);
RegularObject roCloneLegacy = ro.clone();
System.out.println("Regular Object Clone:" + roCloneLegacy);
RegularObject roClone = cloner.clone(ro);
System.out.println("cloner: Regular Object Clone:" + roClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
RegularSubclass rsc = new RegularSubclass(69, "test");
System.out.println("Regular subclass:" + rsc);
RegularSubclass rscCloneLegacy = (RegularSubclass)rsc.clone();
System.out.println("Regular subclass Clone:" + rscCloneLegacy);
RegularSubclass rscClone = cloner.clone(rsc);
System.out.println("cloner: Regular subclass Clone:" + rscClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
Parent parent = new Parent("Foo", 34);
System.out.println("Parent:" + parent);
Parent parentCloneLegacy = parent.clone();
System.out.println("Parent Clone:" + parentCloneLegacy);
Parent parentClone = cloner.clone(parent);
System.out.println("cloner: Parent Clone:" + parentClone);
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
GraphNode root = new GraphNode("root");
GraphNode child1 = root.addLink("child1");
GraphNode child2 = root.addLink("child2");
GraphNode shared = child1.addLink("shared");
child2.addLink(shared);
// Add a circular reference to get fancy
shared.addLink(root);
System.out.println("Simple graph:");
root.dump(" ");
GraphNode rootClone = cloner.clone(root);
System.out.println("clone:");
rootClone.dump(" ");
System.out.println("original:");
root.dump(" ");
GraphNode reclone = Cloner.deepClone(root);
System.out.println("reclone:");
reclone.dump(" ");
System.out.println("------------------------------------");
System.out.println();
cloner = new Cloner();
ArrayHolder arrays = new ArrayHolder(5, 3, 7, 3, 7, 2, 1, 4);
System.out.println("Array holder:" + arrays);
ArrayHolder arraysClone = cloner.clone(arrays);
System.out.println("Array holder clone:" + arraysClone);
}
public static class RegularObject implements Cloneable {
protected int i;
public RegularObject( int i ) {
this.i = i;
}
public RegularObject clone() {
try {
return (RegularObject)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[i=" + i + "]";
}
}
public static class RegularSubclass extends RegularObject {
protected String name;
public RegularSubclass( int i, String name ) {
super(i);
this.name = name;
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[i=" + i + ", name=" + name + "]";
}
}
public static class Parent implements Cloneable, JmeCloneable {
private RegularObject ro;
private RegularSubclass rsc;
public Parent( String name, int age ) {
this.ro = new RegularObject(age);
this.rsc = new RegularSubclass(age, name);
}
public Parent clone() {
try {
return (Parent)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public Parent jmeClone() {
// Ok to delegate to clone() in this case because no deep
// cloning is done there.
return clone();
}
public void cloneFields( Cloner cloner, Object original ) {
this.ro = cloner.clone(ro);
this.rsc = cloner.clone(rsc);
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[ro=" + ro + ", rsc=" + rsc + "]";
}
}
public static class GraphNode implements Cloneable, JmeCloneable {
private String name;
private List<GraphNode> links = new ArrayList<>();
public GraphNode( String name ) {
this.name = name;
}
public void dump( String indent ) {
dump(indent, new HashSet<GraphNode>());
}
private void dump( String indent, Set<GraphNode> visited ) {
if( visited.contains(this) ) {
// already been here
System.out.println(indent + this + " ** circular.");
return;
}
System.out.println(indent + this);
visited.add(this);
for( GraphNode n : links ) {
n.dump(indent + " ", visited);
}
visited.remove(this);
}
public GraphNode addLink( String name ) {
GraphNode node = new GraphNode(name);
links.add(node);
return node;
}
public GraphNode addLink( GraphNode node ) {
links.add(node);
return node;
}
public List<GraphNode> getLinks() {
return links;
}
public GraphNode jmeClone() {
try {
return (GraphNode)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public void cloneFields( Cloner cloner, Object original ) {
this.links = cloner.clone(links);
}
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[name=" + name + "]";
}
}
public static class ArrayHolder implements JmeCloneable {
private int[] intArray;
private int[][] intArray2D;
private Object[] objects;
private RegularObject[] regularObjects;
private String[] strings;
public ArrayHolder( int... values ) {
this.intArray = values;
this.intArray2D = new int[values.length][2];
for( int i = 0; i < values.length; i++ ) {
intArray2D[i][0] = values[i] + 1;
intArray2D[i][1] = values[i] * 2;
}
this.objects = new Object[values.length];
this.regularObjects = new RegularObject[values.length];
this.strings = new String[values.length];
for( int i = 0; i < values.length; i++ ) {
objects[i] = values[i];
regularObjects[i] = new RegularObject(values[i]);
strings[i] = String.valueOf(values[i]);
}
}
public ArrayHolder jmeClone() {
try {
return (ArrayHolder)super.clone();
} catch( CloneNotSupportedException e ) {
throw new RuntimeException(e);
}
}
public void cloneFields( Cloner cloner, Object original ) {
intArray = cloner.clone(intArray);
intArray2D = cloner.clone(intArray2D);
// Boxed types are not cloneable so this will fail
//objects = cloner.clone(objects);
regularObjects = cloner.clone(regularObjects);
// Strings are also not cloneable
//strings = cloner.clone(strings);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("intArray=" + intArray);
for( int i = 0; i < intArray.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(intArray[i]);
}
sb.append("], ");
sb.append("intArray2D=" + intArray2D);
for( int i = 0; i < intArray2D.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append("intArray2D[" + i + "]=" + intArray2D[i]);
for( int j = 0; j < 2; j++ ) {
if( j == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(intArray2D[i][j]);
}
sb.append("], ");
}
sb.append("], ");
sb.append("objectArray=" + objects);
for( int i = 0; i < objects.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(objects[i]);
}
sb.append("], ");
sb.append("objectArray=" + regularObjects);
for( int i = 0; i < regularObjects.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(regularObjects[i]);
}
sb.append("], ");
sb.append("stringArray=" + strings);
for( int i = 0; i < strings.length; i++ ) {
if( i == 0 ) {
sb.append("[");
} else {
sb.append(", ");
}
sb.append(strings[i]);
}
sb.append("]");
return getClass().getSimpleName() + "@" + System.identityHashCode(this)
+ "[" + sb + "]";
}
}
}

@ -0,0 +1,59 @@
/*
* 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 jme3test.app;
import com.jme3.app.LegacyApplication;
import com.jme3.system.AppSettings;
public class TestContextRestart {
public static void main(String[] args) throws InterruptedException{
AppSettings settings = new AppSettings(true);
final LegacyApplication app = new LegacyApplication();
app.setSettings(settings);
app.start();
Thread.sleep(3000);
settings.setFullscreen(true);
settings.setResolution(-1, -1);
app.setSettings(settings);
app.restart();
Thread.sleep(3000);
app.stop();
}
}

@ -0,0 +1,88 @@
package jme3test.app;
import com.jme3.scene.Mesh;
import com.jme3.system.AppSettings;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.prefs.BackingStoreException;
public class TestCustomAppSettings {
private static final String APPSETTINGS_KEY = "JME_AppSettingsTest";
private static void assertEqual(Object a, Object b) {
if (!a.equals(b)){
throw new AssertionError();
}
}
/**
* Tests preference based AppSettings.
*/
private static void testPreferenceSettings() {
AppSettings settings = new AppSettings(false);
settings.putBoolean("TestBool", true);
settings.putInteger("TestInt", 123);
settings.putString("TestStr", "HelloWorld");
settings.putFloat("TestFloat", 123.567f);
settings.put("TestObj", new Mesh()); // Objects not supported by preferences
try {
settings.save(APPSETTINGS_KEY);
} catch (BackingStoreException ex) {
ex.printStackTrace();
}
AppSettings loadedSettings = new AppSettings(false);
try {
loadedSettings.load(APPSETTINGS_KEY);
} catch (BackingStoreException ex) {
ex.printStackTrace();
}
assertEqual(loadedSettings.getBoolean("TestBool"), true);
assertEqual(loadedSettings.getInteger("TestInt"), 123);
assertEqual(loadedSettings.getString("TestStr"), "HelloWorld");
assertEqual(loadedSettings.get("TestFloat"), 123.567f);
}
/**
* Test Java properties file based AppSettings.
*/
private static void testFileSettings() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
AppSettings settings = new AppSettings(false);
settings.putBoolean("TestBool", true);
settings.putInteger("TestInt", 123);
settings.putString("TestStr", "HelloWorld");
settings.putFloat("TestFloat", 123.567f);
settings.put("TestObj", new Mesh()); // Objects not supported by file settings
try {
settings.save(baos);
} catch (IOException ex) {
ex.printStackTrace();
}
AppSettings loadedSettings = new AppSettings(false);
try {
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
loadedSettings.load(bais);
} catch (IOException ex) {
ex.printStackTrace();
}
assertEqual(loadedSettings.getBoolean("TestBool"), true);
assertEqual(loadedSettings.getInteger("TestInt"), 123);
assertEqual(loadedSettings.getString("TestStr"), "HelloWorld");
assertEqual(loadedSettings.get("TestFloat"), 123.567f);
}
public static void main(String[] args){
testPreferenceSettings();
testFileSettings();
System.out.println("All OK");
}
}

@ -0,0 +1,72 @@
package jme3test.app;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
* @author john01dav
*/
public class TestEnqueueRunnable extends SimpleApplication{
private ExampleAsyncTask exampleAsyncTask;
public static void main(String[] args){
new TestEnqueueRunnable().start();
}
@Override
public void simpleInitApp(){
Geometry geom = new Geometry("Box", new Box(1, 1, 1));
Material material = new Material(getAssetManager(), "/Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", ColorRGBA.Blue); //a color is needed to start with
geom.setMaterial(material);
getRootNode().attachChild(geom);
exampleAsyncTask = new ExampleAsyncTask(material);
exampleAsyncTask.getThread().start();
}
@Override
public void destroy(){
exampleAsyncTask.endTask();
super.destroy();
}
private class ExampleAsyncTask implements Runnable{
private final Thread thread;
private final Material material;
private volatile boolean running = true;
public ExampleAsyncTask(Material material){
this.thread = new Thread(this);
this.material = material;
}
public Thread getThread(){
return thread;
}
public void run(){
while(running){
enqueue(new Runnable(){ //primary usage of this in real applications would use lambda expressions which are unavailable at java 6
public void run(){
material.setColor("Color", ColorRGBA.randomColor());
}
});
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
public void endTask(){
running = false;
thread.interrupt();
}
}
}

@ -0,0 +1,164 @@
/*
* 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 jme3test.app;
import com.jme3.renderer.IDList;
import java.util.*;
public class TestIDList {
static class StateCol {
static Random rand = new Random();
Map<Integer, Object> objs = new HashMap<Integer, Object>();
public StateCol(){
// populate with free ids
List<Integer> freeIds = new ArrayList();
for (int i = 0; i < 16; i++){
freeIds.add(i);
}
// create random
int numStates = rand.nextInt(6) + 1;
for (int i = 0; i < numStates; i++){
// remove a random id from free id list
int idx = rand.nextInt(freeIds.size());
int id = freeIds.remove(idx);
objs.put(id, new Object());
}
}
public void print(){
System.out.println("-----------------");
Set<Integer> keys = objs.keySet();
Integer[] keysArr = keys.toArray(new Integer[0]);
Arrays.sort(keysArr);
for (int i = 0; i < keysArr.length; i++){
System.out.println(keysArr[i]+" => "+objs.get(keysArr[i]).hashCode());
}
}
}
static IDList list = new IDList();
static int boundSlot = 0;
static Object[] slots = new Object[16];
static boolean[] enabledSlots = new boolean[16];
static void enable(int slot){
System.out.println("Enabled SLOT["+slot+"]");
if (enabledSlots[slot] == true){
System.err.println("FAIL! Extra state change");
}
enabledSlots[slot] = true;
}
static void disable(int slot){
System.out.println("Disabled SLOT["+slot+"]");
if (enabledSlots[slot] == false){
System.err.println("FAIL! Extra state change");
}
enabledSlots[slot] = false;
}
static void setSlot(int slot, Object val){
if (!list.moveToNew(slot)){
enable(slot);
}
if (slots[slot] != val){
System.out.println("SLOT["+slot+"] = "+val.hashCode());
slots[slot] = val;
}
}
static void checkSlots(StateCol state){
for (int i = 0; i < 16; i++){
if (slots[i] != null && enabledSlots[i] == false){
System.err.println("FAIL! SLOT["+i+"] assigned, but disabled");
}
if (slots[i] == null && enabledSlots[i] == true){
System.err.println("FAIL! SLOT["+i+"] enabled, but not assigned");
}
Object val = state.objs.get(i);
if (val != null){
if (slots[i] != val)
System.err.println("FAIL! SLOT["+i+"] does not contain correct value");
if (!enabledSlots[i])
System.err.println("FAIL! SLOT["+i+"] is not enabled");
}else{
if (slots[i] != null)
System.err.println("FAIL! SLOT["+i+"] is not set");
if (enabledSlots[i])
System.err.println("FAIL! SLOT["+i+"] is enabled");
}
}
}
static void clearSlots(){
for (int i = 0; i < list.oldLen; i++){
int slot = list.oldList[i];
disable(slot);
slots[slot] = null;
}
list.copyNewToOld();
// context.attribIndexList.print();
}
static void setState(StateCol state){
state.print();
for (Map.Entry<Integer, Object> entry : state.objs.entrySet()){
setSlot(entry.getKey(), entry.getValue());
}
clearSlots();
checkSlots(state);
}
public static void main(String[] args){
StateCol[] states = new StateCol[20];
for (int i = 0; i < states.length; i++)
states[i] = new StateCol();
// shuffle would be useful here..
for (int i = 0; i < states.length; i++){
setState(states[i]);
}
}
}

@ -0,0 +1,70 @@
/*
* 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 jme3test.app;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.util.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
public class TestReleaseDirectMemory extends SimpleApplication {
public static void main(String[] args){
TestReleaseDirectMemory app = new TestReleaseDirectMemory();
app.start();
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
ByteBuffer buf = BufferUtils.createByteBuffer(500000);
BufferUtils.destroyDirectBuffer(buf);
FloatBuffer buf2 = BufferUtils.createFloatBuffer(500000);
BufferUtils.destroyDirectBuffer(buf2);
}
}

@ -0,0 +1,87 @@
/*
* Copyright (c) 2009-2015 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 jme3test.app;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.font.Rectangle;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import jme3test.model.shape.TestBox;
/**
* Tests the capability to resize the application window.
*
* @author Kirill Vainer
*/
public class TestResizableApp extends SimpleApplication {
private BitmapText txt;
public static void main(String[] args){
TestResizableApp app = new TestResizableApp();
AppSettings settings = new AppSettings(true);
settings.setResizable(true);
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}
public void reshape(int width, int height) {
super.reshape(width, height);
// Need to move text relative to app height
txt.setLocalTranslation(0, settings.getHeight(), 0);
txt.setText("Drag the corners of the application to resize it.\n" +
"Current Size: " + settings.getWidth() + "x" + settings.getHeight());
}
public void simpleInitApp() {
flyCam.setDragToRotate(true);
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
txt = new BitmapText(loadGuiFont(), false);
txt.setText("Drag the corners of the application to resize it.\n" +
"Current Size: " + settings.getWidth() + "x" + settings.getHeight());
txt.setLocalTranslation(0, settings.getHeight(), 0);
guiNode.attachChild(txt);
}
}

@ -0,0 +1,114 @@
/*
* 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 jme3test.app;
import com.jme3.math.Vector3f;
import com.jme3.util.TempVars;
public class TestTempVars {
private static final int ITERATIONS = 10000000;
private static final int NANOS_TO_MS = 1000000;
private static final Vector3f sumCompute = new Vector3f();
public static void main(String[] args) {
long milliseconds, nanos;
for (int i = 0; i < 4; i++){
System.gc();
}
// sumCompute.set(0, 0, 0);
// long nanos = System.nanoTime();
// for (int i = 0; i < ITERATIONS; i++) {
// recursiveMethod(0);
// }
// long milliseconds = (System.nanoTime() - nanos) / NANOS_TO_MS;
// System.out.println("100 million TempVars calls with 5 recursions: " + milliseconds + " ms");
// System.out.println(sumCompute);
sumCompute.set(0, 0, 0);
nanos = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
methodThatUsesTempVars();
}
milliseconds = (System.nanoTime() - nanos) / NANOS_TO_MS;
System.out.println("100 million TempVars calls: " + milliseconds + " ms");
System.out.println(sumCompute);
sumCompute.set(0, 0, 0);
nanos = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
methodThatUsesAllocation();
}
milliseconds = (System.nanoTime() - nanos) / NANOS_TO_MS;
System.out.println("100 million allocation calls: " + milliseconds + " ms");
System.out.println(sumCompute);
nanos = System.nanoTime();
for (int i = 0; i < 10; i++){
System.gc();
}
milliseconds = (System.nanoTime() - nanos) / NANOS_TO_MS;
System.out.println("cleanup time after allocation calls: " + milliseconds + " ms");
}
public static void methodThatUsesAllocation(){
Vector3f vector = new Vector3f();
vector.set(0.1f, 0.2f, 0.3f);
sumCompute.addLocal(vector);
}
public static void recursiveMethod(int recurse) {
TempVars vars = TempVars.get();
{
vars.vect1.set(0.1f, 0.2f, 0.3f);
if (recurse < 4) {
recursiveMethod(recurse + 1);
}
sumCompute.addLocal(vars.vect1);
}
vars.release();
}
public static void methodThatUsesTempVars() {
TempVars vars = TempVars.get();
{
vars.vect1.set(0.1f, 0.2f, 0.3f);
sumCompute.addLocal(vars.vect1);
}
vars.release();
}
}

@ -0,0 +1,84 @@
/*
* 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 jme3test.app;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestUseAfterFree extends SimpleApplication {
private float time = 0;
private Material mat;
private Texture deletedTex;
public static void main(String[] args) {
TestUseAfterFree app = new TestUseAfterFree();
app.start();
}
@Override
public void simpleInitApp() {
Box box = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", box);
mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
if (time < 0) {
if (deletedTex != null) {
deletedTex.getImage().resetObject();
}
return;
}
time += tpf;
if (time > 5) {
System.out.println("Assiging texture to deleted object!");
deletedTex = assetManager.loadTexture("Interface/Logo/Monkey.png");
BufferUtils.destroyDirectBuffer(deletedTex.getImage().getData(0));
mat.setTexture("ColorMap", deletedTex);
time = -1;
}
}
}

@ -0,0 +1,54 @@
/*
* 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 jme3test.app.state;
import com.jme3.app.state.AbstractAppState;
import com.jme3.scene.Node;
public class RootNodeState extends AbstractAppState {
private Node rootNode = new Node("Root Node");
public Node getRootNode(){
return rootNode;
}
@Override
public void update(float tpf) {
super.update(tpf);
rootNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
}
}

@ -0,0 +1,100 @@
/*
* 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 jme3test.app.state;
import com.jme3.app.LegacyApplication;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.scene.Spatial;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
public class TestAppStates extends LegacyApplication {
public static void main(String[] args){
TestAppStates app = new TestAppStates();
app.start();
}
@Override
public void start(JmeContext.Type contextType){
AppSettings settings = new AppSettings(true);
settings.setResolution(1024, 768);
setSettings(settings);
super.start(contextType);
}
@Override
public void initialize(){
super.initialize();
System.out.println("Initialize");
RootNodeState state = new RootNodeState();
viewPort.attachScene(state.getRootNode());
stateManager.attach(state);
Spatial model = assetManager.loadModel("Models/Teapot/Teapot.obj");
model.scale(3);
model.setMaterial(assetManager.loadMaterial("Interface/Logo/Logo.j3m"));
state.getRootNode().attachChild(model);
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
inputManager,
audioRenderer,
guiViewPort);
niftyDisplay.getNifty().fromXml("Interface/Nifty/HelloJme.xml", "start");
guiViewPort.addProcessor(niftyDisplay);
}
@Override
public void update(){
super.update();
// do some animation
float tpf = timer.getTimePerFrame();
stateManager.update(tpf);
stateManager.render(renderManager);
// render the viewports
renderManager.render(tpf, context.isRenderable());
}
@Override
public void destroy(){
super.destroy();
System.out.println("Destroy");
}
}

@ -0,0 +1,71 @@
/*
* 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 jme3test.asset;
import com.jme3.asset.AssetManager;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.audio.AudioData;
import com.jme3.audio.plugins.WAVLoader;
import com.jme3.system.JmeSystem;
import com.jme3.texture.Texture;
import com.jme3.texture.plugins.AWTLoader;
public class TestAbsoluteLocators {
public static void main(String[] args){
AssetManager am = JmeSystem.newAssetManager();
am.registerLoader(AWTLoader.class, "jpg");
am.registerLoader(WAVLoader.class, "wav");
// register absolute locator
am.registerLocator("/", ClasspathLocator.class);
// find a sound
AudioData audio = am.loadAudio("Sound/Effects/Gun.wav");
// find a texture
Texture tex = am.loadTexture("Textures/Terrain/Pond/Pond.jpg");
if (audio == null)
throw new RuntimeException("Cannot find audio!");
else
System.out.println("Audio loaded from Sounds/Effects/Gun.wav");
if (tex == null)
throw new RuntimeException("Cannot find texture!");
else
System.out.println("Texture loaded from Textures/Terrain/Pond/Pond.jpg");
System.out.println("Success!");
}
}

@ -0,0 +1,228 @@
/*
* 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 jme3test.asset;
import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetProcessor;
import com.jme3.asset.CloneableAssetProcessor;
import com.jme3.asset.CloneableSmartAsset;
import com.jme3.asset.cache.AssetCache;
import com.jme3.asset.cache.SimpleAssetCache;
import com.jme3.asset.cache.WeakRefAssetCache;
import com.jme3.asset.cache.WeakRefCloneAssetCache;
import java.util.ArrayList;
import java.util.List;
public class TestAssetCache {
/**
* Counter for asset keys
*/
private static int counter = 0;
/**
* Dummy data is an asset having 10 KB to put a dent in the garbage collector
*/
private static class DummyData implements CloneableSmartAsset {
private AssetKey key;
private byte[] data = new byte[10 * 1024];
@Override
public Object clone(){
try {
DummyData clone = (DummyData) super.clone();
clone.data = data.clone();
return clone;
} catch (CloneNotSupportedException ex) {
throw new AssertionError();
}
}
public byte[] getData(){
return data;
}
public AssetKey getKey() {
return key;
}
public void setKey(AssetKey key) {
this.key = key;
}
}
/**
* Dummy key is indexed by a generated ID
*/
private static class DummyKey extends AssetKey<DummyData> implements Cloneable {
private int id = 0;
public DummyKey(){
super(".");
id = counter++;
}
public DummyKey(int id){
super(".");
this.id = id;
}
@Override
public int hashCode(){
return id;
}
@Override
public boolean equals(Object other){
return ((DummyKey)other).id == id;
}
@Override
public DummyKey clone(){
return new DummyKey(id);
}
@Override
public String toString() {
return "ID=" + id;
}
}
private static void runTest(boolean cloneAssets, boolean smartCache, boolean keepRefs, int limit) {
counter = 0;
List<Object> refs = new ArrayList<Object>(limit);
AssetCache cache;
AssetProcessor proc = null;
if (cloneAssets) {
proc = new CloneableAssetProcessor();
}
if (smartCache) {
if (cloneAssets) {
cache = new WeakRefCloneAssetCache();
} else {
cache = new WeakRefAssetCache();
}
} else {
cache = new SimpleAssetCache();
}
System.gc();
System.gc();
System.gc();
System.gc();
long memory = Runtime.getRuntime().freeMemory();
while (counter < limit){
// Create a key
DummyKey key = new DummyKey();
// Create some data
DummyData data = new DummyData();
// Post process the data before placing it in the cache
if (proc != null){
data = (DummyData) proc.postProcess(key, data);
}
if (data.key != null){
// Keeping a hard reference to the key in the cache
// means the asset will never be collected => bug
throw new AssertionError();
}
cache.addToCache(key, data);
// Get the asset from the cache
AssetKey<DummyData> keyToGet = key.clone();
// NOTE: Commented out because getFromCache leaks the original key
// DummyData someLoaded = (DummyData) cache.getFromCache(keyToGet);
// if (someLoaded != data){
// // Failed to get the same asset from the cache => bug
// // Since a hard reference to the key is kept,
// // it cannot be collected at this point.
// throw new AssertionError();
// }
// Clone the asset
if (proc != null){
// Data is now the clone!
data = (DummyData) proc.createClone(data);
if (smartCache) {
// Registering a clone is only needed
// if smart cache is used.
cache.registerAssetClone(keyToGet, data);
// The clone of the asset must have the same key as the original
// otherwise => bug
if (data.key != key){
throw new AssertionError();
}
}
}
// Keep references to the asset => *should* prevent
// collections of the asset in the cache thus causing
// an out of memory error.
if (keepRefs){
// Prevent the saved references from taking too much memory ..
if (cloneAssets) {
data.data = null;
}
refs.add(data);
}
if ((counter % 1000) == 0){
long newMem = Runtime.getRuntime().freeMemory();
System.out.println("Allocated objects: " + counter);
System.out.println("Allocated memory: " + ((memory - newMem)/(1024*1024)) + " MB" );
memory = newMem;
}
}
}
public static void main(String[] args){
// Test cloneable smart asset
System.out.println("====== Running Cloneable Smart Asset Test ======");
runTest(true, true, false, 100000);
// Test non-cloneable smart asset
System.out.println("====== Running Non-cloneable Smart Asset Test ======");
runTest(false, true, false, 100000);
}
}

@ -0,0 +1,50 @@
/*
* 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 jme3test.asset;
import com.jme3.asset.AssetLoader;
import com.jme3.asset.AssetManager;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.system.JmeSystem;
/**
* Demonstrates loading a file from a custom {@link AssetLoader}
*/
public class TestCustomLoader {
public static void main(String[] args){
AssetManager assetManager = JmeSystem.newAssetManager();
assetManager.registerLocator("/", ClasspathLocator.class);
assetManager.registerLoader(TextLoader.class, "fnt");
System.out.println(assetManager.loadAsset("Interface/Fonts/Console.fnt"));
}
}

@ -0,0 +1,90 @@
/*
* 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 jme3test.asset;
import com.jme3.asset.*;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.asset.plugins.UrlLocator;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.system.JmeSystem;
public class TestManyLocators {
public static void main(String[] args){
AssetManager am = JmeSystem.newAssetManager();
am.registerLocator("http://www.jmonkeyengine.com/wp-content/uploads/2010/09/",
UrlLocator.class);
am.registerLocator("town.zip", ZipLocator.class);
am.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip",
HttpZipLocator.class);
am.registerLocator("/", ClasspathLocator.class);
// Try loading from Core-Data source package
AssetInfo a = am.locateAsset(new AssetKey<Object>("Interface/Fonts/Default.fnt"));
// Try loading from town scene zip file
AssetInfo b = am.locateAsset(new ModelKey("casaamarela.jpg"));
// Try loading from wildhouse online scene zip file
AssetInfo c = am.locateAsset(new ModelKey("glasstile2.png"));
// Try loading directly from HTTP
AssetInfo d = am.locateAsset(new TextureKey("planet-2.jpg"));
if (a == null)
System.out.println("Failed to load from classpath");
else
System.out.println("Found classpath font: " + a.toString());
if (b == null)
System.out.println("Failed to load from town.zip");
else
System.out.println("Found zip image: " + b.toString());
if (c == null)
System.out.println("Failed to load from wildhouse.zip on googlecode.com");
else
System.out.println("Found online zip image: " + c.toString());
if (d == null)
System.out.println("Failed to load from HTTP");
else
System.out.println("Found HTTP showcase image: " + d.toString());
}
}

@ -0,0 +1,85 @@
/*
* 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 jme3test.asset;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import com.jme3.ui.Picture;
/**
* This tests loading a file from a jar stored online.
* @author Kirill Vainer
*/
public class TestOnlineJar extends SimpleApplication {
public static void main(String[] args){
TestOnlineJar app = new TestOnlineJar();
app.start();
}
@Override
public void simpleInitApp() {
// create a simple plane/quad
Quad quadMesh = new Quad(1, 1);
quadMesh.updateGeometry(1, 1, true);
Geometry quad = new Geometry("Textured Quad", quadMesh);
assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/town.zip",
HttpZipLocator.class);
assetManager.registerLocator("https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jmonkeyengine/wildhouse.zip",
HttpZipLocator.class);
Picture pic1 = new Picture("Picture1");
pic1.move(0, 0, -1);
pic1.setPosition(0, 0);
pic1.setWidth(128);
pic1.setHeight(128);
pic1.setImage(assetManager, "grass.jpg", false);
guiNode.attachChild(pic1);
Picture pic2 = new Picture("Picture1");
pic2.move(0, 0, -1);
pic2.setPosition(128, 0);
pic2.setWidth(128);
pic2.setHeight(128);
pic2.setImage(assetManager, "glasstile2.png", false);
guiNode.attachChild(pic2);
}
}

@ -0,0 +1,80 @@
/*
* 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 jme3test.asset;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.asset.plugins.UrlLocator;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
/**
* Load an image and display it from the internet using the UrlLocator.
* @author Kirill Vainer
*/
public class TestUrlLoading extends SimpleApplication {
public static void main(String[] args){
TestUrlLoading app = new TestUrlLoading();
app.start();
}
@Override
public void simpleInitApp() {
// create a simple plane/quad
Quad quadMesh = new Quad(1, 1);
quadMesh.updateGeometry(1, 1, true);
Geometry quad = new Geometry("Textured Quad", quadMesh);
assetManager.registerLocator("https://raw.githubusercontent.com/jMonkeyEngine/BookSamples/master/assets/Textures/",
UrlLocator.class);
TextureKey key = new TextureKey("mucha-window.png", false);
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", tex);
quad.setMaterial(mat);
float aspect = tex.getImage().getWidth() / (float) tex.getImage().getHeight();
quad.setLocalScale(new Vector3f(aspect * 1.5f, 1.5f, 1));
quad.center();
rootNode.attachChild(quad);
}
}

@ -0,0 +1,25 @@
package jme3test.asset;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import java.io.IOException;
import java.util.Scanner;
/**
* An example implementation of {@link AssetLoader} to load text
* files as strings.
*/
public class TextLoader implements AssetLoader {
public Object load(AssetInfo assetInfo) throws IOException {
Scanner scan = new Scanner(assetInfo.openStream());
StringBuilder sb = new StringBuilder();
try {
while (scan.hasNextLine()) {
sb.append(scan.nextLine()).append('\n');
}
} finally {
scan.close();
}
return sb.toString();
}
}

@ -0,0 +1,87 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioData.DataType;
import com.jme3.audio.AudioNode;
import com.jme3.audio.Environment;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
public class TestAmbient extends SimpleApplication {
private AudioNode nature, waves;
public static void main(String[] args) {
TestAmbient test = new TestAmbient();
test.start();
}
@Override
public void simpleInitApp() {
float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0,
1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f,
0.00f, -229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f,
0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f};
Environment env = new Environment(eax);
audioRenderer.setEnvironment(env);
waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg",
DataType.Buffer);
waves.setPositional(true);
waves.setLocalTranslation(new Vector3f(0, 0,0));
waves.setMaxDistance(100);
waves.setRefDistance(5);
nature = new AudioNode(assetManager, "Sound/Environment/Nature.ogg",
DataType.Stream);
nature.setPositional(false);
nature.setVolume(3);
waves.playInstance();
nature.play();
// just a blue box to mark the spot
Box box1 = new Box(.5f, .5f, .5f);
Geometry player = new Geometry("Player", box1);
Material mat1 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
player.setMaterial(mat1);
rootNode.attachChild(player);
}
@Override
public void simpleUpdate(float tpf) {
}
}

@ -0,0 +1,94 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Torus;
/**
* Test Doppler Effect
*/
public class TestDoppler extends SimpleApplication {
private float pos = -5;
private float vel = 5;
private AudioNode ufoNode;
public static void main(String[] args){
TestDoppler test = new TestDoppler();
test.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(10);
Torus torus = new Torus(10, 6, 1, 3);
Geometry g = new Geometry("Torus Geom", torus);
g.rotate(-FastMath.HALF_PI, 0, 0);
g.center();
g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m"));
// rootNode.attachChild(g);
ufoNode = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", AudioData.DataType.Buffer);
ufoNode.setLooping(true);
ufoNode.setPitch(0.5f);
ufoNode.setRefDistance(1);
ufoNode.setMaxDistance(100000000);
ufoNode.setVelocityFromTranslation(true);
ufoNode.play();
Geometry ball = new Geometry("Beeper", new Sphere(10, 10, 0.1f));
ball.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m"));
ufoNode.attachChild(ball);
rootNode.attachChild(ufoNode);
}
@Override
public void simpleUpdate(float tpf) {
pos += tpf * vel;
if (pos < -10 || pos > 10) {
vel *= -1;
}
ufoNode.setLocalTranslation(new Vector3f(pos, 0, 0));
}
}

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="3"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<Events>
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,82,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnlButtons">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JSlider" name="sldVolume">
<Properties>
<Property name="majorTickSpacing" type="int" value="20"/>
<Property name="orientation" type="int" value="1"/>
<Property name="paintTicks" type="boolean" value="true"/>
<Property name="value" type="int" value="100"/>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="sldVolumeStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnRewind">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;&lt;"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnStop">
<Properties>
<Property name="text" type="java.lang.String" value="[ ]"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnStopActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnPlay">
<Properties>
<Property name="text" type="java.lang.String" value="II / &gt;"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnPlayActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnFF">
<Properties>
<Property name="text" type="java.lang.String" value="&gt;&gt;"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFFActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnOpen">
<Properties>
<Property name="text" type="java.lang.String" value="Open ..."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnOpenActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnlBar">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="First"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="lblTime">
<Properties>
<Property name="text" type="java.lang.String" value="0:00-0:00"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
<EmptyBorder bottom="3" left="3" right="3" top="3"/>
</Border>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSlider" name="sldBar">
<Properties>
<Property name="value" type="int" value="0"/>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="sldBarStateChanged"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

@ -0,0 +1,298 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.audio;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import com.jme3.audio.*;
import com.jme3.audio.AudioSource.Status;
import com.jme3.audio.plugins.OGGLoader;
import com.jme3.audio.plugins.WAVLoader;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeSystem;
import java.io.*;
import javax.swing.JFileChooser;
public class TestMusicPlayer extends javax.swing.JFrame {
private AudioRenderer ar;
private AudioData musicData;
private AudioNode musicSource;
private float musicLength = 0;
private float curTime = 0;
private Listener listener = new Listener();
public TestMusicPlayer() {
initComponents();
setLocationRelativeTo(null);
initAudioPlayer();
}
private void initAudioPlayer(){
AppSettings settings = new AppSettings(true);
settings.setRenderer(null); // disable rendering
settings.setAudioRenderer("LWJGL");
ar = JmeSystem.newAudioRenderer(settings);
ar.initialize();
ar.setListener(listener);
AudioContext.setAudioRenderer(ar);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
pnlButtons = new javax.swing.JPanel();
sldVolume = new javax.swing.JSlider();
btnRewind = new javax.swing.JButton();
btnStop = new javax.swing.JButton();
btnPlay = new javax.swing.JButton();
btnFF = new javax.swing.JButton();
btnOpen = new javax.swing.JButton();
pnlBar = new javax.swing.JPanel();
lblTime = new javax.swing.JLabel();
sldBar = new javax.swing.JSlider();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
pnlButtons.setLayout(new javax.swing.BoxLayout(pnlButtons, javax.swing.BoxLayout.LINE_AXIS));
sldVolume.setMajorTickSpacing(20);
sldVolume.setOrientation(javax.swing.JSlider.VERTICAL);
sldVolume.setPaintTicks(true);
sldVolume.setValue(100);
sldVolume.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sldVolumeStateChanged(evt);
}
});
pnlButtons.add(sldVolume);
btnRewind.setText("<<");
pnlButtons.add(btnRewind);
btnStop.setText("[ ]");
btnStop.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStopActionPerformed(evt);
}
});
pnlButtons.add(btnStop);
btnPlay.setText("II / >");
btnPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPlayActionPerformed(evt);
}
});
pnlButtons.add(btnPlay);
btnFF.setText(">>");
btnFF.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFFActionPerformed(evt);
}
});
pnlButtons.add(btnFF);
btnOpen.setText("Open ...");
btnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnOpenActionPerformed(evt);
}
});
pnlButtons.add(btnOpen);
getContentPane().add(pnlButtons, java.awt.BorderLayout.CENTER);
pnlBar.setLayout(new javax.swing.BoxLayout(pnlBar, javax.swing.BoxLayout.LINE_AXIS));
lblTime.setText("0:00-0:00");
lblTime.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 3, 3));
pnlBar.add(lblTime);
sldBar.setValue(0);
sldBar.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sldBarStateChanged(evt);
}
});
pnlBar.add(sldBar);
getContentPane().add(pnlBar, java.awt.BorderLayout.PAGE_START);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOpenActionPerformed
JFileChooser chooser = new JFileChooser();
chooser.setAcceptAllFileFilterUsed(true);
chooser.setDialogTitle("Select OGG file");
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setMultiSelectionEnabled(false);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION){
btnStopActionPerformed(null);
final File selected = chooser.getSelectedFile();
AssetLoader loader = null;
if(selected.getName().endsWith(".wav")){
loader = new WAVLoader();
}else{
loader = new OGGLoader();
}
AudioKey key = new AudioKey(selected.getName(), true, true);
try{
musicData = (AudioData) loader.load(new AssetInfo(null, key) {
@Override
public InputStream openStream() {
try{
return new FileInputStream(selected);
}catch (FileNotFoundException ex){
ex.printStackTrace();
}
return null;
}
});
}catch (IOException ex){
ex.printStackTrace();
}
musicSource = new AudioNode(musicData, key);
musicLength = musicData.getDuration();
updateTime();
}
}//GEN-LAST:event_btnOpenActionPerformed
private void updateTime(){
int max = (int) (musicLength * 100);
int pos = (int) (curTime * 100);
sldBar.setMaximum(max);
sldBar.setValue(pos);
int minutesTotal = (int) (musicLength / 60);
int secondsTotal = (int) (musicLength % 60);
int minutesNow = (int) (curTime / 60);
int secondsNow = (int) (curTime % 60);
String txt = String.format("%01d:%02d-%01d:%02d", minutesNow, secondsNow,
minutesTotal, secondsTotal);
lblTime.setText(txt);
}
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed
if (musicSource == null){
btnOpenActionPerformed(evt);
return;
}
if (musicSource.getStatus() == Status.Playing){
musicSource.setPitch(1);
ar.pauseSource(musicSource);
}else{
musicSource.setPitch(1);
musicSource.play();
}
}//GEN-LAST:event_btnPlayActionPerformed
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
ar.cleanup();
}//GEN-LAST:event_formWindowClosing
private void sldVolumeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldVolumeStateChanged
listener.setVolume( (float) sldVolume.getValue() / 100f);
ar.setListener(listener);
}//GEN-LAST:event_sldVolumeStateChanged
private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopActionPerformed
if (musicSource != null){
musicSource.setPitch(1);
ar.stopSource(musicSource);
}
}//GEN-LAST:event_btnStopActionPerformed
private void btnFFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFFActionPerformed
if (musicSource.getStatus() == Status.Playing){
musicSource.setPitch(2);
}
}//GEN-LAST:event_btnFFActionPerformed
private void sldBarStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sldBarStateChanged
if (musicSource != null && !sldBar.getValueIsAdjusting()){
curTime = sldBar.getValue() / 100f;
if (curTime < 0)
curTime = 0;
musicSource.setTimeOffset(curTime);
// if (musicSource.getStatus() == Status.Playing){
// musicSource.stop();
// musicSource.play();
// }
updateTime();
}
}//GEN-LAST:event_sldBarStateChanged
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestMusicPlayer().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnFF;
private javax.swing.JButton btnOpen;
private javax.swing.JButton btnPlay;
private javax.swing.JButton btnRewind;
private javax.swing.JButton btnStop;
private javax.swing.JLabel lblTime;
private javax.swing.JPanel pnlBar;
private javax.swing.JPanel pnlButtons;
private javax.swing.JSlider sldBar;
private javax.swing.JSlider sldVolume;
// End of variables declaration//GEN-END:variables
}

@ -0,0 +1,60 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.UrlLocator;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;
public class TestMusicStreaming extends SimpleApplication {
public static void main(String[] args){
TestMusicStreaming test = new TestMusicStreaming();
test.start();
}
@Override
public void simpleInitApp(){
assetManager.registerLocator("http://www.vorbis.com/music/", UrlLocator.class);
AudioNode audioSource = new AudioNode(assetManager, "Lumme-Badloop.ogg",
AudioData.DataType.Stream);
audioSource.setPositional(false);
audioSource.setReverbEnabled(false);
audioSource.play();
}
@Override
public void simpleUpdate(float tpf){}
}

@ -0,0 +1,70 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioData.DataType;
import com.jme3.audio.AudioNode;
import com.jme3.audio.AudioSource;
import com.jme3.audio.LowPassFilter;
public class TestOgg extends SimpleApplication {
private AudioNode audioSource;
public static void main(String[] args){
TestOgg test = new TestOgg();
test.start();
}
@Override
public void simpleInitApp(){
System.out.println("Playing without filter");
audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer);
audioSource.play();
}
@Override
public void simpleUpdate(float tpf){
if (audioSource.getStatus() != AudioSource.Status.Playing){
audioRenderer.deleteAudioData(audioSource.getAudioData());
System.out.println("Playing with low pass filter");
audioSource = new AudioNode(assetManager, "Sound/Effects/Foot steps.ogg", DataType.Buffer);
audioSource.setDryFilter(new LowPassFilter(1f, .1f));
audioSource.setVolume(3);
audioSource.play();
}
}
}

@ -0,0 +1,81 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;
import com.jme3.audio.Environment;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
public class TestReverb extends SimpleApplication {
private AudioNode audioSource;
private float time = 0;
private float nextTime = 1;
public static void main(String[] args) {
TestReverb test = new TestReverb();
test.start();
}
@Override
public void simpleInitApp() {
audioSource = new AudioNode(assetManager, "Sound/Effects/Bang.wav",
AudioData.DataType.Buffer);
float[] eax = new float[]{15, 38.0f, 0.300f, -1000, -3300, 0,
1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f, 0.00f, 0.00f,
-229, 0.088f, 0.00f, 0.00f, 0.00f, 0.125f, 1.000f, 0.250f,
0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f};
audioRenderer.setEnvironment(new Environment(eax));
Environment env = Environment.Cavern;
audioRenderer.setEnvironment(env);
}
@Override
public void simpleUpdate(float tpf) {
time += tpf;
if (time > nextTime) {
Vector3f v = new Vector3f();
v.setX(FastMath.nextRandomFloat());
v.setY(FastMath.nextRandomFloat());
v.setZ(FastMath.nextRandomFloat());
v.multLocal(40, 2, 40);
v.subtractLocal(20, 1, 20);
audioSource.setLocalTranslation(v);
audioSource.playInstance();
time = 0;
nextTime = FastMath.nextRandomFloat() * 2 + 0.5f;
}
}
}

@ -0,0 +1,62 @@
/*
* 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 jme3test.audio;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;
public class TestWav extends SimpleApplication {
private float time = 0;
private AudioNode audioSource;
public static void main(String[] args) {
TestWav test = new TestWav();
test.start();
}
@Override
public void simpleUpdate(float tpf) {
time += tpf;
if (time > 1f) {
audioSource.playInstance();
time = 0;
}
}
@Override
public void simpleInitApp() {
audioSource = new AudioNode(assetManager, "Sound/Effects/Gun.wav",
AudioData.DataType.Buffer);
audioSource.setLooping(false);
}
}

@ -0,0 +1,150 @@
/*
* 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 jme3test.awt;
import com.jme3.app.LegacyApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.system.JmeSystem;
import java.applet.Applet;
import java.awt.Canvas;
import java.awt.Graphics;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.SwingUtilities;
/**
*
* @author Kirill
*/
public class AppHarness extends Applet {
private JmeCanvasContext context;
private Canvas canvas;
private LegacyApplication app;
private String appClass;
private URL appCfg = null;
private void createCanvas(){
AppSettings settings = new AppSettings(true);
// load app cfg
if (appCfg != null){
try {
InputStream in = appCfg.openStream();
settings.load(in);
in.close();
} catch (IOException ex){
ex.printStackTrace();
}
}
settings.setWidth(getWidth());
settings.setHeight(getHeight());
settings.setAudioRenderer(null);
JmeSystem.setLowPermissions(true);
try{
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setSettings(settings);
app.createCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(getWidth(), getHeight());
add(canvas);
app.startCanvas();
}
@Override
public final void update(Graphics g) {
canvas.setSize(getWidth(), getHeight());
}
@Override
public void init(){
appClass = getParameter("AppClass");
if (appClass == null)
throw new RuntimeException("The required parameter AppClass isn't specified!");
try {
appCfg = new URL(getParameter("AppSettingsURL"));
} catch (MalformedURLException ex) {
ex.printStackTrace();
appCfg = null;
}
createCanvas();
System.out.println("applet:init");
}
@Override
public void start(){
context.setAutoFlushFrames(true);
System.out.println("applet:start");
}
@Override
public void stop(){
context.setAutoFlushFrames(false);
System.out.println("applet:stop");
}
@Override
public void destroy(){
System.out.println("applet:destroyStart");
SwingUtilities.invokeLater(new Runnable(){
public void run(){
removeAll();
System.out.println("applet:destroyRemoved");
}
});
app.stop(true);
System.out.println("applet:destroyDone");
}
}

@ -0,0 +1,145 @@
/*
* 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 jme3test.awt;
import com.jme3.app.LegacyApplication;
import com.jme3.app.SimpleApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.system.JmeSystem;
import java.applet.Applet;
import java.awt.Canvas;
import java.awt.Graphics;
import java.util.concurrent.Callable;
import javax.swing.SwingUtilities;
public class TestApplet extends Applet {
private static JmeCanvasContext context;
private static LegacyApplication app;
private static Canvas canvas;
private static TestApplet applet;
public TestApplet(){
}
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
// settings.setRenderer(AppSettings.JOGL);
JmeSystem.setLowPermissions(true);
try{
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setSettings(settings);
app.createCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
}
public static void startApp(){
applet.add(canvas);
app.startCanvas();
app.enqueue(new Callable<Void>(){
public Void call(){
if (app instanceof SimpleApplication){
SimpleApplication simpleApp = (SimpleApplication) app;
simpleApp.getFlyByCamera().setDragToRotate(true);
simpleApp.getInputManager().setCursorVisible(true);
}
return null;
}
});
}
public void freezeApp(){
remove(canvas);
}
public void unfreezeApp(){
add(canvas);
}
@Override
public final void update(Graphics g) {
// canvas.setSize(getWidth(), getHeight());
}
@Override
public void init(){
applet = this;
createCanvas("jme3test.model.shape.TestBox");
startApp();
app.setPauseOnLostFocus(false);
System.out.println("applet:init");
}
@Override
public void start(){
// context.setAutoFlushFrames(true);
System.out.println("applet:start");
}
@Override
public void stop(){
// context.setAutoFlushFrames(false);
System.out.println("applet:stop");
}
@Override
public void destroy(){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
removeAll();
System.out.println("applet:destroyStart");
}
});
app.stop(true);
System.out.println("applet:destroyEnd");
}
}

@ -0,0 +1,112 @@
package jme3test.awt;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.awt.AwtPanel;
import com.jme3.system.awt.AwtPanelsContext;
import com.jme3.system.awt.PaintMode;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TestAwtPanels extends SimpleApplication {
final private static CountDownLatch panelsAreReady = new CountDownLatch(1);
private static TestAwtPanels app;
private static AwtPanel panel, panel2;
private static int panelsClosed = 0;
private static void createWindowForPanel(AwtPanel panel, int location){
JFrame frame = new JFrame("Render Display " + location);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
if (++panelsClosed == 2){
app.stop();
}
}
});
frame.pack();
frame.setLocation(location, Toolkit.getDefaultToolkit().getScreenSize().height - 400);
frame.setVisible(true);
}
public static void main(String[] args){
Logger.getLogger("com.jme3").setLevel(Level.WARNING);
app = new TestAwtPanels();
app.setShowSettings(false);
AppSettings settings = new AppSettings(true);
settings.setCustomRenderer(AwtPanelsContext.class);
settings.setFrameRate(60);
app.setSettings(settings);
app.start();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
/*
* Sleep 2 seconds to ensure there's no race condition.
* The sleep is not required for correctness.
*/
try {
Thread.sleep(2000);
} catch (InterruptedException exception) {
return;
}
final AwtPanelsContext ctx = (AwtPanelsContext) app.getContext();
panel = ctx.createPanel(PaintMode.Accelerated);
panel.setPreferredSize(new Dimension(400, 300));
ctx.setInputSource(panel);
panel2 = ctx.createPanel(PaintMode.Accelerated);
panel2.setPreferredSize(new Dimension(400, 300));
createWindowForPanel(panel, 300);
createWindowForPanel(panel2, 700);
/*
* Both panels are ready.
*/
panelsAreReady.countDown();
}
});
}
@Override
public void simpleInitApp() {
flyCam.setDragToRotate(true);
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
/*
* Wait until both AWT panels are ready.
*/
try {
panelsAreReady.await();
} catch (InterruptedException exception) {
throw new RuntimeException("Interrupted while waiting for panels", exception);
}
panel.attachTo(true, viewPort);
guiViewPort.setClearFlags(true, true, true);
panel2.attachTo(false, guiViewPort);
}
}

@ -0,0 +1,270 @@
/*
* 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 jme3test.awt;
import com.jme3.app.LegacyApplication;
import com.jme3.app.SimpleApplication;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import com.jme3.util.JmeFormatter;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.Callable;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import javax.swing.*;
public class TestCanvas {
private static JmeCanvasContext context;
private static Canvas canvas;
private static LegacyApplication app;
private static JFrame frame;
private static Container canvasPanel1, canvasPanel2;
private static Container currentPanel;
private static JTabbedPane tabbedPane;
private static final String appClass = "jme3test.post.TestRenderToTexture";
private static void createTabs(){
tabbedPane = new JTabbedPane();
canvasPanel1 = new JPanel();
canvasPanel1.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 1", canvasPanel1);
canvasPanel2 = new JPanel();
canvasPanel2.setLayout(new BorderLayout());
tabbedPane.addTab("jME3 Canvas 2", canvasPanel2);
frame.getContentPane().add(tabbedPane);
currentPanel = canvasPanel1;
}
private static void createMenu(){
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menuTortureMethods = new JMenu("Canvas Torture Methods");
menuBar.add(menuTortureMethods);
final JMenuItem itemRemoveCanvas = new JMenuItem("Remove Canvas");
menuTortureMethods.add(itemRemoveCanvas);
itemRemoveCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemRemoveCanvas.getText().equals("Remove Canvas")){
currentPanel.remove(canvas);
itemRemoveCanvas.setText("Add Canvas");
}else if (itemRemoveCanvas.getText().equals("Add Canvas")){
currentPanel.add(canvas, BorderLayout.CENTER);
itemRemoveCanvas.setText("Remove Canvas");
}
}
});
final JMenuItem itemHideCanvas = new JMenuItem("Hide Canvas");
menuTortureMethods.add(itemHideCanvas);
itemHideCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (itemHideCanvas.getText().equals("Hide Canvas")){
canvas.setVisible(false);
itemHideCanvas.setText("Show Canvas");
}else if (itemHideCanvas.getText().equals("Show Canvas")){
canvas.setVisible(true);
itemHideCanvas.setText("Hide Canvas");
}
}
});
final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2");
menuTortureMethods.add(itemSwitchTab);
itemSwitchTab.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (itemSwitchTab.getText().equals("Switch to tab #2")){
canvasPanel1.remove(canvas);
canvasPanel2.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel2;
itemSwitchTab.setText("Switch to tab #1");
}else if (itemSwitchTab.getText().equals("Switch to tab #1")){
canvasPanel2.remove(canvas);
canvasPanel1.add(canvas, BorderLayout.CENTER);
currentPanel = canvasPanel1;
itemSwitchTab.setText("Switch to tab #2");
}
}
});
JMenuItem itemSwitchLaf = new JMenuItem("Switch Look and Feel");
menuTortureMethods.add(itemSwitchLaf);
itemSwitchLaf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t){
t.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
}
});
JMenuItem itemSmallSize = new JMenuItem("Set size to (0, 0)");
menuTortureMethods.add(itemSmallSize);
itemSmallSize.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Dimension preferred = frame.getPreferredSize();
frame.setPreferredSize(new Dimension(0, 0));
frame.pack();
frame.setPreferredSize(preferred);
}
});
JMenuItem itemKillCanvas = new JMenuItem("Stop/Start Canvas");
menuTortureMethods.add(itemKillCanvas);
itemKillCanvas.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
currentPanel.remove(canvas);
app.stop(true);
createCanvas(appClass);
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
}
});
JMenuItem itemExit = new JMenuItem("Exit");
menuTortureMethods.add(itemExit);
itemExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
frame.dispose();
app.stop();
}
});
}
private static void createFrame(){
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosed(WindowEvent e) {
app.stop();
}
});
createTabs();
createMenu();
}
public static void createCanvas(String appClass){
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
try{
Class<? extends LegacyApplication> clazz = (Class<? extends LegacyApplication>) Class.forName(appClass);
app = clazz.newInstance();
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}catch (InstantiationException ex){
ex.printStackTrace();
}catch (IllegalAccessException ex){
ex.printStackTrace();
}
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas();
context = (JmeCanvasContext) app.getContext();
canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
}
public static void startApp(){
app.startCanvas();
app.enqueue(new Callable<Void>(){
public Void call(){
if (app instanceof SimpleApplication){
SimpleApplication simpleApp = (SimpleApplication) app;
simpleApp.getFlyByCamera().setDragToRotate(true);
}
return null;
}
});
}
public static void main(String[] args){
JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setFormatter(formatter);
Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
Logger.getLogger("").addHandler(consoleHandler);
createCanvas(appClass);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
createFrame();
currentPanel.add(canvas, BorderLayout.CENTER);
frame.pack();
startApp();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

@ -0,0 +1,69 @@
package jme3test.awt;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
import java.awt.Canvas;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class TestSafeCanvas extends SimpleApplication {
public static void main(String[] args) throws InterruptedException{
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
final TestSafeCanvas app = new TestSafeCanvas();
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas(true);
JmeCanvasContext context = (JmeCanvasContext) app.getContext();
Canvas canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
Thread.sleep(3000);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
app.stop();
}
});
frame.getContentPane().add(canvas);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Thread.sleep(3000);
frame.getContentPane().remove(canvas);
Thread.sleep(3000);
frame.getContentPane().add(canvas);
}
@Override
public void simpleInitApp() {
flyCam.setDragToRotate(true);
Box b = new Box(1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
}

@ -0,0 +1,175 @@
/*
* 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 jme3test.batching;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.light.DirectionalLight;
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.BatchNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.debug.WireFrustum;
import com.jme3.scene.shape.Box;
import com.jme3.system.NanoTimer;
import com.jme3.util.TangentBinormalGenerator;
/**
*
* @author Nehon
*/
public class TestBatchNode extends SimpleApplication {
public static void main(String[] args) {
TestBatchNode app = new TestBatchNode();
app.start();
}
BatchNode batch;
WireFrustum frustum;
Geometry frustumMdl;
private Vector3f[] points;
{
points = new Vector3f[8];
for (int i = 0; i < points.length; i++) {
points[i] = new Vector3f();
}
}
@Override
public void simpleInitApp() {
timer = new NanoTimer();
batch = new BatchNode("theBatchNode");
/**
* A cube with a color "bleeding" through transparent texture. Uses
* Texture from jme3-test-data library!
*/
Box boxshape4 = new Box(1f, 1f, 1f);
cube = new Geometry("cube1", boxshape4);
Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
cube.setMaterial(mat);
// Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
// mat.setColor("Diffuse", ColorRGBA.Blue);
// mat.setBoolean("UseMaterialColors", true);
/**
* A cube with a color "bleeding" through transparent texture. Uses
* Texture from jme3-test-data library!
*/
Box box = new Box(1f, 1f, 1f);
cube2 = new Geometry("cube2", box);
cube2.setMaterial(mat);
TangentBinormalGenerator.generate(cube);
TangentBinormalGenerator.generate(cube2);
n = new Node("aNode");
// n.attachChild(cube2);
batch.attachChild(cube);
// batch.attachChild(cube2);
// batch.setMaterial(mat);
batch.batch();
rootNode.attachChild(batch);
cube.setLocalTranslation(3, 0, 0);
cube2.setLocalTranslation(0, 20, 0);
updateBoindPoints(points);
frustum = new WireFrustum(points);
frustumMdl = new Geometry("f", frustum);
frustumMdl.setCullHint(Spatial.CullHint.Never);
frustumMdl.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"));
frustumMdl.getMaterial().getAdditionalRenderState().setWireframe(true);
frustumMdl.getMaterial().setColor("Color", ColorRGBA.Red);
rootNode.attachChild(frustumMdl);
dl = new DirectionalLight();
dl.setColor(ColorRGBA.White.mult(2));
dl.setDirection(new Vector3f(1, -1, -1));
rootNode.addLight(dl);
flyCam.setMoveSpeed(10);
}
Node n;
Geometry cube;
Geometry cube2;
float time = 0;
DirectionalLight dl;
boolean done = false;
@Override
public void simpleUpdate(float tpf) {
if (!done) {
done = true;
batch.attachChild(cube2);
batch.batch();
}
updateBoindPoints(points);
frustum.update(points);
time += tpf;
dl.setDirection(cam.getDirection());
cube2.setLocalTranslation(FastMath.sin(-time) * 3, FastMath.cos(time) * 3, 0);
cube2.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z));
cube2.setLocalScale(Math.max(FastMath.sin(time), 0.5f));
// batch.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Z));
}
//
public void updateBoindPoints(Vector3f[] points) {
BoundingBox bb = (BoundingBox) batch.getWorldBound();
float xe = bb.getXExtent();
float ye = bb.getYExtent();
float ze = bb.getZExtent();
float x = bb.getCenter().x;
float y = bb.getCenter().y;
float z = bb.getCenter().z;
points[0].set(new Vector3f(x - xe, y - ye, z - ze));
points[1].set(new Vector3f(x - xe, y + ye, z - ze));
points[2].set(new Vector3f(x + xe, y + ye, z - ze));
points[3].set(new Vector3f(x + xe, y - ye, z - ze));
points[4].set(new Vector3f(x + xe, y - ye, z + ze));
points[5].set(new Vector3f(x - xe, y - ye, z + ze));
points[6].set(new Vector3f(x - xe, y + ye, z + ze));
points[7].set(new Vector3f(x + xe, y + ye, z + ze));
}
}

@ -0,0 +1,372 @@
/*
* 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 jme3test.batching;
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
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.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.scene.*;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.NanoTimer;
import java.util.ArrayList;
import java.util.Random;
public class TestBatchNodeCluster extends SimpleApplication {
public static void main(String[] args) {
TestBatchNodeCluster app = new TestBatchNodeCluster();
settingst = new AppSettings(true);
//settingst.setFrameRate(75);
settingst.setResolution(640, 480);
settingst.setVSync(false);
settingst.setFullscreen(false);
app.setSettings(settingst);
app.setShowSettings(false);
app.start();
}
private ActionListener al = new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("Start Game")) {
// randomGenerator();
}
}
};
protected Random rand = new Random();
protected int maxCubes = 2000;
protected int startAt = 0;
protected static int xPositions = 0, yPositions = 0, zPositions = 0;
protected int returner = 0;
protected ArrayList<Integer> xPosition = new ArrayList<Integer>();
protected ArrayList<Integer> yPosition = new ArrayList<Integer>();
protected ArrayList<Integer> zPosition = new ArrayList<Integer>();
protected int xLimitf = 60, xLimits = -60, yLimitf = 60, yLimits = -20, zLimitf = 60, zLimits = -60;
protected int circ = 8;//increases by 8 every time.
protected int dynamic = 4;
protected static AppSettings settingst;
protected boolean isTrue = true;
private int lineLength = 50;
protected BatchNode batchNode;
Material mat1;
Material mat2;
Material mat3;
Material mat4;
Node terrain;
//protected
// protected Geometry player;
@Override
public void simpleInitApp() {
timer = new NanoTimer();
batchNode = new SimpleBatchNode("BatchNode");
xPosition.add(0);
yPosition.add(0);
zPosition.add(0);
mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.White);
mat1.setColor("GlowColor", ColorRGBA.Blue.mult(10));
mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.White);
mat2.setColor("GlowColor", ColorRGBA.Red.mult(10));
mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat3.setColor("Color", ColorRGBA.White);
mat3.setColor("GlowColor", ColorRGBA.Yellow.mult(10));
mat4 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat4.setColor("Color", ColorRGBA.White);
mat4.setColor("GlowColor", ColorRGBA.Orange.mult(10));
randomGenerator();
//rootNode.attachChild(SkyFactory.createSky(
// assetManager, "Textures/SKY02.zip", false));
inputManager.addMapping("Start Game", new KeyTrigger(KeyInput.KEY_J));
inputManager.addListener(al, new String[]{"Start Game"});
cam.setLocation(new Vector3f(-34.403286f, 126.65158f, 434.791f));
cam.setRotation(new Quaternion(0.022630932f, 0.9749435f, -0.18736298f, 0.11776358f));
batchNode.batch();
terrain = new Node("terrain");
terrain.setLocalTranslation(50, 0, 50);
terrain.attachChild(batchNode);
flyCam.setMoveSpeed(100);
rootNode.attachChild(terrain);
Vector3f pos = new Vector3f(-40, 0, -40);
batchNode.setLocalTranslation(pos);
Arrow a = new Arrow(new Vector3f(0, 50, 0));
Geometry g = new Geometry("a", a);
g.setLocalTranslation(terrain.getLocalTranslation());
Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", ColorRGBA.Blue);
g.setMaterial(m);
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
fpp.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects));
// SSAOFilter ssao = new SSAOFilter(8.630104f,22.970434f,2.9299977f,0.2999997f);
// fpp.addFilter(ssao);
viewPort.addProcessor(fpp);
// viewPort.setBackgroundColor(ColorRGBA.DarkGray);
}
public void randomGenerator() {
for (int i = startAt; i < maxCubes - 1; i++) {
randomize();
Geometry box = new Geometry("Box" + i, new Box(1, 1, 1));
box.setLocalTranslation(new Vector3f(xPosition.get(xPosition.size() - 1),
yPosition.get(yPosition.size() - 1),
zPosition.get(zPosition.size() - 1)));
batchNode.attachChild(box);
if (i < 500) {
box.setMaterial(mat1);
} else if (i < 1000) {
box.setMaterial(mat2);
} else if (i < 1500) {
box.setMaterial(mat3);
} else {
box.setMaterial(mat4);
}
}
}
// public BatchNode randomBatch() {
//
// int randomn = rand.nextInt(4);
// if (randomn == 0) {
// return blue;
// } else if (randomn == 1) {
// return brown;
// } else if (randomn == 2) {
// return pink;
// } else if (randomn == 3) {
// return orange;
// }
// return null;
// }
public ColorRGBA randomColor() {
ColorRGBA color = ColorRGBA.Black;
int randomn = rand.nextInt(4);
if (randomn == 0) {
color = ColorRGBA.Orange;
} else if (randomn == 1) {
color = ColorRGBA.Blue;
} else if (randomn == 2) {
color = ColorRGBA.Brown;
} else if (randomn == 3) {
color = ColorRGBA.Magenta;
}
return color;
}
public void randomize() {
int xpos = xPosition.get(xPosition.size() - 1);
int ypos = yPosition.get(yPosition.size() - 1);
int zpos = zPosition.get(zPosition.size() - 1);
int x = 0;
int y = 0;
int z = 0;
boolean unTrue = true;
while (unTrue) {
unTrue = false;
boolean xChanged = false;
x = 0;
y = 0;
z = 0;
if (xpos >= lineLength * 2) {
x = 2;
xChanged = true;
} else {
x = xPosition.get(xPosition.size() - 1) + 2;
}
if (xChanged) {
//y = yPosition.get(yPosition.size() - lineLength) + 2;
} else {
y = rand.nextInt(3);
if (yPosition.size() > lineLength) {
if (yPosition.size() > 51) {
if (y == 0 && ypos < yLimitf && getym(lineLength) > ypos - 2) {
y = ypos + 2;
} else if (y == 1 && ypos > yLimits && getym(lineLength) < ypos + 2) {
y = ypos - 2;
} else if (y == 2 && getym(lineLength) > ypos - 2 && getym(lineLength) < ypos + 2) {
y = ypos;
} else {
if (ypos >= yLimitf) {
y = ypos - 2;
} else if (ypos <= yLimits) {
y = ypos + 2;
} else if (y == 0 && getym(lineLength) >= ypos - 4) {
y = ypos - 2;
} else if (y == 0 && getym(lineLength) >= ypos - 2) {
y = ypos;
} else if (y == 1 && getym(lineLength) >= ypos + 4) {
y = ypos + 2;
} else if (y == 1 && getym(lineLength) >= ypos + 2) {
y = ypos;
} else if (y == 2 && getym(lineLength) <= ypos - 2) {
y = ypos - 2;
} else if (y == 2 && getym(lineLength) >= ypos + 2) {
y = ypos + 2;
} else {
System.out.println("wtf");
}
}
} else if (yPosition.size() == lineLength) {
if (y == 0 && ypos < yLimitf) {
y = getym(lineLength) + 2;
} else if (y == 1 && ypos > yLimits) {
y = getym(lineLength) - 2;
}
}
} else {
if (y == 0 && ypos < yLimitf) {
y = ypos + 2;
} else if (y == 1 && ypos > yLimits) {
y = ypos - 2;
} else if (y == 2) {
y = ypos;
} else if (y == 0 && ypos >= yLimitf) {
y = ypos - 2;
} else if (y == 1 && ypos <= yLimits) {
y = ypos + 2;
}
}
}
if (xChanged) {
z = zpos + 2;
} else {
z = zpos;
}
// for (int i = 0; i < xPosition.size(); i++)
// {
// if (x - xPosition.get(i) <= 1 && x - xPosition.get(i) >= -1 &&
// y - yPosition.get(i) <= 1 && y - yPosition.get(i) >= -1
// &&z - zPosition.get(i) <= 1 && z - zPosition.get(i) >=
// -1)
// {
// unTrue = true;
// }
// }
}
xPosition.add(x);
yPosition.add(y);
zPosition.add(z);
}
public int getxm(int i) {
return xPosition.get(xPosition.size() - i);
}
public int getym(int i) {
return yPosition.get(yPosition.size() - i);
}
public int getzm(int i) {
return zPosition.get(zPosition.size() - i);
}
public int getx(int i) {
return xPosition.get(i);
}
public int gety(int i) {
return yPosition.get(i);
}
public int getz(int i) {
return zPosition.get(i);
}
long nbFrames = 0;
long cullTime = 0;
float time = 0;
Vector3f lookAtPos = new Vector3f(0, 0, 0);
float xpos = 0;
Spatial box;
@Override
public void simpleUpdate(float tpf) {
time += tpf;
int random = rand.nextInt(2000);
float mult1 = 1.0f;
float mult2 = 1.0f;
if (random < 500) {
mult1 = 1.0f;
mult2 = 1.0f;
} else if (random < 1000) {
mult1 = -1.0f;
mult2 = 1.0f;
} else if (random < 1500) {
mult1 = 1.0f;
mult2 = -1.0f;
} else if (random <= 2000) {
mult1 = -1.0f;
mult2 = -1.0f;
}
box = batchNode.getChild("Box" + random);
if (box != null) {
Vector3f v = box.getLocalTranslation();
box.setLocalTranslation(v.x + FastMath.sin(time * mult1) * 20, v.y + (FastMath.sin(time * mult1) * FastMath.cos(time * mult1) * 20), v.z + FastMath.cos(time * mult2) * 20);
}
terrain.setLocalRotation(new Quaternion().fromAngleAxis(time, Vector3f.UNIT_Y));
}
}

@ -0,0 +1,252 @@
/*
* 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 jme3test.batching;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.BatchNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.shadow.CompareMode;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.system.AppSettings;
import com.jme3.system.NanoTimer;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import jme3test.bullet.BombControl;
/**
*
* @author double1984 (tower mod by atom)
*/
public class TestBatchNodeTower extends SimpleApplication {
int bricksPerLayer = 8;
int brickLayers = 30;
static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f;
float radius = 3f;
float angle = 0;
Material mat;
Material mat2;
Material mat3;
DirectionalLightShadowFilter shadowRenderer;
private Sphere bullet;
private Box brick;
private SphereCollisionShape bulletCollisionShape;
private BulletAppState bulletAppState;
BatchNode batchNode = new BatchNode("batch Node");
public static void main(String args[]) {
TestBatchNodeTower f = new TestBatchNodeTower();
AppSettings s = new AppSettings(true);
f.setSettings(s);
f.start();
}
@Override
public void simpleInitApp() {
timer = new NanoTimer();
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
// bulletAppState.setEnabled(false);
stateManager.attach(bulletAppState);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);
brick = new Box(brickWidth, brickHeight, brickDepth);
brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
initMaterial();
initTower();
initFloor();
initCrossHairs();
this.cam.setLocation(new Vector3f(0, 25f, 8f));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(80);
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
rootNode.setShadowMode(ShadowMode.Off);
batchNode.batch();
batchNode.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(batchNode);
shadowRenderer = new DirectionalLightShadowFilter(assetManager, 1024, 2);
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
shadowRenderer.setLight(dl);
shadowRenderer.setLambda(0.55f);
shadowRenderer.setShadowIntensity(0.6f);
shadowRenderer.setShadowCompareMode(CompareMode.Hardware);
shadowRenderer.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
fpp.addFilter(shadowRenderer);
viewPort.addProcessor(fpp);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("shoot") && !keyPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(cam.getLocation());
RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1);
bulletNode.setLinearVelocity(cam.getDirection().mult(25));
bulletg.addControl(bulletNode);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletNode);
}
}
};
public void initTower() {
double tempX = 0;
double tempY = 0;
double tempZ = 0;
angle = 0f;
for (int i = 0; i < brickLayers; i++){
// Increment rows
if (i != 0) {
tempY += brickHeight * 2;
} else {
tempY = brickHeight;
}
// Alternate brick seams
angle = 360.0f / bricksPerLayer * i/2f;
for (int j = 0; j < bricksPerLayer; j++){
tempZ = Math.cos(Math.toRadians(angle))*radius;
tempX = Math.sin(Math.toRadians(angle))*radius;
System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ));
Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ));
// Add crenelation
if (i==brickLayers-1){
if (j%2 == 0){
addBrick(vt);
}
}
// Create main tower
else {
addBrick(vt);
}
angle += 360.0/bricksPerLayer;
}
}
}
public void initFloor() {
Box floorBox = new Box(10f, 0.1f, 5f);
floorBox.scaleTextureCoordinates(new Vector2f(3, 6));
Geometry floor = new Geometry("floor", floorBox);
floor.setMaterial(mat3);
floor.setShadowMode(ShadowMode.Receive);
floor.setLocalTranslation(0, 0, 0);
floor.addControl(new RigidBodyControl(0));
this.rootNode.attachChild(floor);
this.getPhysicsSpace().add(floor);
}
public void initMaterial() {
mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
mat.setTexture("ColorMap", tex);
mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
mat2.setTexture("ColorMap", tex2);
mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
key3.setGenerateMips(true);
Texture tex3 = assetManager.loadTexture(key3);
tex3.setWrap(WrapMode.Repeat);
mat3.setTexture("ColorMap", tex3);
}
int nbBrick =0;
public void addBrick(Vector3f ori) {
Geometry reBoxg = new Geometry("brick", brick);
reBoxg.setMaterial(mat);
reBoxg.setLocalTranslation(ori);
reBoxg.rotate(0f, (float)Math.toRadians(angle) , 0f );
reBoxg.addControl(new RigidBodyControl(1.5f));
reBoxg.setShadowMode(ShadowMode.CastAndReceive);
reBoxg.getControl(RigidBodyControl.class).setFriction(1.6f);
this.batchNode.attachChild(reBoxg);
this.getPhysicsSpace().add(reBoxg);
nbBrick++;
}
protected void initCrossHairs() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // crosshairs
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
}

@ -0,0 +1,83 @@
/*
* 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 jme3test.blender;
import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
public class TestBlenderLoader extends SimpleApplication {
public static void main(String[] args){
TestBlenderLoader app = new TestBlenderLoader();
app.start();
}
@Override
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
//load model with packed images
Spatial ogre = assetManager.loadModel("Blender/2.4x/Sinbad.blend");
rootNode.attachChild(ogre);
//load model with referenced images
Spatial track = assetManager.loadModel("Blender/2.4x/MountainValley_Track.blend");
rootNode.attachChild(track);
// sunset light
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f,-0.7f,1).normalizeLocal());
dl.setColor(new ColorRGBA(0.44f, 0.30f, 0.20f, 1.0f));
rootNode.addLight(dl);
// skylight
dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.6f,-1,-0.6f).normalizeLocal());
dl.setColor(new ColorRGBA(0.10f, 0.22f, 0.44f, 1.0f));
rootNode.addLight(dl);
// white ambient light
dl = new DirectionalLight();
dl.setDirection(new Vector3f(1, -0.5f,-0.1f).normalizeLocal());
dl.setColor(new ColorRGBA(0.80f, 0.70f, 0.80f, 1.0f));
rootNode.addLight(dl);
}
@Override
public void simpleUpdate(float tpf){
}
}

@ -0,0 +1,65 @@
/*
* 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 jme3test.bounding;
import com.jme3.bounding.BoundingBox;
import com.jme3.collision.CollisionResults;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
/**
* Tests picking/collision between bounds and shapes.
*/
public class TestRayCollision {
public static void main(String[] args){
Ray r = new Ray(Vector3f.ZERO, Vector3f.UNIT_X);
BoundingBox bbox = new BoundingBox(new Vector3f(5, 0, 0), 1, 1, 1);
CollisionResults res = new CollisionResults();
bbox.collideWith(r, res);
System.out.println("Bounding:" +bbox);
System.out.println("Ray: "+r);
System.out.println("Num collisions: "+res.size());
for (int i = 0; i < res.size(); i++){
System.out.println("--- Collision #"+i+" ---");
float dist = res.getCollision(i).getDistance();
Vector3f pt = res.getCollision(i).getContactPoint();
System.out.println("distance: "+dist);
System.out.println("point: "+pt);
}
}
}

@ -0,0 +1,217 @@
/*
* 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 jme3test.bullet;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.objects.PhysicsGhostObject;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import java.io.IOException;
import java.util.Iterator;
/**
*
* @author normenhansen
*/
public class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener {
private float explosionRadius = 10;
private PhysicsGhostObject ghostObject;
private Vector3f vector = new Vector3f();
private Vector3f vector2 = new Vector3f();
private float forceFactor = 1;
private ParticleEmitter effect;
private float fxTime = 0.5f;
private float maxTime = 4f;
private float curTime = -1.0f;
private float timer;
public BombControl(CollisionShape shape, float mass) {
super(shape, mass);
createGhostObject();
}
public BombControl(AssetManager manager, CollisionShape shape, float mass) {
super(shape, mass);
createGhostObject();
prepareEffect(manager);
}
public void setPhysicsSpace(PhysicsSpace space) {
super.setPhysicsSpace(space);
if (space != null) {
space.addCollisionListener(this);
}
}
private void prepareEffect(AssetManager assetManager) {
int COUNT_FACTOR = 1;
float COUNT_FACTOR_F = 1f;
effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
effect.setSelectRandomImage(true);
effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F)));
effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
effect.setStartSize(1.3f);
effect.setEndSize(2f);
effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
effect.setParticlesPerSec(0);
effect.setGravity(0, -5f, 0);
effect.setLowLife(.4f);
effect.setHighLife(.5f);
effect.getParticleInfluencer()
.setInitialVelocity(new Vector3f(0, 7, 0));
effect.getParticleInfluencer().setVelocityVariation(1f);
effect.setImagesX(2);
effect.setImagesY(2);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
effect.setMaterial(mat);
}
protected void createGhostObject() {
ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius));
}
public void collision(PhysicsCollisionEvent event) {
if (space == null) {
return;
}
if (event.getObjectA() == this || event.getObjectB() == this) {
space.add(ghostObject);
ghostObject.setPhysicsLocation(getPhysicsLocation(vector));
space.addTickListener(this);
if (effect != null && spatial.getParent() != null) {
curTime = 0;
effect.setLocalTranslation(spatial.getLocalTranslation());
spatial.getParent().attachChild(effect);
effect.emitAllParticles();
}
space.remove(this);
spatial.removeFromParent();
}
}
public void prePhysicsTick(PhysicsSpace space, float f) {
space.removeCollisionListener(this);
}
public void physicsTick(PhysicsSpace space, float f) {
//get all overlapping objects and apply impulse to them
for (Iterator<PhysicsCollisionObject> it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) {
PhysicsCollisionObject physicsCollisionObject = it.next();
if (physicsCollisionObject instanceof PhysicsRigidBody) {
PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject;
rBody.getPhysicsLocation(vector2);
vector2.subtractLocal(vector);
float force = explosionRadius - vector2.length();
force *= forceFactor;
force = force > 0 ? force : 0;
vector2.normalizeLocal();
vector2.multLocal(force);
((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO);
}
}
space.removeTickListener(this);
space.remove(ghostObject);
}
@Override
public void update(float tpf) {
super.update(tpf);
if(enabled){
timer+=tpf;
if(timer>maxTime){
if(spatial.getParent()!=null){
space.removeCollisionListener(this);
space.remove(this);
spatial.removeFromParent();
}
}
}
if (enabled && curTime >= 0) {
curTime += tpf;
if (curTime > fxTime) {
curTime = -1;
effect.removeFromParent();
}
}
}
/**
* @return the explosionRadius
*/
public float getExplosionRadius() {
return explosionRadius;
}
/**
* @param explosionRadius the explosionRadius to set
*/
public void setExplosionRadius(float explosionRadius) {
this.explosionRadius = explosionRadius;
createGhostObject();
}
public float getForceFactor() {
return forceFactor;
}
public void setForceFactor(float forceFactor) {
this.forceFactor = forceFactor;
}
@Override
public void read(JmeImporter im) throws IOException {
throw new UnsupportedOperationException("Reading not supported.");
}
@Override
public void write(JmeExporter ex) throws IOException {
throw new UnsupportedOperationException("Saving not supported.");
}
}

@ -0,0 +1,245 @@
/*
* 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 jme3test.bullet;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.PhysicsControl;
import com.jme3.bullet.objects.PhysicsVehicle;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
* PhysicsHoverControl uses a RayCast Vehicle with "slippery wheels" to simulate a hovering tank
* @author normenhansen
*/
public class PhysicsHoverControl extends PhysicsVehicle implements PhysicsControl, PhysicsTickListener, JmeCloneable {
protected Spatial spatial;
protected boolean enabled = true;
protected PhysicsSpace space = null;
protected float steeringValue = 0;
protected float accelerationValue = 0;
protected int xw = 3;
protected int zw = 5;
protected int yw = 2;
protected Vector3f HOVER_HEIGHT_LF_START = new Vector3f(xw, 1, zw);
protected Vector3f HOVER_HEIGHT_RF_START = new Vector3f(-xw, 1, zw);
protected Vector3f HOVER_HEIGHT_LR_START = new Vector3f(xw, 1, -zw);
protected Vector3f HOVER_HEIGHT_RR_START = new Vector3f(-xw, 1, -zw);
protected Vector3f HOVER_HEIGHT_LF = new Vector3f(xw, -yw, zw);
protected Vector3f HOVER_HEIGHT_RF = new Vector3f(-xw, -yw, zw);
protected Vector3f HOVER_HEIGHT_LR = new Vector3f(xw, -yw, -zw);
protected Vector3f HOVER_HEIGHT_RR = new Vector3f(-xw, -yw, -zw);
protected Vector3f tempVect1 = new Vector3f(0, 0, 0);
protected Vector3f tempVect2 = new Vector3f(0, 0, 0);
protected Vector3f tempVect3 = new Vector3f(0, 0, 0);
// protected float rotationCounterForce = 10000f;
// protected float speedCounterMult = 2000f;
// protected float multiplier = 1000f;
public PhysicsHoverControl() {
}
/**
* Creates a new PhysicsNode with the supplied collision shape
* @param shape
*/
public PhysicsHoverControl(CollisionShape shape) {
super(shape);
createWheels();
}
public PhysicsHoverControl(CollisionShape shape, float mass) {
super(shape, mass);
createWheels();
}
@Override
public Control cloneForSpatial(Spatial spatial) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object jmeClone() {
throw new UnsupportedOperationException("Not yet implemented.");
}
@Override
public void cloneFields( Cloner cloner, Object original ) {
throw new UnsupportedOperationException("Not yet implemented.");
}
public void setSpatial(Spatial spatial) {
this.spatial = spatial;
setUserObject(spatial);
if (spatial == null) {
return;
}
setPhysicsLocation(spatial.getWorldTranslation());
setPhysicsRotation(spatial.getWorldRotation().toRotationMatrix());
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return enabled;
}
private void createWheels() {
addWheel(HOVER_HEIGHT_LF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false);
addWheel(HOVER_HEIGHT_RF_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false);
addWheel(HOVER_HEIGHT_LR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false);
addWheel(HOVER_HEIGHT_RR_START, new Vector3f(0, -1, 0), new Vector3f(-1, 0, 0), yw, yw, false);
for (int i = 0; i < 4; i++) {
getWheel(i).setFrictionSlip(0.001f);
}
}
public void prePhysicsTick(PhysicsSpace space, float f) {
Vector3f angVel = getAngularVelocity();
float rotationVelocity = angVel.getY();
Vector3f dir = getForwardVector(tempVect2).multLocal(1, 0, 1).normalizeLocal();
getLinearVelocity(tempVect3);
Vector3f linearVelocity = tempVect3.multLocal(1, 0, 1);
if (steeringValue != 0) {
if (rotationVelocity < 1 && rotationVelocity > -1) {
applyTorque(tempVect1.set(0, steeringValue, 0));
}
} else {
// counter the steering value!
if (rotationVelocity > 0.2f) {
applyTorque(tempVect1.set(0, -mass * 20, 0));
} else if (rotationVelocity < -0.2f) {
applyTorque(tempVect1.set(0, mass * 20, 0));
}
}
if (accelerationValue > 0) {
// counter force that will adjust velocity
// if we are not going where we want to go.
// this will prevent "drifting" and thus improve control
// of the vehicle
float d = dir.dot(linearVelocity.normalize());
Vector3f counter = dir.project(linearVelocity).normalizeLocal().negateLocal().multLocal(1 - d);
applyForce(counter.multLocal(mass * 10), Vector3f.ZERO);
if (linearVelocity.length() < 30) {
applyForce(dir.multLocal(accelerationValue), Vector3f.ZERO);
}
} else {
// counter the acceleration value
if (linearVelocity.length() > FastMath.ZERO_TOLERANCE) {
linearVelocity.normalizeLocal().negateLocal();
applyForce(linearVelocity.mult(mass * 10), Vector3f.ZERO);
}
}
}
public void physicsTick(PhysicsSpace space, float f) {
}
public void update(float tpf) {
if (enabled && spatial != null) {
getMotionState().applyTransform(spatial);
}
}
public void render(RenderManager rm, ViewPort vp) {
}
public void setPhysicsSpace(PhysicsSpace space) {
createVehicle(space);
if (space == null) {
if (this.space != null) {
this.space.removeCollisionObject(this);
this.space.removeTickListener(this);
}
this.space = space;
} else {
space.addCollisionObject(this);
space.addTickListener(this);
}
this.space = space;
}
public PhysicsSpace getPhysicsSpace() {
return space;
}
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(enabled, "enabled", true);
oc.write(spatial, "spatial", null);
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
enabled = ic.readBoolean("enabled", true);
spatial = (Spatial) ic.readSavable("spatial", null);
}
/**
* @param steeringValue the steeringValue to set
*/
@Override
public void steer(float steeringValue) {
this.steeringValue = steeringValue * getMass();
}
/**
* @param accelerationValue the accelerationValue to set
*/
@Override
public void accelerate(float accelerationValue) {
this.accelerationValue = accelerationValue * getMass();
}
}

@ -0,0 +1,242 @@
/*
* Copyright (c) 2009-2018 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 jme3test.bullet;
import com.jme3.app.Application;
import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
/**
*
* @author normenhansen
*/
public class PhysicsTestHelper {
/**
* creates a simple physics test world with a floor, an obstacle and some test boxes
* @param rootNode
* @param assetManager
* @param space
*/
public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.LightGray);
rootNode.addLight(light);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box floorBox = new Box(140, 0.25f, 140);
Geometry floorGeometry = new Geometry("Floor", floorBox);
floorGeometry.setMaterial(material);
floorGeometry.setLocalTranslation(0, -5, 0);
// Plane plane = new Plane();
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
floorGeometry.addControl(new RigidBodyControl(0));
rootNode.attachChild(floorGeometry);
space.add(floorGeometry);
//movable boxes
for (int i = 0; i < 12; i++) {
Box box = new Box(0.25f, 0.25f, 0.25f);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
boxGeometry.setLocalTranslation(i, 5, -3);
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
boxGeometry.addControl(new RigidBodyControl(2));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
//immovable sphere with mesh collision shape
Sphere sphere = new Sphere(8, 8, 1);
Geometry sphereGeometry = new Geometry("Sphere", sphere);
sphereGeometry.setMaterial(material);
sphereGeometry.setLocalTranslation(4, -4, 2);
sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0));
rootNode.attachChild(sphereGeometry);
space.add(sphereGeometry);
}
public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.LightGray);
rootNode.addLight(light);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box floorBox = new Box(20, 0.25f, 20);
Geometry floorGeometry = new Geometry("Floor", floorBox);
floorGeometry.setMaterial(material);
floorGeometry.setLocalTranslation(0, -0.25f, 0);
// Plane plane = new Plane();
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
floorGeometry.addControl(new RigidBodyControl(0));
rootNode.attachChild(floorGeometry);
space.add(floorGeometry);
//movable spheres
for (int i = 0; i < 5; i++) {
Sphere sphere = new Sphere(16, 16, .5f);
Geometry ballGeometry = new Geometry("Soccer ball", sphere);
ballGeometry.setMaterial(material);
ballGeometry.setLocalTranslation(i, 2, -3);
//RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh
ballGeometry.addControl(new RigidBodyControl(.001f));
ballGeometry.getControl(RigidBodyControl.class).setRestitution(1);
rootNode.attachChild(ballGeometry);
space.add(ballGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
boxGeometry.setLocalTranslation(4, 1, 2);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
boxGeometry.setLocalTranslation(4, 3, 4);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
}
/**
* creates a box geometry with a RigidBodyControl
* @param assetManager
* @return
*/
public static Geometry createPhysicsTestBox(AssetManager assetManager) {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box box = new Box(0.25f, 0.25f, 0.25f);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
boxGeometry.addControl(new RigidBodyControl(2));
return boxGeometry;
}
/**
* creates a sphere geometry with a RigidBodyControl
* @param assetManager
* @return
*/
public static Geometry createPhysicsTestSphere(AssetManager assetManager) {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Sphere sphere = new Sphere(8, 8, 0.25f);
Geometry boxGeometry = new Geometry("Sphere", sphere);
boxGeometry.setMaterial(material);
//RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh
boxGeometry.addControl(new RigidBodyControl(2));
return boxGeometry;
}
/**
* creates an empty node with a RigidBodyControl
* @param manager
* @param shape
* @param mass
* @return
*/
public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) {
Node node = new Node("PhysicsNode");
RigidBodyControl control = new RigidBodyControl(shape, mass);
node.addControl(control);
return node;
}
/**
* creates the necessary inputlistener and action to shoot balls from the camera
* @param app
* @param rootNode
* @param space
*/
public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) {
ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
Sphere bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = app.getAssetManager().loadTexture(key2);
mat2.setTexture("ColorMap", tex2);
if (name.equals("shoot") && !keyPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(app.getCamera().getLocation());
RigidBodyControl bulletControl = new RigidBodyControl(10);
bulletg.addControl(bulletControl);
bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25));
bulletg.addControl(bulletControl);
rootNode.attachChild(bulletg);
space.add(bulletControl);
}
}
};
app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
app.getInputManager().addListener(actionListener, "shoot");
}
}

@ -0,0 +1,294 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.control.VehicleControl;
import com.jme3.bullet.joints.SliderJoint;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.*;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import com.jme3.texture.Texture;
/**
* Tests attaching/detaching nodes via joints
* @author normenhansen
*/
public class TestAttachDriver extends SimpleApplication implements ActionListener {
private VehicleControl vehicle;
private RigidBodyControl driver;
private RigidBodyControl bridge;
private SliderJoint slider;
private final float accelerationForce = 1000.0f;
private final float brakeForce = 100.0f;
private float steeringValue = 0;
private float accelerationValue = 0;
private Vector3f jumpForce = new Vector3f(0, 3000, 0);
private BulletAppState bulletAppState;
public static void main(String[] args) {
TestAttachDriver app = new TestAttachDriver();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
setupKeys();
setupFloor();
buildPlayer();
}
private PhysicsSpace getPhysicsSpace(){
return bulletAppState.getPhysicsSpace();
}
private void setupKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "Lefts");
inputManager.addListener(this, "Rights");
inputManager.addListener(this, "Ups");
inputManager.addListener(this, "Downs");
inputManager.addListener(this, "Space");
inputManager.addListener(this, "Reset");
}
public void setupFloor() {
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Interface/Logo/Monkey.jpg", true);
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
tex.setMinFilter(Texture.MinFilter.Trilinear);
mat.setTexture("ColorMap", tex);
Box floor = new Box(100, 1f, 100);
Geometry floorGeom = new Geometry("Floor", floor);
floorGeom.setMaterial(mat);
floorGeom.setLocalTranslation(new Vector3f(0f, -3, 0f));
floorGeom.addControl(new RigidBodyControl(new MeshCollisionShape(floorGeom.getMesh()), 0));
rootNode.attachChild(floorGeom);
getPhysicsSpace().add(floorGeom);
}
private void buildPlayer() {
Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor("Color", ColorRGBA.Red);
//create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0
//this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0
CompoundCollisionShape compoundShape = new CompoundCollisionShape();
BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.2f, 0.5f, 2.4f));
compoundShape.addChildShape(box, new Vector3f(0, 1, 0));
//create vehicle node
Node vehicleNode=new Node("vehicleNode");
vehicle = new VehicleControl(compoundShape, 800);
vehicleNode.addControl(vehicle);
//setting suspension values for wheels, this can be a bit tricky
//see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en
float stiffness = 60.0f;//200=f1 car
float compValue = .3f; //(should be lower than damp)
float dampValue = .4f;
vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
vehicle.setSuspensionStiffness(stiffness);
vehicle.setMaxSuspensionForce(10000.0f);
//Create four wheels and add them at their locations
Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0
Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0
float radius = 0.5f;
float restLength = 0.3f;
float yOff = 0.5f;
float xOff = 1f;
float zOff = 2f;
Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.6f, true);
Node node1 = new Node("wheel 1 node");
Geometry wheels1 = new Geometry("wheel 1", wheelMesh);
node1.attachChild(wheels1);
wheels1.rotate(0, FastMath.HALF_PI, 0);
wheels1.setMaterial(mat);
vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff),
wheelDirection, wheelAxle, restLength, radius, true);
Node node2 = new Node("wheel 2 node");
Geometry wheels2 = new Geometry("wheel 2", wheelMesh);
node2.attachChild(wheels2);
wheels2.rotate(0, FastMath.HALF_PI, 0);
wheels2.setMaterial(mat);
vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff),
wheelDirection, wheelAxle, restLength, radius, true);
Node node3 = new Node("wheel 3 node");
Geometry wheels3 = new Geometry("wheel 3", wheelMesh);
node3.attachChild(wheels3);
wheels3.rotate(0, FastMath.HALF_PI, 0);
wheels3.setMaterial(mat);
vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff),
wheelDirection, wheelAxle, restLength, radius, false);
Node node4 = new Node("wheel 4 node");
Geometry wheels4 = new Geometry("wheel 4", wheelMesh);
node4.attachChild(wheels4);
wheels4.rotate(0, FastMath.HALF_PI, 0);
wheels4.setMaterial(mat);
vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff),
wheelDirection, wheelAxle, restLength, radius, false);
vehicleNode.attachChild(node1);
vehicleNode.attachChild(node2);
vehicleNode.attachChild(node3);
vehicleNode.attachChild(node4);
rootNode.attachChild(vehicleNode);
getPhysicsSpace().add(vehicle);
//driver
Node driverNode=new Node("driverNode");
driverNode.setLocalTranslation(0,2,0);
driver=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,.5f,0.2f)));
driverNode.addControl(driver);
rootNode.attachChild(driverNode);
getPhysicsSpace().add(driver);
//joint
slider=new SliderJoint(driver, vehicle, Vector3f.UNIT_Y.negate(), Vector3f.UNIT_Y, true);
slider.setUpperLinLimit(.1f);
slider.setLowerLinLimit(-.1f);
getPhysicsSpace().add(slider);
Node pole1Node=new Node("pole1Node");
Node pole2Node=new Node("pole1Node");
Node bridgeNode=new Node("pole1Node");
pole1Node.setLocalTranslation(new Vector3f(-2,-1,4));
pole2Node.setLocalTranslation(new Vector3f(2,-1,4));
bridgeNode.setLocalTranslation(new Vector3f(0,1.4f,4));
RigidBodyControl pole1=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0);
pole1Node.addControl(pole1);
RigidBodyControl pole2=new RigidBodyControl(new BoxCollisionShape(new Vector3f(0.2f,1.25f,0.2f)),0);
pole2Node.addControl(pole2);
bridge=new RigidBodyControl(new BoxCollisionShape(new Vector3f(2.5f,0.2f,0.2f)));
bridgeNode.addControl(bridge);
rootNode.attachChild(pole1Node);
rootNode.attachChild(pole2Node);
rootNode.attachChild(bridgeNode);
getPhysicsSpace().add(pole1);
getPhysicsSpace().add(pole2);
getPhysicsSpace().add(bridge);
}
@Override
public void simpleUpdate(float tpf) {
Quaternion quat=new Quaternion();
cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y);
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if (value) {
steeringValue += .5f;
} else {
steeringValue += -.5f;
}
vehicle.steer(steeringValue);
} else if (binding.equals("Rights")) {
if (value) {
steeringValue += -.5f;
} else {
steeringValue += .5f;
}
vehicle.steer(steeringValue);
} else if (binding.equals("Ups")) {
if (value) {
accelerationValue += accelerationForce;
} else {
accelerationValue -= accelerationForce;
}
vehicle.accelerate(accelerationValue);
} else if (binding.equals("Downs")) {
if (value) {
vehicle.brake(brakeForce);
} else {
vehicle.brake(0f);
}
} else if (binding.equals("Space")) {
if (value) {
getPhysicsSpace().remove(slider);
slider.destroy();
vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
}
} else if (binding.equals("Reset")) {
if (value) {
System.out.println("Reset");
vehicle.setPhysicsLocation(new Vector3f(0, 0, 0));
vehicle.setPhysicsRotation(new Matrix3f());
vehicle.setLinearVelocity(Vector3f.ZERO);
vehicle.setAngularVelocity(Vector3f.ZERO);
vehicle.resetSuspension();
bridge.setPhysicsLocation(new Vector3f(0,1.4f,4));
bridge.setPhysicsRotation(Quaternion.DIRECTION_Z.toRotationMatrix());
}
}
}
}

@ -0,0 +1,130 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.PhysicsControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.joints.HingeJoint;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
/**
* Tests attaching ghost nodes to physicsnodes via the scenegraph
* @author normenhansen
*/
public class TestAttachGhostObject extends SimpleApplication implements AnalogListener {
private HingeJoint joint;
private GhostControl ghostControl;
private Node collisionNode;
private Node hammerNode;
private Vector3f tempVec = new Vector3f();
private BulletAppState bulletAppState;
public static void main(String[] args) {
TestAttachGhostObject app = new TestAttachGhostObject();
app.start();
}
private void setupKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K));
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "Lefts", "Rights", "Space");
}
public void onAnalog(String binding, float value, float tpf) {
if (binding.equals("Lefts")) {
joint.enableMotor(true, 1, .1f);
} else if (binding.equals("Rights")) {
joint.enableMotor(true, -1, .1f);
} else if (binding.equals("Space")) {
joint.enableMotor(false, 0, 0);
}
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
setupKeys();
setupJoint();
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
public void setupJoint() {
Node holderNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.1f, .1f, .1f)), 0);
holderNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, 0, 0f));
rootNode.attachChild(holderNode);
getPhysicsSpace().add(holderNode);
Node hammerNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 1);
hammerNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -1, 0f));
rootNode.attachChild(hammerNode);
getPhysicsSpace().add(hammerNode);
//immovable
collisionNode = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(.3f, .3f, .3f)), 0);
collisionNode.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(1.8f, 0, 0f));
rootNode.attachChild(collisionNode);
getPhysicsSpace().add(collisionNode);
//ghost node
ghostControl = new GhostControl(new SphereCollisionShape(0.7f));
hammerNode.addControl(ghostControl);
getPhysicsSpace().add(ghostControl);
joint = new HingeJoint(holderNode.getControl(RigidBodyControl.class), hammerNode.getControl(RigidBodyControl.class), Vector3f.ZERO, new Vector3f(0f, -1, 0f), Vector3f.UNIT_Z, Vector3f.UNIT_Z);
getPhysicsSpace().add(joint);
}
@Override
public void simpleUpdate(float tpf) {
if (ghostControl.getOverlappingObjects().contains(collisionNode.getControl(PhysicsControl.class))) {
fpsText.setText("collide");
}
}
}

@ -0,0 +1,295 @@
/*
* Copyright (c) 2009-2018 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.shape.Sphere;
import com.jme3.system.AppSettings;
/**
* A walking physical character followed by a 3rd person camera. (No animation.)
*
* @author normenhansen, zathras
*/
public class TestBetterCharacter extends SimpleApplication implements ActionListener {
private BulletAppState bulletAppState;
private BetterCharacterControl physicsCharacter;
private Node characterNode;
private CameraNode camNode;
boolean rotate = false;
private Vector3f walkDirection = new Vector3f(0, 0, 0);
private Vector3f viewDirection = new Vector3f(0, 0, 1);
boolean leftStrafe = false, rightStrafe = false, forward = false, backward = false,
leftRotate = false, rightRotate = false;
private Vector3f normalGravity = new Vector3f(0, -9.81f, 0);
private Geometry planet;
public static void main(String[] args) {
TestBetterCharacter app = new TestBetterCharacter();
AppSettings settings = new AppSettings(true);
settings.setRenderer(AppSettings.LWJGL_OPENGL2);
settings.setAudioRenderer(AppSettings.LWJGL_OPENAL);
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
//setup keyboard mapping
setupKeys();
// activate physics
bulletAppState = new BulletAppState() {
@Override
public void prePhysicsTick(PhysicsSpace space, float tpf) {
// Apply radial gravity near the planet, downward gravity elsewhere.
checkPlanetGravity();
}
};
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
// init a physics test scene
PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace());
PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace());
setupPlanet();
// Create a node for the character model
characterNode = new Node("character node");
characterNode.setLocalTranslation(new Vector3f(4, 5, 2));
// Add a character control to the node so we can add other things and
// control the model rotation
physicsCharacter = new BetterCharacterControl(0.3f, 2.5f, 8f);
characterNode.addControl(physicsCharacter);
getPhysicsSpace().add(physicsCharacter);
// Load model, attach to character node
Node model = (Node) assetManager.loadModel("Models/Jaime/Jaime.j3o");
model.setLocalScale(1.50f);
characterNode.attachChild(model);
// Add character node to the rootNode
rootNode.attachChild(characterNode);
// Set forward camera node that follows the character, only used when
// view is "locked"
camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 2, -6));
Quaternion quat = new Quaternion();
// These coordinates are local, the camNode is attached to the character node!
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
characterNode.attachChild(camNode);
// Disable by default, can be enabled via keyboard shortcut
camNode.setEnabled(false);
}
@Override
public void simpleUpdate(float tpf) {
// Get current forward and left vectors of model by using its rotation
// to rotate the unit vectors
Vector3f modelForwardDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_Z);
Vector3f modelLeftDir = characterNode.getWorldRotation().mult(Vector3f.UNIT_X);
// WalkDirection is global!
// You *can* make your character fly with this.
walkDirection.set(0, 0, 0);
if (leftStrafe) {
walkDirection.addLocal(modelLeftDir.mult(3));
} else if (rightStrafe) {
walkDirection.addLocal(modelLeftDir.negate().multLocal(3));
}
if (forward) {
walkDirection.addLocal(modelForwardDir.mult(3));
} else if (backward) {
walkDirection.addLocal(modelForwardDir.negate().multLocal(3));
}
physicsCharacter.setWalkDirection(walkDirection);
// ViewDirection is local to characters physics system!
// The final world rotation depends on the gravity and on the state of
// setApplyPhysicsLocal()
if (leftRotate) {
Quaternion rotateL = new Quaternion().fromAngleAxis(FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateL.multLocal(viewDirection);
} else if (rightRotate) {
Quaternion rotateR = new Quaternion().fromAngleAxis(-FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateR.multLocal(viewDirection);
}
physicsCharacter.setViewDirection(viewDirection);
fpsText.setText("Touch da ground = " + physicsCharacter.isOnGround());
if (!lockView) {
cam.lookAt(characterNode.getWorldTranslation().add(new Vector3f(0, 2, 0)), Vector3f.UNIT_Y);
}
}
private void setupPlanet() {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
//immovable sphere with mesh collision shape
Sphere sphere = new Sphere(64, 64, 20);
planet = new Geometry("Sphere", sphere);
planet.setMaterial(material);
planet.setLocalTranslation(30, -15, 30);
planet.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0));
rootNode.attachChild(planet);
getPhysicsSpace().add(planet);
}
private void checkPlanetGravity() {
Vector3f planetDist = planet.getWorldTranslation().subtract(characterNode.getWorldTranslation());
if (planetDist.length() < 24) {
physicsCharacter.setGravity(planetDist.normalizeLocal().multLocal(9.81f));
} else {
physicsCharacter.setGravity(normalGravity);
}
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Strafe Left")) {
if (value) {
leftStrafe = true;
} else {
leftStrafe = false;
}
} else if (binding.equals("Strafe Right")) {
if (value) {
rightStrafe = true;
} else {
rightStrafe = false;
}
} else if (binding.equals("Rotate Left")) {
if (value) {
leftRotate = true;
} else {
leftRotate = false;
}
} else if (binding.equals("Rotate Right")) {
if (value) {
rightRotate = true;
} else {
rightRotate = false;
}
} else if (binding.equals("Walk Forward")) {
if (value) {
forward = true;
} else {
forward = false;
}
} else if (binding.equals("Walk Backward")) {
if (value) {
backward = true;
} else {
backward = false;
}
} else if (binding.equals("Jump")) {
physicsCharacter.jump();
} else if (binding.equals("Duck")) {
if (value) {
physicsCharacter.setDucked(true);
} else {
physicsCharacter.setDucked(false);
}
} else if (binding.equals("Lock View")) {
if (value && lockView) {
lockView = false;
} else if (value && !lockView) {
lockView = true;
}
flyCam.setEnabled(!lockView);
camNode.setEnabled(lockView);
}
}
private boolean lockView = false;
private void setupKeys() {
inputManager.addMapping("Strafe Left",
new KeyTrigger(KeyInput.KEY_U),
new KeyTrigger(KeyInput.KEY_Z));
inputManager.addMapping("Strafe Right",
new KeyTrigger(KeyInput.KEY_O),
new KeyTrigger(KeyInput.KEY_X));
inputManager.addMapping("Rotate Left",
new KeyTrigger(KeyInput.KEY_J),
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Rotate Right",
new KeyTrigger(KeyInput.KEY_L),
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("Walk Forward",
new KeyTrigger(KeyInput.KEY_I),
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Walk Backward",
new KeyTrigger(KeyInput.KEY_K),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Jump",
new KeyTrigger(KeyInput.KEY_F),
new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("Duck",
new KeyTrigger(KeyInput.KEY_G),
new KeyTrigger(KeyInput.KEY_LSHIFT),
new KeyTrigger(KeyInput.KEY_RSHIFT));
inputManager.addMapping("Lock View",
new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "Strafe Left", "Strafe Right");
inputManager.addListener(this, "Rotate Left", "Rotate Right");
inputManager.addListener(this, "Walk Forward", "Walk Backward");
inputManager.addListener(this, "Jump", "Duck", "Lock View");
}
@Override
public void simpleRender(RenderManager rm) {
}
}

@ -0,0 +1,357 @@
/*
* 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 jme3test.bullet;
import com.jme3.animation.*;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.RagdollCollisionListener;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.KinematicRagdollControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.DirectionalLight;
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.Node;
import com.jme3.scene.debug.SkeletonDebugger;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
/**
* PHYSICS RAGDOLLS ARE NOT WORKING PROPERLY YET!
* @author normenhansen
*/
public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisionListener, AnimEventListener {
private BulletAppState bulletAppState;
Material matBullet;
Node model;
KinematicRagdollControl ragdoll;
float bulletSize = 1f;
Material mat;
Material mat3;
private Sphere bullet;
private SphereCollisionShape bulletCollisionShape;
public static void main(String[] args) {
TestBoneRagdoll app = new TestBoneRagdoll();
app.start();
}
public void simpleInitApp() {
initCrossHairs();
initMaterial();
cam.setLocation(new Vector3f(0.26924422f, 6.646658f, 22.265987f));
cam.setRotation(new Quaternion(-2.302544E-4f, 0.99302495f, -0.117888905f, -0.0019395084f));
bulletAppState = new BulletAppState();
bulletAppState.setEnabled(true);
stateManager.attach(bulletAppState);
bullet = new Sphere(32, 32, 1.0f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(1.0f);
// bulletAppState.getPhysicsSpace().enableDebug(assetManager);
PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
setupLight();
model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
// model.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X));
//debug view
AnimControl control = model.getControl(AnimControl.class);
SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
Material mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat2.getAdditionalRenderState().setWireframe(true);
mat2.setColor("Color", ColorRGBA.Green);
mat2.getAdditionalRenderState().setDepthTest(false);
skeletonDebug.setMaterial(mat2);
skeletonDebug.setLocalTranslation(model.getLocalTranslation());
//Note: PhysicsRagdollControl is still TODO, constructor will change
ragdoll = new KinematicRagdollControl(0.5f);
setupSinbad(ragdoll);
ragdoll.addCollisionListener(this);
model.addControl(ragdoll);
float eighth_pi = FastMath.PI * 0.125f;
ragdoll.setJointLimit("Waist", eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi);
ragdoll.setJointLimit("Chest", eighth_pi, eighth_pi, 0, 0, eighth_pi, eighth_pi);
//Oto's head is almost rigid
// ragdoll.setJointLimit("head", 0, 0, eighth_pi, -eighth_pi, 0, 0);
getPhysicsSpace().add(ragdoll);
speed = 1.3f;
rootNode.attachChild(model);
// rootNode.attachChild(skeletonDebug);
flyCam.setMoveSpeed(50);
animChannel = control.createChannel();
animChannel.setAnim("Dance");
control.addListener(this);
inputManager.addListener(new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("toggle") && isPressed) {
Vector3f v = new Vector3f();
v.set(model.getLocalTranslation());
v.y = 0;
model.setLocalTranslation(v);
Quaternion q = new Quaternion();
float[] angles = new float[3];
model.getLocalRotation().toAngles(angles);
q.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
model.setLocalRotation(q);
if (angles[0] < 0) {
animChannel.setAnim("StandUpBack");
ragdoll.blendToKinematicMode(0.5f);
} else {
animChannel.setAnim("StandUpFront");
ragdoll.blendToKinematicMode(0.5f);
}
}
if (name.equals("bullet+") && isPressed) {
bulletSize += 0.1f;
}
if (name.equals("bullet-") && isPressed) {
bulletSize -= 0.1f;
}
if (name.equals("stop") && isPressed) {
ragdoll.setEnabled(!ragdoll.isEnabled());
ragdoll.setRagdollMode();
}
if (name.equals("shoot") && !isPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(matBullet);
bulletg.setLocalTranslation(cam.getLocation());
bulletg.setLocalScale(bulletSize);
bulletCollisionShape = new SphereCollisionShape(bulletSize);
RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10);
bulletNode.setCcdMotionThreshold(0.001f);
bulletNode.setLinearVelocity(cam.getDirection().mult(80));
bulletg.addControl(bulletNode);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletNode);
}
if (name.equals("boom") && !isPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(matBullet);
bulletg.setLocalTranslation(cam.getLocation());
bulletg.setLocalScale(bulletSize);
bulletCollisionShape = new SphereCollisionShape(bulletSize);
BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
bulletNode.setForceFactor(8);
bulletNode.setExplosionRadius(20);
bulletNode.setCcdMotionThreshold(0.001f);
bulletNode.setLinearVelocity(cam.getDirection().mult(180));
bulletg.addControl(bulletNode);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletNode);
}
}
}, "toggle", "shoot", "stop", "bullet+", "bullet-", "boom");
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addMapping("boom", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H));
inputManager.addMapping("bullet-", new KeyTrigger(KeyInput.KEY_COMMA));
inputManager.addMapping("bullet+", new KeyTrigger(KeyInput.KEY_PERIOD));
}
private void setupLight() {
// AmbientLight al = new AmbientLight();
// al.setColor(ColorRGBA.White.mult(1));
// rootNode.addLight(al);
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal());
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
public void initMaterial() {
matBullet = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
matBullet.setTexture("ColorMap", tex2);
}
protected void initCrossHairs() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // crosshairs
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
public void collide(Bone bone, PhysicsCollisionObject object, PhysicsCollisionEvent event) {
if (object.getUserObject() != null && object.getUserObject() instanceof Geometry) {
Geometry geom = (Geometry) object.getUserObject();
if ("Floor".equals(geom.getName())) {
return;
}
}
ragdoll.setRagdollMode();
}
private void setupSinbad(KinematicRagdollControl ragdoll) {
ragdoll.addBoneName("Ulna.L");
ragdoll.addBoneName("Ulna.R");
ragdoll.addBoneName("Chest");
ragdoll.addBoneName("Foot.L");
ragdoll.addBoneName("Foot.R");
ragdoll.addBoneName("Hand.R");
ragdoll.addBoneName("Hand.L");
ragdoll.addBoneName("Neck");
ragdoll.addBoneName("Root");
ragdoll.addBoneName("Stomach");
ragdoll.addBoneName("Waist");
ragdoll.addBoneName("Humerus.L");
ragdoll.addBoneName("Humerus.R");
ragdoll.addBoneName("Thigh.L");
ragdoll.addBoneName("Thigh.R");
ragdoll.addBoneName("Calf.L");
ragdoll.addBoneName("Calf.R");
ragdoll.addBoneName("Clavicle.L");
ragdoll.addBoneName("Clavicle.R");
}
float elTime = 0;
boolean forward = true;
AnimControl animControl;
AnimChannel animChannel;
Vector3f direction = new Vector3f(0, 0, 1);
Quaternion rotate = new Quaternion().fromAngleAxis(FastMath.PI / 8, Vector3f.UNIT_Y);
boolean dance = true;
@Override
public void simpleUpdate(float tpf) {
// System.out.println(((BoundingBox) model.getWorldBound()).getYExtent());
// elTime += tpf;
// if (elTime > 3) {
// elTime = 0;
// if (dance) {
// rotate.multLocal(direction);
// }
// if (Math.random() > 0.80) {
// dance = true;
// animChannel.setAnim("Dance");
// } else {
// dance = false;
// animChannel.setAnim("RunBase");
// rotate.fromAngleAxis(FastMath.QUARTER_PI * ((float) Math.random() - 0.5f), Vector3f.UNIT_Y);
// rotate.multLocal(direction);
// }
// }
// if (!ragdoll.hasControl() && !dance) {
// if (model.getLocalTranslation().getZ() < -10) {
// direction.z = 1;
// direction.normalizeLocal();
// } else if (model.getLocalTranslation().getZ() > 10) {
// direction.z = -1;
// direction.normalizeLocal();
// }
// if (model.getLocalTranslation().getX() < -10) {
// direction.x = 1;
// direction.normalizeLocal();
// } else if (model.getLocalTranslation().getX() > 10) {
// direction.x = -1;
// direction.normalizeLocal();
// }
// model.move(direction.multLocal(tpf * 8));
// direction.normalizeLocal();
// model.lookAt(model.getLocalTranslation().add(direction), Vector3f.UNIT_Y);
// }
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
// if(channel.getAnimationName().equals("StandUpFront")){
// channel.setAnim("Dance");
// }
if (channel.getAnimationName().equals("StandUpBack") || channel.getAnimationName().equals("StandUpFront")) {
channel.setLoopMode(LoopMode.DontLoop);
channel.setAnim("IdleTop", 5);
channel.setLoopMode(LoopMode.Loop);
}
// if(channel.getAnimationName().equals("IdleTop")){
// channel.setAnim("StandUpFront");
// }
}
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
}
}

@ -0,0 +1,251 @@
/*
* 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 jme3test.bullet;
/*
* 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.
*/
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
/**
*
* @author double1984 (tower mod by atom)
*/
public class TestBrickTower extends SimpleApplication {
int bricksPerLayer = 8;
int brickLayers = 30;
static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f;
float radius = 3f;
float angle = 0;
Material mat;
Material mat2;
Material mat3;
private Sphere bullet;
private Box brick;
private SphereCollisionShape bulletCollisionShape;
private BulletAppState bulletAppState;
public static void main(String args[]) {
TestBrickTower f = new TestBrickTower();
f.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
// bulletAppState.setEnabled(false);
stateManager.attach(bulletAppState);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);
brick = new Box(brickWidth, brickHeight, brickDepth);
brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
initMaterial();
initTower();
initFloor();
initCrossHairs();
this.cam.setLocation(new Vector3f(0, 25f, 8f));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(80);
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
rootNode.setShadowMode(ShadowMode.Off);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("shoot") && !keyPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(cam.getLocation());
RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1);
bulletNode.setLinearVelocity(cam.getDirection().mult(25));
bulletg.addControl(bulletNode);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletNode);
}
}
};
public void initTower() {
double tempX = 0;
double tempY = 0;
double tempZ = 0;
angle = 0f;
for (int i = 0; i < brickLayers; i++){
// Increment rows
if(i!=0)
tempY+=brickHeight*2;
else
tempY=brickHeight;
// Alternate brick seams
angle = 360.0f / bricksPerLayer * i/2f;
for (int j = 0; j < bricksPerLayer; j++){
tempZ = Math.cos(Math.toRadians(angle))*radius;
tempX = Math.sin(Math.toRadians(angle))*radius;
System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ));
Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ));
// Add crenelation
if (i==brickLayers-1){
if (j%2 == 0){
addBrick(vt);
}
}
// Create main tower
else {
addBrick(vt);
}
angle += 360.0/bricksPerLayer;
}
}
}
public void initFloor() {
Box floorBox = new Box(10f, 0.1f, 5f);
floorBox.scaleTextureCoordinates(new Vector2f(3, 6));
Geometry floor = new Geometry("floor", floorBox);
floor.setMaterial(mat3);
floor.setShadowMode(ShadowMode.Receive);
floor.setLocalTranslation(0, 0, 0);
floor.addControl(new RigidBodyControl(0));
this.rootNode.attachChild(floor);
this.getPhysicsSpace().add(floor);
}
public void initMaterial() {
mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
mat.setTexture("ColorMap", tex);
mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
mat2.setTexture("ColorMap", tex2);
mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
key3.setGenerateMips(true);
Texture tex3 = assetManager.loadTexture(key3);
tex3.setWrap(WrapMode.Repeat);
mat3.setTexture("ColorMap", tex3);
}
public void addBrick(Vector3f ori) {
Geometry reBoxg = new Geometry("brick", brick);
reBoxg.setMaterial(mat);
reBoxg.setLocalTranslation(ori);
reBoxg.rotate(0f, (float)Math.toRadians(angle) , 0f );
reBoxg.addControl(new RigidBodyControl(1.5f));
reBoxg.setShadowMode(ShadowMode.CastAndReceive);
reBoxg.getControl(RigidBodyControl.class).setFriction(1.6f);
this.rootNode.attachChild(reBoxg);
this.getPhysicsSpace().add(reBoxg);
}
protected void initCrossHairs() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // crosshairs
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
}

@ -0,0 +1,205 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
/**
*
* @author double1984
*/
public class TestBrickWall extends SimpleApplication {
static float bLength = 0.48f;
static float bWidth = 0.24f;
static float bHeight = 0.12f;
Material mat;
Material mat2;
Material mat3;
private static Sphere bullet;
private static Box brick;
private static SphereCollisionShape bulletCollisionShape;
private BulletAppState bulletAppState;
public static void main(String args[]) {
TestBrickWall f = new TestBrickWall();
f.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);
brick = new Box(bLength, bHeight, bWidth);
brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
initMaterial();
initWall();
initFloor();
initCrossHairs();
this.cam.setLocation(new Vector3f(0, 6f, 6f));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(15);
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
inputManager.addMapping("gc", new KeyTrigger(KeyInput.KEY_X));
inputManager.addListener(actionListener, "gc");
rootNode.setShadowMode(ShadowMode.Off);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("shoot") && !keyPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(cam.getLocation());
SphereCollisionShape bulletCollisionShape = new SphereCollisionShape(0.4f);
RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
// RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1);
bulletNode.setLinearVelocity(cam.getDirection().mult(25));
bulletg.addControl(bulletNode);
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletNode);
}
if (name.equals("gc") && !keyPressed) {
System.gc();
}
}
};
public void initWall() {
float startpt = bLength / 4;
float height = 0;
for (int j = 0; j < 15; j++) {
for (int i = 0; i < 4; i++) {
Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight + height, 0);
addBrick(vt);
}
startpt = -startpt;
height += 2 * bHeight;
}
}
public void initFloor() {
Box floorBox = new Box(10f, 0.1f, 5f);
floorBox.scaleTextureCoordinates(new Vector2f(3, 6));
Geometry floor = new Geometry("floor", floorBox);
floor.setMaterial(mat3);
floor.setShadowMode(ShadowMode.Receive);
floor.setLocalTranslation(0, -0.1f, 0);
floor.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(10f, 0.1f, 5f)), 0));
this.rootNode.attachChild(floor);
this.getPhysicsSpace().add(floor);
}
public void initMaterial() {
mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
mat.setTexture("ColorMap", tex);
mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
mat2.setTexture("ColorMap", tex2);
mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
key3.setGenerateMips(true);
Texture tex3 = assetManager.loadTexture(key3);
tex3.setWrap(WrapMode.Repeat);
mat3.setTexture("ColorMap", tex3);
}
public void addBrick(Vector3f ori) {
Geometry reBoxg = new Geometry("brick", brick);
reBoxg.setMaterial(mat);
reBoxg.setLocalTranslation(ori);
//for geometry with sphere mesh the physics system automatically uses a sphere collision shape
reBoxg.addControl(new RigidBodyControl(1.5f));
reBoxg.setShadowMode(ShadowMode.CastAndReceive);
reBoxg.getControl(RigidBodyControl.class).setFriction(0.6f);
this.rootNode.attachChild(reBoxg);
this.getPhysicsSpace().add(reBoxg);
}
protected void initCrossHairs() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // crosshairs
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}
}

@ -0,0 +1,152 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
/**
*
* @author normenhansen
*/
public class TestCcd extends SimpleApplication implements ActionListener {
private Material mat;
private Material mat2;
private Sphere bullet;
private SphereCollisionShape bulletCollisionShape;
private BulletAppState bulletAppState;
public static void main(String[] args) {
TestCcd app = new TestCcd();
app.start();
}
private void setupKeys() {
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addMapping("shoot2", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addListener(this, "shoot");
inputManager.addListener(this, "shoot2");
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.1f);
setupKeys();
mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor("Color", ColorRGBA.Green);
mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat2.getAdditionalRenderState().setWireframe(true);
mat2.setColor("Color", ColorRGBA.Red);
// An obstacle mesh, does not move (mass=0)
Node node2 = new Node();
node2.setName("mesh");
node2.setLocalTranslation(new Vector3f(2.5f, 0, 0f));
node2.addControl(new RigidBodyControl(new MeshCollisionShape(new Box(4, 4, 0.1f)), 0));
rootNode.attachChild(node2);
getPhysicsSpace().add(node2);
// The floor, does not move (mass=0)
Node node3 = new Node();
node3.setLocalTranslation(new Vector3f(0f, -6, 0f));
node3.addControl(new RigidBodyControl(new BoxCollisionShape(new Vector3f(100, 1, 100)), 0));
rootNode.attachChild(node3);
getPhysicsSpace().add(node3);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("shoot") && !value) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat);
bulletg.setName("bullet");
bulletg.setLocalTranslation(cam.getLocation());
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.addControl(new RigidBodyControl(bulletCollisionShape, 1));
bulletg.getControl(RigidBodyControl.class).setCcdMotionThreshold(0.1f);
bulletg.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40));
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletg);
} else if (binding.equals("shoot2") && !value) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setName("bullet");
bulletg.setLocalTranslation(cam.getLocation());
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.addControl(new RigidBodyControl(bulletCollisionShape, 1));
bulletg.getControl(RigidBodyControl.class).setLinearVelocity(cam.getDirection().mult(40));
rootNode.attachChild(bulletg);
getPhysicsSpace().add(bulletg);
}
}
}

@ -0,0 +1,107 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
/**
*
* @author normenhansen
*/
public class TestCollisionGroups extends SimpleApplication {
private BulletAppState bulletAppState;
public static void main(String[] args) {
TestCollisionGroups app = new TestCollisionGroups();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
// Add a physics sphere to the world
Node physicsSphere = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
physicsSphere.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(3, 6, 0));
rootNode.attachChild(physicsSphere);
getPhysicsSpace().add(physicsSphere);
// Add a physics sphere to the world
Node physicsSphere2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new SphereCollisionShape(1), 1);
physicsSphere2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(4, 8, 0));
physicsSphere2.getControl(RigidBodyControl.class).addCollideWithGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
rootNode.attachChild(physicsSphere2);
getPhysicsSpace().add(physicsSphere2);
// an obstacle mesh, does not move (mass=0)
Node node2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Sphere(16, 16, 1.2f)), 0);
node2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(2.5f, -4, 0f));
node2.getControl(RigidBodyControl.class).setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
node2.getControl(RigidBodyControl.class).setCollideWithGroups(PhysicsCollisionObject.COLLISION_GROUP_02);
rootNode.attachChild(node2);
getPhysicsSpace().add(node2);
// the floor, does not move (mass=0)
Node node3 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new MeshCollisionShape(new Box(100f, 0.2f, 100f)), 0);
node3.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f));
rootNode.attachChild(node3);
getPhysicsSpace().add(node3);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}

@ -0,0 +1,98 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
/**
*
* @author normenhansen
*/
public class TestCollisionListener extends SimpleApplication implements PhysicsCollisionListener {
private BulletAppState bulletAppState;
private Sphere bullet;
private SphereCollisionShape bulletCollisionShape;
public static void main(String[] args) {
TestCollisionListener app = new TestCollisionListener();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);
PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace());
// add ourselves as collision listener
getPhysicsSpace().addCollisionListener(this);
}
private PhysicsSpace getPhysicsSpace(){
return bulletAppState.getPhysicsSpace();
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
public void collision(PhysicsCollisionEvent event) {
if ("Box".equals(event.getNodeA().getName()) || "Box".equals(event.getNodeB().getName())) {
if ("bullet".equals(event.getNodeA().getName()) || "bullet".equals(event.getNodeB().getName())) {
fpsText.setText("You hit the box!");
}
}
}
}

@ -0,0 +1,137 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import com.jme3.scene.shape.Torus;
/**
* This is a basic Test of jbullet-jme functions
*
* @author normenhansen
*/
public class TestCollisionShapeFactory extends SimpleApplication {
private BulletAppState bulletAppState;
private Material mat1;
private Material mat2;
private Material mat3;
public static void main(String[] args) {
TestCollisionShapeFactory app = new TestCollisionShapeFactory();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
createMaterial();
Node node = new Node("node1");
attachRandomGeometry(node, mat1);
randomizeTransform(node);
Node node2 = new Node("node2");
attachRandomGeometry(node2, mat2);
randomizeTransform(node2);
node.attachChild(node2);
rootNode.attachChild(node);
RigidBodyControl control = new RigidBodyControl(0);
node.addControl(control);
getPhysicsSpace().add(control);
//test single geometry too
Geometry myGeom = new Geometry("cylinder", new Cylinder(16, 16, 0.5f, 1));
myGeom.setMaterial(mat3);
randomizeTransform(myGeom);
rootNode.attachChild(myGeom);
RigidBodyControl control3 = new RigidBodyControl(0);
myGeom.addControl(control3);
getPhysicsSpace().add(control3);
}
private void attachRandomGeometry(Node node, Material mat) {
Box box = new Box(0.25f, 0.25f, 0.25f);
Torus torus = new Torus(16, 16, 0.2f, 0.8f);
Geometry[] boxes = new Geometry[]{
new Geometry("box1", box),
new Geometry("box2", box),
new Geometry("box3", box),
new Geometry("torus1", torus),
new Geometry("torus2", torus),
new Geometry("torus3", torus)
};
for (int i = 0; i < boxes.length; i++) {
Geometry geometry = boxes[i];
geometry.setLocalTranslation((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10);
geometry.setLocalRotation(new Quaternion().fromAngles((float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI, (float) Math.random() * FastMath.PI));
geometry.setLocalScale((float) Math.random() * 10 -10, (float) Math.random() * 10 -10, (float) Math.random() * 10 -10);
geometry.setMaterial(mat);
node.attachChild(geometry);
}
}
private void randomizeTransform(Spatial spat){
spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10);
spat.setLocalTranslation((float) Math.random() * 10, (float) Math.random() * 10, (float) Math.random() * 10);
spat.setLocalScale((float) Math.random() * 2, (float) Math.random() * 2, (float) Math.random() * 2);
}
private void createMaterial() {
mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Green);
mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.Red);
mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat3.setColor("Color", ColorRGBA.Yellow);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
}

@ -0,0 +1,259 @@
/*
* Copyright (c) 2009-2018 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.VehicleControl;
import com.jme3.bullet.objects.VehicleWheel;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
public class TestFancyCar extends SimpleApplication implements ActionListener {
private BulletAppState bulletAppState;
private VehicleControl player;
private VehicleWheel fr, fl, br, bl;
private Node node_fr, node_fl, node_br, node_bl;
private float wheelRadius;
private float steeringValue = 0;
private float accelerationValue = 0;
private Node carNode;
public static void main(String[] args) {
TestFancyCar app = new TestFancyCar();
app.start();
}
private void setupKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "Lefts");
inputManager.addListener(this, "Rights");
inputManager.addListener(this, "Ups");
inputManager.addListener(this, "Downs");
inputManager.addListener(this, "Space");
inputManager.addListener(this, "Reset");
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
// bulletAppState.getPhysicsSpace().enableDebug(assetManager);
cam.setFrustumFar(150f);
flyCam.setMoveSpeed(10);
setupKeys();
PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
// setupFloor();
buildPlayer();
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.5f, -1f, -0.3f).normalizeLocal());
rootNode.addLight(dl);
dl = new DirectionalLight();
dl.setDirection(new Vector3f(0.5f, -0.1f, 0.3f).normalizeLocal());
// rootNode.addLight(dl);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
// public void setupFloor() {
// Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m");
// mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat);
//// mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat);
//// mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat);
//
// Box floor = new Box(Vector3f.ZERO, 140, 1f, 140);
// floor.scaleTextureCoordinates(new Vector2f(112.0f, 112.0f));
// Geometry floorGeom = new Geometry("Floor", floor);
// floorGeom.setShadowMode(ShadowMode.Receive);
// floorGeom.setMaterial(mat);
//
// PhysicsNode tb = new PhysicsNode(floorGeom, new MeshCollisionShape(floorGeom.getMesh()), 0);
// tb.setLocalTranslation(new Vector3f(0f, -6, 0f));
//// tb.attachDebugShape(assetManager);
// rootNode.attachChild(tb);
// getPhysicsSpace().add(tb);
// }
private Geometry findGeom(Spatial spatial, String name) {
if (spatial instanceof Node) {
Node node = (Node) spatial;
for (int i = 0; i < node.getQuantity(); i++) {
Spatial child = node.getChild(i);
Geometry result = findGeom(child, name);
if (result != null) {
return result;
}
}
} else if (spatial instanceof Geometry) {
if (spatial.getName().startsWith(name)) {
return (Geometry) spatial;
}
}
return null;
}
private void buildPlayer() {
float stiffness = 120.0f;//200=f1 car
float compValue = 0.2f; //(lower than damp!)
float dampValue = 0.3f;
final float mass = 400;
//Load model and get chassis Geometry
carNode = (Node)assetManager.loadModel("Models/Ferrari/Car.scene");
carNode.setShadowMode(ShadowMode.Cast);
Geometry chasis = findGeom(carNode, "Car");
BoundingBox box = (BoundingBox) chasis.getModelBound();
//Create a hull collision shape for the chassis
CollisionShape carHull = CollisionShapeFactory.createDynamicMeshShape(chasis);
//Create a vehicle control
player = new VehicleControl(carHull, mass);
carNode.addControl(player);
//Setting default values for wheels
player.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
player.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
player.setSuspensionStiffness(stiffness);
player.setMaxSuspensionForce(10000);
//Create four wheels and add them at their locations
//note that our fancy car actually goes backwards..
Vector3f wheelDirection = new Vector3f(0, -1, 0);
Vector3f wheelAxle = new Vector3f(-1, 0, 0);
Geometry wheel_fr = findGeom(carNode, "WheelFrontRight");
wheel_fr.center();
box = (BoundingBox) wheel_fr.getModelBound();
wheelRadius = box.getYExtent();
float back_wheel_h = (wheelRadius * 1.7f) - 1f;
float front_wheel_h = (wheelRadius * 1.9f) - 1f;
player.addWheel(wheel_fr.getParent(), box.getCenter().add(0, -front_wheel_h, 0),
wheelDirection, wheelAxle, 0.2f, wheelRadius, true);
Geometry wheel_fl = findGeom(carNode, "WheelFrontLeft");
wheel_fl.center();
box = (BoundingBox) wheel_fl.getModelBound();
player.addWheel(wheel_fl.getParent(), box.getCenter().add(0, -front_wheel_h, 0),
wheelDirection, wheelAxle, 0.2f, wheelRadius, true);
Geometry wheel_br = findGeom(carNode, "WheelBackRight");
wheel_br.center();
box = (BoundingBox) wheel_br.getModelBound();
player.addWheel(wheel_br.getParent(), box.getCenter().add(0, -back_wheel_h, 0),
wheelDirection, wheelAxle, 0.2f, wheelRadius, false);
Geometry wheel_bl = findGeom(carNode, "WheelBackLeft");
wheel_bl.center();
box = (BoundingBox) wheel_bl.getModelBound();
player.addWheel(wheel_bl.getParent(), box.getCenter().add(0, -back_wheel_h, 0),
wheelDirection, wheelAxle, 0.2f, wheelRadius, false);
player.getWheel(2).setFrictionSlip(4);
player.getWheel(3).setFrictionSlip(4);
rootNode.attachChild(carNode);
getPhysicsSpace().add(player);
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if (value) {
steeringValue += .5f;
} else {
steeringValue += -.5f;
}
player.steer(steeringValue);
} else if (binding.equals("Rights")) {
if (value) {
steeringValue += -.5f;
} else {
steeringValue += .5f;
}
player.steer(steeringValue);
} //note that our fancy car actually goes backwards..
else if (binding.equals("Ups")) {
if (value) {
accelerationValue -= 800;
} else {
accelerationValue += 800;
}
player.accelerate(accelerationValue);
player.setCollisionShape(CollisionShapeFactory.createDynamicMeshShape(findGeom(carNode, "Car")));
} else if (binding.equals("Downs")) {
if (value) {
player.brake(40f);
} else {
player.brake(0f);
}
} else if (binding.equals("Reset")) {
if (value) {
System.out.println("Reset");
player.setPhysicsLocation(Vector3f.ZERO);
player.setPhysicsRotation(new Matrix3f());
player.setLinearVelocity(Vector3f.ZERO);
player.setAngularVelocity(Vector3f.ZERO);
player.resetSuspension();
} else {
}
}
}
@Override
public void simpleUpdate(float tpf) {
cam.lookAt(carNode.getWorldTranslation(), Vector3f.UNIT_Y);
}
}

@ -0,0 +1,117 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
/**
*
* @author tim8dev [at] gmail [dot com]
*/
public class TestGhostObject extends SimpleApplication {
private BulletAppState bulletAppState;
private GhostControl ghostControl;
public static void main(String[] args) {
Application app = new TestGhostObject();
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
// Mesh to be shared across several boxes.
Box boxGeom = new Box(1f, 1f, 1f);
// CollisionShape to be shared across several boxes.
CollisionShape shape = new BoxCollisionShape(new Vector3f(1, 1, 1));
Node physicsBox = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1);
physicsBox.setName("box0");
physicsBox.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.6f, 4, .5f));
rootNode.attachChild(physicsBox);
getPhysicsSpace().add(physicsBox);
Node physicsBox1 = PhysicsTestHelper.createPhysicsTestNode(assetManager, shape, 1);
physicsBox1.setName("box1");
physicsBox1.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0, 40, 0));
rootNode.attachChild(physicsBox1);
getPhysicsSpace().add(physicsBox1);
Node physicsBox2 = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(1, 1, 1)), 1);
physicsBox2.setName("box0");
physicsBox2.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(.5f, 80, -.8f));
rootNode.attachChild(physicsBox2);
getPhysicsSpace().add(physicsBox2);
// the floor, does not move (mass=0)
Node node = PhysicsTestHelper.createPhysicsTestNode(assetManager, new BoxCollisionShape(new Vector3f(100, 1, 100)), 0);
node.setName("floor");
node.getControl(RigidBodyControl.class).setPhysicsLocation(new Vector3f(0f, -6, 0f));
rootNode.attachChild(node);
getPhysicsSpace().add(node);
initGhostObject();
}
private PhysicsSpace getPhysicsSpace(){
return bulletAppState.getPhysicsSpace();
}
private void initGhostObject() {
Vector3f halfExtents = new Vector3f(3, 4.2f, 1);
ghostControl = new GhostControl(new BoxCollisionShape(halfExtents));
Node node=new Node("Ghost Object");
node.addControl(ghostControl);
rootNode.attachChild(node);
getPhysicsSpace().add(ghostControl);
}
@Override
public void simpleUpdate(float tpf) {
fpsText.setText("Overlapping objects: " + ghostControl.getOverlappingObjects().toString());
}
}

@ -0,0 +1,301 @@
/*
* 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.*;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.system.AppSettings;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.SkyFactory;
import com.jme3.util.SkyFactory.EnvMapType;
import java.util.ArrayList;
import java.util.List;
public class TestHoveringTank extends SimpleApplication implements AnalogListener,
ActionListener {
private BulletAppState bulletAppState;
private PhysicsHoverControl hoverControl;
private Spatial spaceCraft;
TerrainQuad terrain;
Material matRock;
boolean wireframe = false;
protected BitmapText hintText;
PointLight pl;
Geometry lightMdl;
Geometry collisionMarker;
public static void main(String[] args) {
TestHoveringTank app = new TestHoveringTank();
app.start();
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private void setupKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, "Lefts");
inputManager.addListener(this, "Rights");
inputManager.addListener(this, "Ups");
inputManager.addListener(this, "Downs");
inputManager.addListener(this, "Space");
inputManager.addListener(this, "Reset");
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
// bulletAppState.getPhysicsSpace().enableDebug(assetManager);
bulletAppState.getPhysicsSpace().setAccuracy(1f/30f);
rootNode.attachChild(SkyFactory.createSky(assetManager,
"Textures/Sky/Bright/BrightSky.dds", EnvMapType.CubeMap));
DirectionalLightShadowRenderer dlsr
= new DirectionalLightShadowRenderer(assetManager, 2048, 3);
dlsr.setLambda(0.55f);
dlsr.setShadowIntensity(0.6f);
dlsr.setEdgeFilteringMode(EdgeFilteringMode.Bilinear);
viewPort.addProcessor(dlsr);
setupKeys();
createTerrain();
buildPlayer();
DirectionalLight dl = new DirectionalLight();
dlsr.setLight(dl);
dl.setColor(new ColorRGBA(1.0f, 0.94f, 0.8f, 1f).multLocal(1.3f));
dl.setDirection(new Vector3f(-0.5f, -0.3f, -0.3f).normalizeLocal());
rootNode.addLight(dl);
Vector3f lightDir2 = new Vector3f(0.70518064f, 0.5902297f, -0.39287305f);
DirectionalLight dl2 = new DirectionalLight();
dl2.setColor(new ColorRGBA(0.7f, 0.85f, 1.0f, 1f));
dl2.setDirection(lightDir2);
rootNode.addLight(dl2);
}
private void buildPlayer() {
spaceCraft = assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml");
CollisionShape colShape = CollisionShapeFactory.createDynamicMeshShape(spaceCraft);
spaceCraft.setShadowMode(ShadowMode.CastAndReceive);
spaceCraft.setLocalTranslation(new Vector3f(-140, 50, -23));
spaceCraft.setLocalRotation(new Quaternion(new float[]{0, 0.01f, 0}));
hoverControl = new PhysicsHoverControl(colShape, 500);
spaceCraft.addControl(hoverControl);
rootNode.attachChild(spaceCraft);
getPhysicsSpace().add(hoverControl);
hoverControl.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_02);
ChaseCamera chaseCam = new ChaseCamera(cam, inputManager);
spaceCraft.addControl(chaseCam);
flyCam.setEnabled(false);
}
public void makeMissile() {
Vector3f pos = spaceCraft.getWorldTranslation().clone();
Quaternion rot = spaceCraft.getWorldRotation();
Vector3f dir = rot.getRotationColumn(2);
Spatial missile = assetManager.loadModel("Models/SpaceCraft/Rocket.mesh.xml");
missile.scale(0.5f);
missile.rotate(0, FastMath.PI, 0);
missile.updateGeometricState();
BoundingBox box = (BoundingBox) missile.getWorldBound();
final Vector3f extent = box.getExtent(null);
BoxCollisionShape boxShape = new BoxCollisionShape(extent);
missile.setName("Missile");
missile.rotate(rot);
missile.setLocalTranslation(pos.addLocal(0, extent.y * 4.5f, 0));
missile.setLocalRotation(hoverControl.getPhysicsRotation());
missile.setShadowMode(ShadowMode.Cast);
RigidBodyControl control = new BombControl(assetManager, boxShape, 20);
control.setLinearVelocity(dir.mult(100));
control.setCollisionGroup(PhysicsCollisionObject.COLLISION_GROUP_03);
missile.addControl(control);
rootNode.attachChild(missile);
getPhysicsSpace().add(missile);
}
public void onAnalog(String binding, float value, float tpf) {
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
hoverControl.steer(value ? 50f : 0);
} else if (binding.equals("Rights")) {
hoverControl.steer(value ? -50f : 0);
} else if (binding.equals("Ups")) {
hoverControl.accelerate(value ? 100f : 0);
} else if (binding.equals("Downs")) {
hoverControl.accelerate(value ? -100f : 0);
} else if (binding.equals("Reset")) {
if (value) {
System.out.println("Reset");
hoverControl.setPhysicsLocation(new Vector3f(-140, 14, -23));
hoverControl.setPhysicsRotation(new Matrix3f());
hoverControl.clearForces();
} else {
}
} else if (binding.equals("Space") && value) {
makeMissile();
}
}
public void updateCamera() {
rootNode.updateGeometricState();
Vector3f pos = spaceCraft.getWorldTranslation().clone();
Quaternion rot = spaceCraft.getWorldRotation();
Vector3f dir = rot.getRotationColumn(2);
// make it XZ only
Vector3f camPos = new Vector3f(dir);
camPos.setY(0);
camPos.normalizeLocal();
// negate and multiply by distance from object
camPos.negateLocal();
camPos.multLocal(15);
// add Y distance
camPos.setY(2);
camPos.addLocal(pos);
cam.setLocation(camPos);
Vector3f lookAt = new Vector3f(dir);
lookAt.multLocal(7); // look at dist
lookAt.addLocal(pos);
cam.lookAt(lookAt, Vector3f.UNIT_Y);
}
@Override
public void simpleUpdate(float tpf) {
}
private void createTerrain() {
matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
matRock.setBoolean("useTriPlanarMapping", false);
matRock.setBoolean("WardIso", true);
matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap", grass);
matRock.setFloat("DiffuseMap_0_scale", 64);
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap_1", dirt);
matRock.setFloat("DiffuseMap_1_scale", 16);
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
matRock.setTexture("DiffuseMap_2", rock);
matRock.setFloat("DiffuseMap_2_scale", 128);
Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
normalMap0.setWrap(WrapMode.Repeat);
Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
normalMap1.setWrap(WrapMode.Repeat);
Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png");
normalMap2.setWrap(WrapMode.Repeat);
matRock.setTexture("NormalMap", normalMap0);
matRock.setTexture("NormalMap_1", normalMap2);
matRock.setTexture("NormalMap_2", normalMap2);
AbstractHeightMap heightmap = null;
try {
heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
heightmap.load();
} catch (Exception e) {
e.printStackTrace();
}
terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
List<Camera> cameras = new ArrayList<Camera>();
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);
terrain.setMaterial(matRock);
terrain.setLocalScale(new Vector3f(2, 2, 2));
terrain.setLocked(false); // unlock it so we can edit the height
terrain.setShadowMode(ShadowMode.CastAndReceive);
terrain.addControl(new RigidBodyControl(0));
rootNode.attachChild(terrain);
getPhysicsSpace().addAll(terrain);
}
}

@ -0,0 +1,93 @@
/*
* Copyright (c) 2009-2010 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 jme3test.bullet;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.Bone;
import com.jme3.bullet.collision.RagdollCollisionListener;
import com.jme3.bullet.control.KinematicRagdollControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
/**
* @author reden
*/
public class TestIK extends TestBoneRagdoll implements RagdollCollisionListener, AnimEventListener {
Node targetNode = new Node("");
Vector3f targetPoint;
Bone mouseBone;
Vector3f oldMousePos;
public static void main(String[] args) {
TestIK app = new TestIK();
app.start();
}
@Override
public void simpleInitApp() {
super.simpleInitApp();
final KinematicRagdollControl ikControl = model.getControl(KinematicRagdollControl.class);
inputManager.addListener(new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("stop") && isPressed) {
ikControl.setEnabled(!ikControl.isEnabled());
ikControl.setIKMode();
}
if (name.equals("one") && isPressed) {
//ragdoll.setKinematicMode();
targetPoint = model.getWorldTranslation().add(new Vector3f(0,2,4));
targetNode.setLocalTranslation(targetPoint);
ikControl.setIKTarget(ikControl.getBone("Hand.L"), targetPoint, 2);
ikControl.setIKMode();
}
if (name.equals("two") && isPressed) {
//ragdoll.setKinematicMode();
targetPoint = model.getWorldTranslation().add(new Vector3f(-3,3,0));
targetNode.setLocalTranslation(targetPoint);
ikControl.setIKTarget(ikControl.getBone("Hand.R"), targetPoint, 3);
ikControl.setIKMode();
}
}
}, "one", "two");
inputManager.addMapping("one", new KeyTrigger(KeyInput.KEY_1));
inputManager.addMapping("two", new KeyTrigger(KeyInput.KEY_2));
inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H));
}
}

@ -0,0 +1,148 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
/**
* Test case for JME issue #877: multiple hinges. Based on code submitted by
* Daniel Martensson.
*
* If successful, all pendulums will swing at the same frequency, and all the
* free-falling objects will fall straight down.
*/
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.joints.HingeJoint;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
public class TestIssue877 extends SimpleApplication {
BulletAppState bulletAppState = new BulletAppState();
int numPendulums = 6;
int numFalling = 6;
Node pivots[] = new Node[numPendulums];
Node bobs[] = new Node[numPendulums];
Node falling[] = new Node[numFalling];
float timeToNextPrint = 1f; // in seconds
public static void main(String[] args) {
TestIssue877 app = new TestIssue877();
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setEnabled(false);
cam.setLocation(new Vector3f(-4.77f, -7.55f, 16.52f));
cam.setRotation(new Quaternion(-0.103433f, 0.889420f, 0.368792f, 0.249449f));
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
float pivotY = 14.6214f;
float bobStartY = 3f;
float length = pivotY - bobStartY;
for (int i = 0; i < numPendulums; i++) {
float x = 6f - 2.5f * i;
Vector3f pivotLocation = new Vector3f(x, pivotY, 0f);
pivots[i] = createTestNode(0f, pivotLocation);
Vector3f bobLocation = new Vector3f(x, bobStartY, 0f);
bobs[i] = createTestNode(1f, bobLocation);
}
for (int i = 0; i < numFalling; i++) {
float x = -6f - 2.5f * (i + numPendulums);
Vector3f createLocation = new Vector3f(x, bobStartY, 0f);
falling[i] = createTestNode(1f, createLocation);
}
for (int i = 0; i < numPendulums; i++) {
HingeJoint joint = new HingeJoint(
pivots[i].getControl(RigidBodyControl.class),
bobs[i].getControl(RigidBodyControl.class),
new Vector3f(0f, 0f, 0f),
new Vector3f(length, 0f, 0f),
Vector3f.UNIT_Z.clone(),
Vector3f.UNIT_Z.clone());
bulletAppState.getPhysicsSpace().add(joint);
}
}
Node createTestNode(float mass, Vector3f location) {
float size = 0.1f;
Vector3f halfExtents = new Vector3f(size, size, size);
CollisionShape shape = new BoxCollisionShape(halfExtents);
RigidBodyControl control = new RigidBodyControl(shape, mass);
Node node = new Node();
node.addControl(control);
rootNode.attachChild(node);
bulletAppState.getPhysicsSpace().add(node);
control.setPhysicsLocation(location);
return node;
}
@Override
public void simpleUpdate(float tpf) {
if (timeToNextPrint > 0f) {
timeToNextPrint -= tpf;
return;
}
if (numFalling > 0) {
Vector3f fallingLocation = falling[0].getWorldTranslation();
System.out.printf(" falling[0] location(x=%f, z=%f)",
fallingLocation.x, fallingLocation.z);
/*
* If an object is falling vertically, its X- and Z-coordinates
* should not change.
*/
}
if (numPendulums > 0) {
Vector3f bobLocation = bobs[0].getWorldTranslation();
Vector3f pivotLocation = pivots[0].getWorldTranslation();
float distance = bobLocation.distance(pivotLocation);
System.out.printf(" bob[0] distance=%f", distance);
/*
* If the hinge is working properly, the distance from the
* pivot to the bob should remain roughly constant.
*/
}
System.out.println();
timeToNextPrint = 1f;
}
}

@ -0,0 +1,87 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
/**
* Test case for JME issue #883: extra physicsTicks in ThreadingType.PARALLEL.
*
* If successful, physics time and frame time will advance at the same rate.
*/
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
public class TestIssue883 extends SimpleApplication {
boolean firstPrint = true;
float timeToNextPrint = 1f; // in seconds
double frameTime; // in seconds
double physicsTime; // in seconds
public static void main(String[] args) {
TestIssue883 app = new TestIssue883();
app.start();
}
@Override
public void simpleInitApp() {
BulletAppState bulletAppState = new BulletAppState() {
@Override
public void physicsTick(PhysicsSpace space, float timeStep) {
physicsTime += timeStep;
}
};
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
}
@Override
public void simpleUpdate(float tpf) {
frameTime += tpf;
if (timeToNextPrint > 0f) {
timeToNextPrint -= tpf;
return;
}
if (firstPrint) { // synchronize
frameTime = 0.;
physicsTime = 0.;
firstPrint = false;
}
System.out.printf(" frameTime= %s physicsTime= %s%n",
frameTime, physicsTime);
timeToNextPrint = 1f;
}
}

@ -0,0 +1,87 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
/**
* Test case for JME issue #889: disabled physics control gets added to a
* physics space.
* <p>
* If successful, no debug meshes will be visible.
*/
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.GhostControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.Vector3f;
public class TestIssue889 extends SimpleApplication {
public static void main(String[] args) {
TestIssue889 app = new TestIssue889();
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setEnabled(false);
BulletAppState bulletAppState = new BulletAppState();
bulletAppState.setDebugEnabled(true);
bulletAppState.setSpeed(0f);
stateManager.attach(bulletAppState);
PhysicsSpace space = bulletAppState.getPhysicsSpace();
float radius = 1f;
CollisionShape sphere = new SphereCollisionShape(radius);
CollisionShape box = new BoxCollisionShape(Vector3f.UNIT_XYZ);
RigidBodyControl rbc = new RigidBodyControl(box);
rbc.setEnabled(false);
rbc.setPhysicsSpace(space);
rootNode.addControl(rbc);
BetterCharacterControl bcc = new BetterCharacterControl(radius, 4f, 1f);
bcc.setEnabled(false);
bcc.setPhysicsSpace(space);
rootNode.addControl(bcc);
GhostControl gc = new GhostControl(sphere);
gc.setEnabled(false);
gc.setPhysicsSpace(space);
rootNode.addControl(gc);
}
}

@ -0,0 +1,81 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.joints.Point2PointJoint;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.math.Vector3f;
/**
* Test case for JME issue #918: Point2PointJoint.getImpulseClamp() and
* .getTau() return the damping value instead. The bug existed in Native Bullet
* only.
* <p>
* If successful, no UnsatisfiedLinkError exception will be thrown.
*/
public class TestIssue918 extends SimpleApplication {
// *************************************************************************
// new methods exposed
public static void main(String[] args) {
TestIssue918 app = new TestIssue918();
app.start();
}
// *************************************************************************
// SimpleApplication methods
@Override
public void simpleInitApp() {
CollisionShape capsule = new SphereCollisionShape(1f);
PhysicsRigidBody body1 = new PhysicsRigidBody(capsule, 1f);
PhysicsRigidBody body2 = new PhysicsRigidBody(capsule, 1f);
Vector3f pivot1 = new Vector3f();
Vector3f pivot2 = new Vector3f();
Point2PointJoint joint
= new Point2PointJoint(body1, body2, pivot1, pivot2);
joint.setImpulseClamp(42f);
joint.setTau(99f);
if (joint.getImpulseClamp() != 42f) {
throw new RuntimeException();
}
if (joint.getTau() != 99f) {
throw new RuntimeException();
}
stop();
}
}

@ -0,0 +1,72 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.joints.SixDofJoint;
import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.math.Vector3f;
/**
* Test case for JME issue #919: native implementation of
* TranslationalLimitMotor.getLimitSoftness() has wrong name. The bug existed in
* Native Bullet only.
* <p>
* If successful, no UnsatisfiedLinkError exception will be thrown.
*/
public class TestIssue919 extends SimpleApplication {
// *************************************************************************
// new methods exposed
public static void main(String[] args) {
TestIssue919 app = new TestIssue919();
app.start();
}
// *************************************************************************
// SimpleApplication methods
@Override
public void simpleInitApp() {
CollisionShape capsule = new SphereCollisionShape(1f);
PhysicsRigidBody body1 = new PhysicsRigidBody(capsule, 1f);
PhysicsRigidBody body2 = new PhysicsRigidBody(capsule, 1f);
Vector3f pivot1 = new Vector3f();
Vector3f pivot2 = new Vector3f();
SixDofJoint joint = new SixDofJoint(body1, body2, pivot1, pivot2, true);
joint.getTranslationalLimitMotor().getLimitSoftness();
stop();
}
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2018 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 jme3test.bullet;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.BulletAppState.ThreadingType;
/**
* Test case for JME issue #928: crash after 64 attached and detached
* BulletAppStates with parallel threading. The bug existed in Native Bullet
* only.
* <p>
* If successful, no crash will occur.
*/
public class TestIssue928 extends SimpleApplication {
// *************************************************************************
// new methods exposed
public static void main(String[] args) {
TestIssue928 app = new TestIssue928();
app.start();
}
int count = 0;
int frame = 0;
BulletAppState bulletAppState;
// *************************************************************************
// SimpleApplication methods
@Override
public void simpleInitApp() {
}
@Override
public void simpleUpdate(float tpf) {
if (frame % 4 == 0) {
System.out.println(++count);
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
} else if (frame % 4 == 2) {
stateManager.detach(bulletAppState);
}
frame++;
if (count == 70) {
System.exit(0);
}
}
}

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

Loading…
Cancel
Save