Merged with master after pull.

cleanup_build_scripts
Daniel Johansson 9 years ago
commit e530fa644b
  1. 5
      .travis.yml
  2. 29
      bintray.gradle
  3. 8
      build.gradle
  4. 61
      common.gradle
  5. 5
      gradle.properties
  6. 11
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/BlenderContext.java
  7. 104
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Edge.java
  8. 155
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java
  9. 6
      jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/SphereCollisionShape.java
  10. 18
      jme3-core/src/main/java/com/jme3/animation/Bone.java
  11. 31
      jme3-core/src/main/java/com/jme3/app/Application.java
  12. 2
      jme3-core/src/main/java/com/jme3/asset/AssetKey.java
  13. 38
      jme3-core/src/main/java/com/jme3/audio/AudioNode.java
  14. 11
      jme3-core/src/main/java/com/jme3/collision/bih/BIHTree.java
  15. 11
      jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java
  16. 9
      jme3-core/src/main/java/com/jme3/input/KeyInput.java
  17. 8
      jme3-core/src/main/java/com/jme3/input/KeyNames.java
  18. 8
      jme3-core/src/main/java/com/jme3/light/DirectionalLight.java
  19. 6
      jme3-core/src/main/java/com/jme3/light/Light.java
  20. 9
      jme3-core/src/main/java/com/jme3/light/PointLight.java
  21. 10
      jme3-core/src/main/java/com/jme3/light/SpotLight.java
  22. 35
      jme3-core/src/main/java/com/jme3/material/MatParam.java
  23. 2
      jme3-core/src/main/java/com/jme3/material/Material.java
  24. 119
      jme3-core/src/main/java/com/jme3/scene/BatchNode.java
  25. 2
      jme3-core/src/main/java/com/jme3/scene/Geometry.java
  26. 2
      jme3-core/src/main/java/com/jme3/scene/GeometryGroupNode.java
  27. 5
      jme3-core/src/main/java/com/jme3/scene/Node.java
  28. 2
      jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java
  29. 3
      jme3-core/src/main/java/com/jme3/scene/shape/Cylinder.java
  30. 2
      jme3-core/src/main/java/com/jme3/system/AppSettings.java
  31. 61
      jme3-core/src/main/java/com/jme3/util/BufferUtils.java
  32. 97
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java
  33. 100
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikkTSpaceImpl.java
  34. 1717
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java
  35. 5
      jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.vert
  36. 19
      jme3-core/src/main/resources/joystick-mapping.properties
  37. 2
      jme3-core/src/tools/java/jme3tools/optimize/TextureAtlas.java
  38. 2
      jme3-desktop/src/main/java/com/jme3/app/SettingsDialog.java
  39. 2
      jme3-effects/src/main/resources/Common/MatDefs/SSAO/normal.vert
  40. 14
      jme3-examples/build.gradle
  41. 72
      jme3-examples/src/main/java/jme3test/app/TestEnqueueRunnable.java
  42. 2
      jme3-jbullet/src/main/java/com/jme3/bullet/objects/PhysicsVehicle.java
  43. 5
      jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java
  44. 67
      jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
  45. 12
      jme3-lwjgl3/build.gradle
  46. BIN
      jme3-lwjgl3/lib/lwjgl-3.0.0b-35-natives.jar
  47. BIN
      jme3-lwjgl3/lib/lwjgl-3.0.0b-35.jar
  48. 40
      jme3-lwjgl3/src/main/java/com/jme3/audio/lwjgl/LwjglALC.java
  49. 3
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyInput.java
  50. 171
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyMap.java
  51. 138
      jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwMouseInput.java
  52. 57
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
  53. 155
      jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java
  54. 55
      jme3-networking/src/main/java/com/jme3/network/base/DefaultClient.java
  55. 2
      jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java
  56. 8
      jme3-networking/src/main/java/com/jme3/network/base/KernelAdapter.java
  57. 2
      jme3-networking/src/main/java/com/jme3/network/base/MessageProtocol.java
  58. 12
      jme3-networking/src/main/java/com/jme3/network/kernel/AbstractKernel.java
  59. 13
      jme3-networking/src/main/java/com/jme3/network/kernel/tcp/SelectorKernel.java
  60. 13
      jme3-networking/src/main/java/com/jme3/network/kernel/udp/UdpKernel.java
  61. 8
      jme3-networking/src/main/java/com/jme3/network/message/SerializerRegistrationsMessage.java
  62. 16
      jme3-networking/src/main/java/com/jme3/network/serializing/Serializer.java
  63. 5
      jme3-networking/src/main/java/com/jme3/network/serializing/serializers/EnumSerializer.java
  64. 37
      jme3-networking/src/main/java/com/jme3/network/serializing/serializers/FieldSerializer.java
  65. 5
      jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiRegistry.java
  66. 1
      sdk/BasicGameTemplate/MANIFEST.MF
  67. 0
      sdk/BasicGameTemplate/assets/Interface/.keep
  68. 0
      sdk/BasicGameTemplate/assets/MatDefs/.keep
  69. 0
      sdk/BasicGameTemplate/assets/Materials/.keep
  70. 0
      sdk/BasicGameTemplate/assets/Models/.keep
  71. 0
      sdk/BasicGameTemplate/assets/Scenes/.keep
  72. 0
      sdk/BasicGameTemplate/assets/Shaders/.keep
  73. 0
      sdk/BasicGameTemplate/assets/Sounds/.keep
  74. 0
      sdk/BasicGameTemplate/assets/Textures/.keep
  75. 76
      sdk/BasicGameTemplate/build.xml
  76. 22
      sdk/BasicGameTemplate/master-application.jnlp
  77. 8
      sdk/BasicGameTemplate/nbproject/genfiles.properties
  78. 92
      sdk/BasicGameTemplate/nbproject/project.properties
  79. 18
      sdk/BasicGameTemplate/nbproject/project.xml
  80. 43
      sdk/BasicGameTemplate/src/mygame/Main.java
  81. 73
      sdk/JME3TestsTemplate/build.xml
  82. 880
      sdk/JME3TestsTemplate/nbproject/build-impl.xml
  83. 8
      sdk/JME3TestsTemplate/nbproject/genfiles.properties
  84. 83
      sdk/JME3TestsTemplate/nbproject/project.properties
  85. 13
      sdk/JME3TestsTemplate/nbproject/project.xml
  86. 1
      sdk/JME3TestsTemplateAndroid/MANIFEST.MF
  87. 76
      sdk/JME3TestsTemplateAndroid/build.xml
  88. 22
      sdk/JME3TestsTemplateAndroid/master-application.jnlp
  89. 15
      sdk/JME3TestsTemplateAndroid/mobile/AndroidManifest.xml
  90. 17
      sdk/JME3TestsTemplateAndroid/mobile/ant.properties
  91. 92
      sdk/JME3TestsTemplateAndroid/mobile/build.xml
  92. 20
      sdk/JME3TestsTemplateAndroid/mobile/proguard-project.txt
  93. 14
      sdk/JME3TestsTemplateAndroid/mobile/project.properties
  94. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/monkey256.png
  95. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/monkey256_9.9.png
  96. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/monkey512.png
  97. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/monkey512_9.9.png
  98. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/nonselected.png
  99. BIN
      sdk/JME3TestsTemplateAndroid/mobile/res/drawable/selected.png
  100. 13
      sdk/JME3TestsTemplateAndroid/mobile/res/layout/main.xml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -25,7 +25,6 @@ install:
script:
- ./gradlew check
- ./gradlew createZipDistribution
- "[ $TRAVIS_BRANCH == 'master' ] && [ $TRAVIS_PULL_REQUEST == 'false' ] && ./gradlew uploadArchives || :"
before_deploy:
- export RELEASE_DIST=$(ls build/distributions/*.zip)
@ -54,3 +53,7 @@ before_install:
# wget http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin -O ndk.bin
# 7z x ndk.bin -y > /dev/null
# export ANDROID_NDK=`pwd`/android-ndk-r10c
after_success:
- '[ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives || :'
- '[ -n "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && ./gradlew uploadArchives bintrayUpload || :'

@ -0,0 +1,29 @@
//
// This file is to be applied to some subproject.
//
apply plugin: 'com.jfrog.bintray'
bintray {
user = bintray_user
key = bintray_api_key
configurations = ['archives']
dryRun = false
pkg {
repo = 'org.jmonkeyengine'
userOrg = 'jmonkeyengine'
name = project.name
desc = POM_DESCRIPTION
websiteUrl = POM_URL
licenses = ['BSD New']
vcsUrl = POM_SCM_URL
labels = ['jmonkeyengine']
}
}
bintrayUpload.dependsOn(writeFullPom)
bintrayUpload.onlyIf {
(bintray_api_key.length() > 0) &&
!(version ==~ /.*SNAPSHOT/)
}

@ -2,10 +2,11 @@ import org.gradle.api.artifacts.*
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.5'
}
}
@ -17,6 +18,9 @@ apply from: file('upload.gradle')
subprojects {
if(!project.name.equals('jme3-android-examples')) {
apply from: rootProject.file('common.gradle')
if (!['jme3-testdata', 'sdk'].contains(project.name)) {
apply from: rootProject.file('bintray.gradle')
}
} else {
apply from: rootProject.file('common-android-app.gradle')
}
@ -87,6 +91,8 @@ task mergedJavadoc(type: Javadoc, description: 'Creates Javadoc from all the pro
title = 'jMonkeyEngine3'
destinationDir = mkdir("dist/javadoc")
options.encoding = 'UTF-8'
// Allows Javadoc to be generated on Java 8 despite doclint errors.
if (JavaVersion.current().isJava8Compatible()) {
options.addStringOption('Xdoclint:none', '-quiet')

@ -5,7 +5,7 @@
apply plugin: 'java'
apply plugin: 'maven'
group = 'com.jme3'
group = 'org.jmonkeyengine'
version = jmePomVersion
sourceCompatibility = '1.6'
@ -61,12 +61,53 @@ task javadocJar(type: Jar, dependsOn: javadoc, description: 'Creates a jar from
from javadoc.destinationDir
}
def pomConfig = {
name POM_NAME
description POM_DESCRIPTION
url POM_URL
inceptionYear '2016'
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEVELOPER_CONNECTION
}
licenses {
license {
name POM_LICENSE_NAME
url POM_LICENSE_URL
distribution POM_LICENSE_DISTRIBUTION
}
}
// from http://hub.jmonkeyengine.org/introduction/team/
developers {
developer {
name 'jMonkeyEngine Team'
id 'jMonkeyEngine'
}
}
}
// workaround to be able to use same custom pom with 'maven' and 'bintray' plugin
task writeFullPom {
ext.pomFile = "$mavenPomDir/${project.name}-${project.version}.pom"
outputs.file pomFile
doLast {
pom {
project pomConfig
}.writeTo(pomFile)
}
}
assemble.dependsOn(writeFullPom)
install.dependsOn(writeFullPom)
uploadArchives.dependsOn(writeFullPom)
artifacts {
archives jar
archives sourcesJar
if(buildJavaDoc == "true"){
archives javadocJar
}
archives writeFullPom.outputs.files[0]
}
uploadArchives {
@ -80,23 +121,7 @@ uploadArchives {
authentication(userName: "www-updater", privateKey: "private/www-updater.key")
}
pom.project {
name POM_NAME
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEVELOPER_CONNECTION
}
licenses {
license {
name POM_LICENSE_NAME
url POM_LICENSE_URL
distribution POM_LICENSE_DISTRIBUTION
}
}
}
pom.project pomConfig
}
}

@ -11,7 +11,6 @@ jmeVersionTagID = 0
buildJavaDoc = true
# specify if SDK and Native libraries get built
buildSdkProject = true
buildNativeProjects = false
buildAndroidExamples = false
@ -37,3 +36,7 @@ POM_SCM_DEVELOPER_CONNECTION=scm:git:git@github.com:jMonkeyEngine/jmonkeyengine.
POM_LICENSE_NAME=New BSD (3-clause) License
POM_LICENSE_URL=http://opensource.org/licenses/BSD-3-Clause
POM_LICENSE_DISTRIBUTION=repo
# Bintray settings to override in $HOME/.gradle/gradle.properties or ENV or commandline
bintray_user=
bintray_api_key=

@ -59,6 +59,7 @@ import com.jme3.scene.plugins.blender.file.FileBlockHeader;
import com.jme3.scene.plugins.blender.file.FileBlockHeader.BlockCode;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.materials.MaterialContext;
import com.jme3.scene.plugins.blender.meshes.TemporalMesh;
import com.jme3.texture.Texture;
/**
@ -389,11 +390,11 @@ public class BlenderContext {
}
}
} else if("ME".equals(namePrefix)) {
List<Node> features = (List<Node>) linkedFeatures.get("meshes");
if(features != null) {
for(Node feature : features) {
if(featureName.equals(feature.getName())) {
return feature;
List<TemporalMesh> temporalMeshes = (List<TemporalMesh>) linkedFeatures.get("meshes");
if(temporalMeshes != null) {
for(TemporalMesh temporalMesh : temporalMeshes) {
if(featureName.equals(temporalMesh.getName())) {
return temporalMesh;
}
}
}

@ -10,6 +10,7 @@ import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.file.BlenderFileException;
import com.jme3.scene.plugins.blender.file.Pointer;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.math.Vector3d;
import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate;
/**
@ -24,6 +25,8 @@ public class Edge {
/** The vertices indexes. */
private int index1, index2;
/** The vertices that can be set if we need and abstract edge outside the mesh (for computations). */
private Vector3f v1, v2;
/** The weight of the edge. */
private float crease;
/** A variable that indicates if this edge belongs to any face or not. */
@ -31,6 +34,13 @@ public class Edge {
/** The mesh that owns the edge. */
private TemporalMesh temporalMesh;
public Edge(Vector3f v1, Vector3f v2) {
this.v1 = v1 == null ? new Vector3f() : v1;
this.v2 = v2 == null ? new Vector3f() : v2;
index1 = 0;
index2 = 1;
}
/**
* This constructor only stores the indexes of the vertices. The position vertices should be stored
* outside this class.
@ -74,14 +84,14 @@ public class Edge {
* @return the first vertex of the edge
*/
public Vector3f getFirstVertex() {
return temporalMesh.getVertices().get(index1);
return temporalMesh == null ? v1 : temporalMesh.getVertices().get(index1);
}
/**
* @return the second vertex of the edge
*/
public Vector3f getSecondVertex() {
return temporalMesh.getVertices().get(index2);
return temporalMesh == null ? v2 : temporalMesh.getVertices().get(index2);
}
/**
@ -188,28 +198,82 @@ public class Edge {
* @return <b>true</b> if the edges cross and false otherwise
*/
public boolean cross(Edge edge) {
Vector3f P1 = this.getFirstVertex();
Vector3f P2 = edge.getFirstVertex();
Vector3f u = this.getSecondVertex().subtract(P1);
Vector3f v = edge.getSecondVertex().subtract(P2);
float t2 = (u.x * (P2.y - P1.y) - u.y * (P2.x - P1.x)) / (u.y * v.x - u.x * v.y);
float t1 = (P2.x - P1.x + v.x * t2) / u.x;
Vector3f p1 = P1.add(u.mult(t1));
Vector3f p2 = P2.add(v.mult(t2));
if (p1.distance(p2) <= FastMath.FLT_EPSILON) {
// the lines cross, check if p1 and p2 are within the edges
Vector3f p = p1.subtract(P1);
float cos = p.dot(u) / (p.length() * u.length());
if (cos > 0 && p.length() <= u.length()) {
return this.getCrossPoint(edge) != null;
}
/**
* The method computes the crossing pint of this edge and another edge. If
* there is no crossing then null is returned.
*
* @param edge
* the edge to compute corss point with
* @return cross point on null if none exist
*/
public Vector3f getCrossPoint(Edge edge) {
return this.getCrossPoint(edge, false, false);
}
/**
* The method computes the crossing pint of this edge and another edge. If
* there is no crossing then null is returned. This method also allows to
* get the crossing point of the straight lines that contain these edges if
* you set the 'extend' parameter to true.
*
* @param edge
* the edge to compute corss point with
* @param extendThisEdge
* set to <b>true</b> to find a crossing point along the whole
* straight that contains the current edge
* @param extendSecondEdge
* set to <b>true</b> to find a crossing point along the whole
* straight that contains the given edge
* @return cross point on null if none exist
*/
public Vector3f getCrossPoint(Edge edge, boolean extendThisEdge, boolean extendSecondEdge) {
Vector3d P1 = new Vector3d(this.getFirstVertex());
Vector3d P2 = new Vector3d(edge.getFirstVertex());
Vector3d u = new Vector3d(this.getSecondVertex()).subtract(P1).normalizeLocal();
Vector3d v = new Vector3d(edge.getSecondVertex()).subtract(P2).normalizeLocal();
double t1 = 0, t2 = 0;
if(u.x == 0 && v.x == 0) {
t2 = (u.z * (P2.y - P1.y) - u.y * (P2.z - P1.z)) / (u.y * v.z - u.z * v.y);
t1 = (P2.z - P1.z + v.z * t2) / u.z;
} else if(u.y == 0 && v.y == 0) {
t2 = (u.x * (P2.z - P1.z) - u.z * (P2.x - P1.x)) / (u.z * v.x - u.x * v.z);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
} else if(u.z == 0 && v.z == 0) {
t2 = (u.x * (P2.y - P1.y) - u.y * (P2.x - P1.x)) / (u.y * v.x - u.x * v.y);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
} else {
t2 = (P1.y * u.x - P1.x * u.y + P2.x * u.y - P2.y * u.x) / (v.y * u.x - u.y * v.x);
t1 = (P2.x - P1.x + v.x * t2) / u.x;
if(Math.abs(P1.z - P2.z + u.z * t1 - v.z * t2) > FastMath.FLT_EPSILON) {
return null;
}
}
Vector3d p1 = P1.add(u.mult(t1));
Vector3d p2 = P2.add(v.mult(t2));
if (p1.distance(p2) <= FastMath.FLT_EPSILON) {
if(extendThisEdge && extendSecondEdge) {
return p1.toVector3f();
}
// the lines cross, check if p1 and p2 are within the edges
Vector3d p = p1.subtract(P1);
double cos = p.dot(u) / p.length();
if (extendThisEdge || p.length()<= FastMath.FLT_EPSILON || cos >= 1 - FastMath.FLT_EPSILON && p.length() <= this.getLength()) {
// p1 is inside the first edge, lets check the other edge now
p = p2.subtract(P2);
cos = p.dot(v) / (p.length() * v.length());
return cos > 0 && p.length() <= u.length();
cos = p.dot(v) / p.length();
if(extendSecondEdge || p.length()<= FastMath.FLT_EPSILON || cos >= 1 - FastMath.FLT_EPSILON && p.length() <= edge.getLength()) {
return p1.toVector3f();
}
}
}
return false;
}
return null;
}
@Override
public String toString() {

@ -276,30 +276,45 @@ public class Face implements Comparator<Integer> {
List<Face> facesToTriangulate = new ArrayList<Face>(Arrays.asList(this.clone()));
while (facesToTriangulate.size() > 0) {
Face face = facesToTriangulate.remove(0);
int previousIndex1 = -1, previousIndex2 = -1, previousIndex3 = -1;
while (face.vertexCount() > 0) {
indexes[0] = face.getIndex(0);
indexes[1] = face.findClosestVertex(indexes[0], -1);
indexes[2] = face.findClosestVertex(indexes[0], indexes[1]);
LOGGER.finer("Veryfying improper triangulation of the temporal mesh.");
if (indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) {
throw new BlenderFileException("Unable to find two closest vertices while triangulating face in mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!");
}
if (previousIndex1 == indexes[0] && previousIndex2 == indexes[1] && previousIndex3 == indexes[2]) {
throw new BlenderFileException("Infinite loop detected during triangulation of mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!");
}
previousIndex1 = indexes[0];
previousIndex2 = indexes[1];
previousIndex3 = indexes[2];
// two special cases will improve the computations speed
if(face.getIndexes().size() == 3) {
triangulatedFaces.add(face.getIndexes().clone());
} else if(face.getIndexes().size() == 4) {
// in case face has 4 verts we use the plain triangulation
indexes[0] = face.getIndex(0);
indexes[1] = face.getIndex(1);
indexes[2] = face.getIndex(2);
triangulatedFaces.add(new IndexesLoop(indexes));
indexes[1] = face.getIndex(2);
indexes[2] = face.getIndex(3);
triangulatedFaces.add(new IndexesLoop(indexes));
} else {
int previousIndex1 = -1, previousIndex2 = -1, previousIndex3 = -1;
while (face.vertexCount() > 0) {
indexes[0] = face.getIndex(0);
indexes[1] = face.findClosestVertex(indexes[0], -1);
indexes[2] = face.findClosestVertex(indexes[0], indexes[1]);
LOGGER.finer("Veryfying improper triangulation of the temporal mesh.");
if (indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) {
throw new BlenderFileException("Unable to find two closest vertices while triangulating face in mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!");
}
if (previousIndex1 == indexes[0] && previousIndex2 == indexes[1] && previousIndex3 == indexes[2]) {
throw new BlenderFileException("Infinite loop detected during triangulation of mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!");
}
previousIndex1 = indexes[0];
previousIndex2 = indexes[1];
previousIndex3 = indexes[2];
Arrays.sort(indexes, this);
facesToTriangulate.addAll(face.detachTriangle(indexes));
triangulatedFaces.add(new IndexesLoop(indexes));
Arrays.sort(indexes, this);
facesToTriangulate.addAll(face.detachTriangle(indexes));
triangulatedFaces.add(new IndexesLoop(indexes));
}
}
}
} catch (BlenderFileException e) {
LOGGER.log(Level.WARNING, "Errors occured during face triangulation: {0}. The face will be triangulated with the most direct algorithm, " + "but the results might not be identical to blender.", e.getLocalizedMessage());
LOGGER.log(Level.WARNING, "Errors occured during face triangulation: {0}. The face will be triangulated with the most direct algorithm, but the results might not be identical to blender.", e.getLocalizedMessage());
indexes[0] = this.getIndex(0);
for (int i = 1; i < this.vertexCount() - 1; ++i) {
indexes[1] = this.getIndex(i);
@ -335,17 +350,23 @@ public class Face implements Comparator<Integer> {
return "Face " + indexes;
}
/**
* The method finds the closest vertex to the one specified by <b>index</b>.
* If the vertexToIgnore is positive than it will be ignored in the result.
* The closes vertex must be able to create an edge that is fully contained within the face and does not cross
* any other edges.
* @param index
* the index of the vertex that needs to have found the nearest neighbour
* @param indexToIgnore
* the index to ignore in the result (pass -1 if none is to be ignored)
* @return the index of the closest vertex to the given one
*/
/**
* The method finds the closest vertex to the one specified by <b>index</b>.
* If the vertexToIgnore is positive than it will be ignored in the result.
* The closest vertex must be able to create an edge that is fully contained
* within the face and does not cross any other edges. Also if the
* vertexToIgnore is not negative then the condition that the edge between
* the found index and the one to ignore is inside the face must also be
* met.
*
* @param index
* the index of the vertex that needs to have found the nearest
* neighbour
* @param indexToIgnore
* the index to ignore in the result (pass -1 if none is to be
* ignored)
* @return the index of the closest vertex to the given one
*/
private int findClosestVertex(int index, int indexToIgnore) {
int result = -1;
List<Vector3f> vertices = temporalMesh.getVertices();
@ -355,7 +376,7 @@ public class Face implements Comparator<Integer> {
if (i != index && i != indexToIgnore) {
Vector3f v2 = vertices.get(i);
float d = v2.distance(v1);
if (d < distance && this.contains(new Edge(index, i, 0, true, temporalMesh))) {
if (d < distance && this.contains(new Edge(index, i, 0, true, temporalMesh)) && (indexToIgnore < 0 || this.contains(new Edge(indexToIgnore, i, 0, true, temporalMesh)))) {
result = i;
distance = d;
}
@ -376,11 +397,9 @@ public class Face implements Comparator<Integer> {
int index2 = edge.getSecondIndex();
// check if the line between the vertices is not a border edge of the face
if (!indexes.areNeighbours(index1, index2)) {
List<Vector3f> vertices = temporalMesh.getVertices();
for (int i = 0; i < indexes.size(); ++i) {
int i1 = this.getIndex(i);
int i2 = this.getIndex(i + 1);
int i1 = this.getIndex(i - 1);
int i2 = this.getIndex(i);
// check if the edges have no common verts (because if they do, they cannot cross)
if (i1 != index1 && i1 != index2 && i2 != index1 && i2 != index2) {
if (edge.cross(new Edge(i1, i2, 0, false, temporalMesh))) {
@ -389,31 +408,49 @@ public class Face implements Comparator<Integer> {
}
}
// the edge does NOT cross any of other edges, so now we need to verify if it is inside the face or outside
// we check it by comparing the angle that is created by vertices: [index1 - 1, index1, index1 + 1]
// with the one creaded by vertices: [index1 - 1, index1, index2]
// if the latter is greater than it means that the edge is outside the face
// IMPORTANT: we assume that all vertices are in one plane (this should be ensured before creating the Face)
int indexOfIndex1 = indexes.indexOf(index1);
int indexMinus1 = this.getIndex(indexOfIndex1 - 1);// indexOfIndex1 == 0 ? indexes.get(indexes.size() - 1) : indexes.get(indexOfIndex1 - 1);
int indexPlus1 = this.getIndex(indexOfIndex1 + 1);// indexOfIndex1 == indexes.size() - 1 ? 0 : indexes.get(indexOfIndex1 + 1);
Vector3f edge1 = vertices.get(indexMinus1).subtract(vertices.get(index1)).normalizeLocal();
Vector3f edge2 = vertices.get(indexPlus1).subtract(vertices.get(index1)).normalizeLocal();
Vector3f newEdge = vertices.get(index2).subtract(vertices.get(index1)).normalizeLocal();
// verify f the later computed angle is inside or outside the face
Vector3f direction1 = edge1.cross(edge2).normalizeLocal();
Vector3f direction2 = edge1.cross(newEdge).normalizeLocal();
Vector3f normal = temporalMesh.getNormals().get(index1);
boolean isAngle1Interior = normal.dot(direction1) < 0;
boolean isAngle2Interior = normal.dot(direction2) < 0;
// computing the edge's middle point
Vector3f edgeMiddlePoint = edge.computeCentroid();
// computing the edge that is perpendicular to the given edge and has a length of 1 (length actually does not matter)
Vector3f edgeVector = edge.getSecondVertex().subtract(edge.getFirstVertex());
Vector3f edgeNormal = temporalMesh.getNormals().get(index1).cross(edgeVector).normalizeLocal();
Edge e = new Edge(edgeMiddlePoint, edgeNormal.add(edgeMiddlePoint));
// compute the vectors from the middle point to the crossing between the extended edge 'e' and other edges of the face
List<Vector3f> crossingVectors = new ArrayList<Vector3f>();
for (int i = 0; i < indexes.size(); ++i) {
int i1 = this.getIndex(i);
int i2 = this.getIndex(i + 1);
Vector3f crossPoint = e.getCrossPoint(new Edge(i1, i2, 0, false, temporalMesh), true, false);
if(crossPoint != null) {
crossingVectors.add(crossPoint.subtractLocal(edgeMiddlePoint));
}
}
if(crossingVectors.size() == 0) {
return false;// edges do not cross
}
float angle1 = isAngle1Interior ? edge1.angleBetween(edge2) : FastMath.TWO_PI - edge1.angleBetween(edge2);
float angle2 = isAngle2Interior ? edge1.angleBetween(newEdge) : FastMath.TWO_PI - edge1.angleBetween(newEdge);
// use only distinct vertices (doubles may appear if the crossing point is a vertex)
List<Vector3f> distinctCrossingVectors = new ArrayList<Vector3f>();
for(Vector3f cv : crossingVectors) {
double minDistance = Double.MAX_VALUE;
for(Vector3f dcv : distinctCrossingVectors) {
minDistance = Math.min(minDistance, dcv.distance(cv));
}
if(minDistance > FastMath.FLT_EPSILON) {
distinctCrossingVectors.add(cv);
}
}
return angle1 >= angle2;
if(distinctCrossingVectors.size() == 0) {
throw new IllegalStateException("There MUST be at least 2 crossing vertices!");
}
// checking if all crossing vectors point to the same direction (if yes then the edge is outside the face)
float direction = Math.signum(distinctCrossingVectors.get(0).dot(edgeNormal));// if at least one vector has different direction that this - it means that the edge is inside the face
for(int i=1;i<distinctCrossingVectors.size();++i) {
if(direction != Math.signum(distinctCrossingVectors.get(i).dot(edgeNormal))) {
return true;
}
}
return false;
}
return true;
}

@ -82,7 +82,9 @@ public class SphereCollisionShape extends CollisionShape {
*/
@Override
public void setScale(Vector3f scale) {
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "SphereCollisionShape cannot be scaled");
if (!scale.equals(Vector3f.UNIT_XYZ)) {
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "SphereCollisionShape cannot be scaled");
}
}
protected void createShape() {
@ -91,7 +93,7 @@ public class SphereCollisionShape extends CollisionShape {
// new SphereShape(radius);
// objectId.setLocalScaling(Converter.convert(getScale()));
// objectId.setMargin(margin);
setScale(scale);
setScale(scale); // Set the scale to 1
setMargin(margin);
}

@ -139,11 +139,7 @@ public final class Bone implements Savable {
/**
* Special-purpose copy constructor.
* <p>
* Only copies the name and bind pose from the original.
* <p>
* WARNING: Local bind pose and world inverse bind pose transforms shallow
* copied. Modifying that data on the original bone will cause it to
* be recomputed on any cloned bones.
* Only copies the name, user control state and bind pose transforms from the original.
* <p>
* The rest of the data is <em>NOT</em> copied, as it will be
* generated automatically when the bone is animated.
@ -155,13 +151,13 @@ public final class Bone implements Savable {
userControl = source.userControl;
bindPos = source.bindPos;
bindRot = source.bindRot;
bindScale = source.bindScale;
bindPos = source.bindPos.clone();
bindRot = source.bindRot.clone();
bindScale = source.bindScale.clone();
modelBindInversePos = source.modelBindInversePos;
modelBindInverseRot = source.modelBindInverseRot;
modelBindInverseScale = source.modelBindInverseScale;
modelBindInversePos = source.modelBindInversePos.clone();
modelBindInverseRot = source.modelBindInverseRot.clone();
modelBindInverseScale = source.modelBindInverseScale.clone();
// parent and children will be assigned manually..
}

@ -650,6 +650,8 @@ public class Application implements SystemListener {
* Callables are executed right at the beginning of the main loop.
* They are executed even if the application is currently paused
* or out of focus.
*
* @param callable The callable to run in the main jME3 thread
*/
public <V> Future<V> enqueue(Callable<V> callable) {
AppTask<V> task = new AppTask<V>(callable);
@ -657,6 +659,20 @@ public class Application implements SystemListener {
return task;
}
/**
* Enqueues a runnable object to execute in the jME3
* rendering thread.
* <p>
* Runnables are executed right at the beginning of the main loop.
* They are executed even if the application is currently paused
* or out of focus.
*
* @param runnable The runnable to run in the main jME3 thread
*/
public void enqueue(Runnable runnable){
enqueue(new RunnableWrapper(runnable));
}
/**
* Runs tasks enqueued via {@link #enqueue(Callable)}
*/
@ -740,4 +756,19 @@ public class Application implements SystemListener {
return viewPort;
}
private class RunnableWrapper implements Callable{
private final Runnable runnable;
public RunnableWrapper(Runnable runnable){
this.runnable = runnable;
}
@Override
public Object call(){
runnable.run();
return null;
}
}
}

@ -156,7 +156,7 @@ public class AssetKey<T> implements Savable, Cloneable {
list.removeLast();
} else {
list.add("..");
Logger.getLogger(AssetKey.class.getName()).log(Level.SEVERE, "Asset path is outside assetmanager root");
Logger.getLogger(AssetKey.class.getName()).log(Level.SEVERE, "Asset path \"{0}\" is outside assetmanager root", path);
}
} else {
list.add(string);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2012, 2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,6 +33,7 @@ package com.jme3.audio;
import com.jme3.asset.AssetManager;
import com.jme3.asset.AssetNotFoundException;
import com.jme3.audio.AudioData.DataType;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
@ -128,6 +129,17 @@ public class AudioNode extends Node implements AudioSource {
setAudioData(audioData, audioKey);
}
/**
* Creates a new <code>AudioNode</code> with the given audio file.
* @param assetManager The asset manager to use to load the audio file
* @param name The filename of the audio file
* @param type The type. If <code>{@link com.jme3.audio.AudioData.DataType}.Stream</code>, the audio will be streamed gradually from disk,
* otherwise it will be buffered (<code>{@link com.jme3.audio.AudioData.DataType}.Buffer</code>)
*/
public AudioNode(AssetManager assetManager, String name, DataType type) {
this(assetManager, name, type == DataType.Stream, true);
}
/**
* Creates a new <code>AudioNode</code> with the given audio file.
*
@ -139,6 +151,8 @@ public class AudioNode extends Node implements AudioSource {
* the stream cache is used. When enabled, the audio stream will
* be read entirely but not decoded, allowing features such as
* seeking, looping and determining duration.
*
* @deprecated Use {@link AudioNode#AudioNode(com.jme3.asset.AssetManager, java.lang.String, com.jme3.audio.AudioData.DataType)} instead
*/
public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
this.audioKey = new AudioKey(name, stream, streamCache);
@ -152,9 +166,11 @@ public class AudioNode extends Node implements AudioSource {
* @param name The filename of the audio file
* @param stream If true, the audio will be streamed gradually from disk,
* otherwise, it will be buffered.
*
* @deprecated Use {@link AudioNode#AudioNode(com.jme3.asset.AssetManager, java.lang.String, com.jme3.audio.AudioData.DataType)} instead
*/
public AudioNode(AssetManager assetManager, String name, boolean stream) {
this(assetManager, name, stream, false);
this(assetManager, name, stream, true); // Always streamCached
}
/**
@ -167,7 +183,7 @@ public class AudioNode extends Node implements AudioSource {
* @deprecated AudioRenderer parameter is ignored.
*/
public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name) {
this(assetManager, name, false);
this(assetManager, name, DataType.Buffer);
}
/**
@ -175,9 +191,10 @@ public class AudioNode extends Node implements AudioSource {
*
* @param assetManager The asset manager to use to load the audio file
* @param name The filename of the audio file
* @deprecated Use {@link AudioNode#AudioNode(com.jme3.asset.AssetManager, java.lang.String, com.jme3.audio.AudioData.DataType) } instead
*/
public AudioNode(AssetManager assetManager, String name) {
this(assetManager, name, false);
this(assetManager, name, DataType.Buffer);
}
protected AudioRenderer getRenderer() {
@ -310,6 +327,19 @@ public class AudioNode extends Node implements AudioSource {
this.status = status;
}
/**
* Get the Type of the underlying AudioData to see if it's streamed or buffered.
* This is a shortcut to getAudioData().getType()
* <b>Warning</b>: Can return null!
* @return The {@link com.jme3.audio.AudioData.DataType} of the audio node.
*/
public DataType getType() {
if (data == null)
return null;
else
return data.getDataType();
}
/**
* @return True if the audio will keep looping after it is done playing,
* otherwise, false.

@ -109,8 +109,11 @@ public class BIHTree implements CollisionData {
this.mesh = mesh;
this.maxTrisPerNode = maxTrisPerNode;
if (maxTrisPerNode < 1 || mesh == null) {
throw new IllegalArgumentException();
if (maxTrisPerNode < 1) {
throw new IllegalArgumentException("maxTrisPerNode cannot be less than 1");
}
if (mesh == null) {
throw new IllegalArgumentException("Mesh cannot be null");
}
bihSwapTmp = new float[9];
@ -451,7 +454,7 @@ public class BIHTree implements CollisionData {
} else if (bv instanceof BoundingBox) {
bbox = new BoundingBox((BoundingBox) bv);
} else {
throw new UnsupportedCollisionException();
throw new UnsupportedCollisionException("BoundingVolume:" + bv);
}
bbox.transform(worldMatrix.invert(), bbox);
@ -470,7 +473,7 @@ public class BIHTree implements CollisionData {
BoundingVolume bv = (BoundingVolume) other;
return collideWithBoundingVolume(bv, worldMatrix, results);
} else {
throw new UnsupportedCollisionException();
throw new UnsupportedCollisionException("Collidable:" + other);
}
}

@ -106,6 +106,7 @@ public class ParticleEmitter extends Geometry {
private boolean worldSpace = true;
//variable that helps with computations
private transient Vector3f temp = new Vector3f();
private transient Vector3f lastPos;
public static class ParticleEmitterControl implements Control {
@ -1013,12 +1014,16 @@ public class ParticleEmitter extends Geometry {
// Spawns particles within the tpf timeslot with proper age
float interval = 1f / particlesPerSec;
float originalTpf = tpf;
tpf += timeDifference;
while (tpf > interval){
tpf -= interval;
Particle p = emitParticle(min, max);
if (p != null){
p.life -= tpf;
if (lastPos != null && isInWorldSpace()) {
p.position.interpolateLocal(lastPos, 1 - tpf / originalTpf);
}
if (p.life <= 0){
freeParticle(lastUsed);
}else{
@ -1028,6 +1033,12 @@ public class ParticleEmitter extends Geometry {
}
timeDifference = tpf;
if (lastPos == null) {
lastPos = new Vector3f();
}
lastPos.set(getWorldTranslation());
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
bbox.setMinMax(min, max);
this.setBoundRefresh();

@ -36,6 +36,11 @@ package com.jme3.input;
*/
public interface KeyInput extends Input {
/**
* unmapped key.
*/
public static final int KEY_UNKNOWN = 0x00;
/**
* escape key.
*/
@ -539,4 +544,8 @@ public interface KeyInput extends Input {
*/
public static final int KEY_SLEEP = 0xDF;
/**
* the last key.
*/
public static final int KEY_LAST = 0xE0;
}

@ -38,6 +38,7 @@ public class KeyNames {
private static final String[] KEY_NAMES = new String[0xFF];
static {
KEY_NAMES[KEY_UNKNOWN] = "Unknown";
KEY_NAMES[KEY_0] = "0";
KEY_NAMES[KEY_1] = "1";
KEY_NAMES[KEY_2] = "2";
@ -105,9 +106,10 @@ public class KeyNames {
KEY_NAMES[KEY_NUMPADEQUALS] = "Numpad =";
KEY_NAMES[KEY_NUMPADENTER] = "Numpad Enter";
KEY_NAMES[KEY_NUMPADCOMMA] = "Numpad .";
KEY_NAMES[KEY_NUMPADCOMMA] = "Numpad ,";
KEY_NAMES[KEY_DIVIDE] = "Numpad /";
KEY_NAMES[KEY_SUBTRACT] = "Numpad -";
KEY_NAMES[KEY_DECIMAL] = "Numpad .";
KEY_NAMES[KEY_LMENU] = "Left Alt";
KEY_NAMES[KEY_RMENU] = "Right Alt";
@ -178,7 +180,7 @@ public class KeyNames {
KEY_NAMES[KEY_UNLABELED] = "Unlabeled";
}
public String getName(int keyId){
public static String getName(int keyId) {
return KEY_NAMES[keyId];
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012, 2015 jMonkeyEngine
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -146,4 +146,10 @@ public class DirectionalLight extends Light {
direction = (Vector3f) ic.readSavable("direction", null);
}
@Override
public DirectionalLight clone() {
DirectionalLight l = (DirectionalLight)super.clone();
l.direction = direction.clone();
return l;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012, 2015 jMonkeyEngine
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -228,7 +228,9 @@ public abstract class Light implements Savable, Cloneable {
@Override
public Light clone(){
try {
return (Light) super.clone();
Light l = (Light) super.clone();
l.color = color.clone();
return l;
} catch (CloneNotSupportedException ex) {
throw new AssertionError();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012, 2015 jMonkeyEngine
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -241,4 +241,11 @@ public class PointLight extends Light {
this.invRadius = 0;
}
}
@Override
public PointLight clone() {
PointLight p = (PointLight)super.clone();
p.position = position.clone();
return p;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012, 2015 jMonkeyEngine
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -448,5 +448,13 @@ public class SpotLight extends Light {
this.invSpotRange = 0;
}
}
@Override
public SpotLight clone() {
SpotLight s = (SpotLight)super.clone();
s.direction = direction.clone();
s.position = position.clone();
return s;
}
}

@ -248,16 +248,45 @@ When arrays can be inserted in J3M files
if (texKey.isFlipY()) {
ret += "Flip ";
}
if (texVal.getWrap(Texture.WrapAxis.S) == WrapMode.Repeat) {
ret += "Repeat ";
//Wrap mode
ret += getWrapMode(texVal, Texture.WrapAxis.S);
ret += getWrapMode(texVal, Texture.WrapAxis.T);
ret += getWrapMode(texVal, Texture.WrapAxis.R);
//Min and Mag filter
Texture.MinFilter def = Texture.MinFilter.BilinearNoMipMaps;
if(texVal.getImage().hasMipmaps() || texKey.isGenerateMips()){
def = Texture.MinFilter.Trilinear;
}
if(texVal.getMinFilter() != def){
ret += "Min" + texVal.getMinFilter().name()+ " ";
}
if(texVal.getMagFilter() != Texture.MagFilter.Bilinear){
ret += "Mag" + texVal.getMagFilter().name()+ " ";
}
return ret + texKey.getName();
return ret + "\"" + texKey.getName() + "\"";
default:
return null; // parameter type not supported in J3M
}
}
private String getWrapMode(Texture texVal, Texture.WrapAxis axis) {
WrapMode mode = WrapMode.EdgeClamp;
try{
mode = texVal.getWrap(axis);
}catch (IllegalArgumentException e){
//this axis doesn't exist on the texture
return "";
}
if(mode != WrapMode.EdgeClamp){
return"Wrap"+ mode.name() + "_" + axis.name() + " ";
}
return "";
}
@Override
public MatParam clone() {
try {

@ -1236,12 +1236,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
oc.write(def.getAssetName(), "material_def", null);
oc.write(additionalState, "render_state", null);
oc.write(transparent, "is_transparent", false);
oc.write(name, "name", null);
oc.writeStringSavableMap(paramValues, "parameters", null);
}
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", null);
additionalState = (RenderState) ic.readSavable("render_state", null);
transparent = ic.readBoolean("is_transparent", false);

@ -31,14 +31,6 @@
*/
package com.jme3.scene;
import com.jme3.export.*;
import com.jme3.material.Material;
import com.jme3.math.Matrix4f;
import com.jme3.math.Vector3f;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
@ -48,13 +40,22 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme3.collision.Collidable;
import com.jme3.collision.CollisionResults;
import com.jme3.material.Material;
import com.jme3.math.Matrix4f;
import com.jme3.math.Vector3f;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.util.SafeArrayList;
import com.jme3.util.TempVars;
/**
* BatchNode holds geometries that are a batched version of all the geometries that are in its sub scenegraph.
* There is one geometry per different material in the sub tree.
* The geometries are directly attached to the node in the scene graph.
* Usage is like any other node except you have to call the {@link #batch()} method once all the geometries have been attached to the sub scene graph and their material set
* (see todo more automagic for further enhancements)
* All the geometries that have been batched are set to {@link CullHint#Always} to not render them.
* All the geometries that have been batched are set to not be rendered - {@link CullHint} is left intact.
* The sub geometries can be transformed as usual, their transforms are used to update the mesh of the geometryBatch.
* Sub geoms can be removed but it may be slower than the normal spatial removing
* Sub geoms can be added after the batch() method has been called but won't be batched and will just be rendered as normal geometries.
@ -72,7 +73,7 @@ public class BatchNode extends GeometryGroupNode {
*/
protected SafeArrayList<Batch> batches = new SafeArrayList<Batch>(Batch.class);
/**
* a map storing he batches by geometry to quickly acces the batch when updating
* a map for storing the batches by geometry to quickly access the batch when updating
*/
protected Map<Geometry, Batch> batchesByGeom = new HashMap<Geometry, Batch>();
/**
@ -115,11 +116,10 @@ public class BatchNode extends GeometryGroupNode {
}
@Override
public void onGeoemtryUnassociated(Geometry geom) {
public void onGeometryUnassociated(Geometry geom) {
setNeedsFullRebatch(true);
}
protected Matrix4f getTransformMatrix(Geometry g){
return g.cachedWorldMat;
}
@ -177,7 +177,7 @@ public class BatchNode extends GeometryGroupNode {
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
int nbGeoms = 0;
gatherGeomerties(matMap, this, needsFullRebatch);
gatherGeometries(matMap, this, needsFullRebatch);
if (needsFullRebatch) {
for (Batch batch : batches.getArray()) {
batch.geometry.removeFromParent();
@ -271,7 +271,7 @@ public class BatchNode extends GeometryGroupNode {
}
private void gatherGeomerties(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) {
private void gatherGeometries(Map<Material, List<Geometry>> map, Spatial n, boolean rebatch) {
if (n instanceof Geometry) {
@ -304,7 +304,7 @@ public class BatchNode extends GeometryGroupNode {
if (child instanceof BatchNode) {
continue;
}
gatherGeomerties(map, child, rebatch);
gatherGeometries(map, child, rebatch);
}
}
@ -319,7 +319,7 @@ public class BatchNode extends GeometryGroupNode {
return null;
}
private boolean isBatch(Spatial s) {
public final boolean isBatch(Spatial s) {
for (Batch batch : batches.getArray()) {
if (batch.geometry == s) {
return true;
@ -336,9 +336,6 @@ public class BatchNode extends GeometryGroupNode {
*/
@Override
public void setMaterial(Material material) {
// for (Batch batch : batches.values()) {
// batch.geometry.setMaterial(material);
// }
throw new UnsupportedOperationException("Unsupported for now, please set the material on the geoms before batching");
}
@ -356,74 +353,7 @@ public class BatchNode extends GeometryGroupNode {
Batch b = batches.iterator().next();
return b.geometry.getMaterial();
}
return null;//material;
}
// /**
// * Sets the material to the a specific batch of this BatchNode
// *
// *
// * @param material the material to use for this geometry
// */
// public void setMaterial(Material material,int batchIndex) {
// if (!batches.isEmpty()) {
//
// }
//
// }
//
// /**
// * Returns the material that is used for the first batch of this BatchNode
// *
// * use getMaterial(Material material,int batchIndex) to get a material from a specific batch
// *
// * @return the material that is used for the first batch of this BatchNode
// *
// * @see #setMaterial(com.jme3.material.Material)
// */
// public Material getMaterial(int batchIndex) {
// if (!batches.isEmpty()) {
// Batch b = batches.get(batches.keySet().iterator().next());
// return b.geometry.getMaterial();
// }
// return null;//material;
// }
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
//
// if (material != null) {
// oc.write(material.getAssetName(), "materialName", null);
// }
// oc.write(material, "material", null);
}
@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
// material = null;
// String matName = ic.readString("materialName", null);
// if (matName != null) {
// // Material name is set,
// // Attempt to load material via J3M
// try {
// material = im.getAssetManager().loadMaterial(matName);
// } catch (AssetNotFoundException ex) {
// // Cannot find J3M file.
// logger.log(Level.FINE, "Could not load J3M file {0} for Geometry.",
// matName);
// }
// }
// // If material is NULL, try to load it from the geometry
// if (material == null) {
// material = (Material) ic.readSavable("material", null);
// }
return null;
}
/**
@ -510,8 +440,7 @@ public class BatchNode extends GeometryGroupNode {
outMesh.setMode(mode);
outMesh.setLineWidth(lineWidth);
if (totalVerts >= 65536) {
// make sure we create an UnsignedInt buffer so
// we can fit all of the meshes
// make sure we create an UnsignedInt buffer so we can fit all of the meshes
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt;
} else {
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort;
@ -733,7 +662,6 @@ public class BatchNode extends GeometryGroupNode {
}
protected class Batch {
/**
* update the batchesByGeom map for this batch with the given List of geometries
* @param list
@ -771,4 +699,15 @@ public class BatchNode extends GeometryGroupNode {
}
return clone;
}
@Override
public int collideWith(Collidable other, CollisionResults results) {
int total = 0;
for (Spatial child : children.getArray()){
if (!isBatch(child)) {
total += child.collideWith(other, results);
}
}
return total;
}
}

@ -344,7 +344,7 @@ public class Geometry extends Spatial {
if (groupNode != null) {
// Once the geometry is removed
// from the parent, the group node needs to be updated.
groupNode.onGeoemtryUnassociated(this);
groupNode.onGeometryUnassociated(this);
groupNode = null;
// change the default to -1 to make error detection easier

@ -83,5 +83,5 @@ public abstract class GeometryGroupNode extends Node {
*
* @param geom The Geometry which is being unassociated.
*/
public abstract void onGeoemtryUnassociated(Geometry geom);
public abstract void onGeometryUnassociated(Geometry geom);
}

@ -687,6 +687,11 @@ public class Node extends Spatial {
// childClone.parent = nodeClone;
// nodeClone.children.add(childClone);
// }
// Reset the fields of the clone that should be in a 'new' state.
nodeClone.updateList = null;
nodeClone.updateListValid = false; // safe because parent is nulled out in super.clone()
return nodeClone;
}

@ -329,7 +329,7 @@ public class InstancedNode extends GeometryGroupNode {
}
@Override
public void onGeoemtryUnassociated(Geometry geom) {
public void onGeometryUnassociated(Geometry geom) {
removeFromInstancedGeometry(geom);
}
}

@ -211,7 +211,7 @@ public class Cylinder extends Mesh {
*/
public void updateGeometry(int axisSamples, int radialSamples,
float radius, float radius2, float height, boolean closed, boolean inverted) {
this.axisSamples = axisSamples + (closed ? 2 : 0);
this.axisSamples = axisSamples;
this.radialSamples = radialSamples;
this.radius = radius;
this.radius2 = radius2;
@ -222,6 +222,7 @@ public class Cylinder extends Mesh {
// VertexBuffer pvb = getBuffer(Type.Position);
// VertexBuffer nvb = getBuffer(Type.Normal);
// VertexBuffer tvb = getBuffer(Type.TexCoord);
axisSamples += (closed ? 2 : 0);
// Vertices
int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0);

@ -963,7 +963,7 @@ public final class AppSettings extends HashMap<String, Object> {
return getString("SettingsDialogImage");
}
public boolean getGammaCorrection() {
public boolean isGammaCorrection() {
return getBoolean("GammaCorrection");
}

@ -51,7 +51,6 @@ import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -401,6 +400,25 @@ public final class BufferUtils {
vector.z = buf.get(index * 3 + 2);
}
/**
* Updates the values of the given vector from the specified buffer at the
* index provided.
*
* @param vector
* the vector to set data on
* @param buf
* the buffer to read from
* @param index
* the position (in terms of vectors, not floats) to read from
* the buf
*/
public static void populateFromBuffer(Vector4f vector, FloatBuffer buf, int index) {
vector.x = buf.get(index * 4);
vector.y = buf.get(index * 4 + 1);
vector.z = buf.get(index * 4 + 2);
vector.w = buf.get(index * 4 + 3);
}
/**
* Generates a Vector3f array from the given FloatBuffer.
*
@ -1249,7 +1267,6 @@ public final class BufferUtils {
System.out.println(store.toString());
}
}
private static final AtomicBoolean loadedMethods = new AtomicBoolean(false);
private static Method cleanerMethod = null;
private static Method cleanMethod = null;
private static Method viewedBufferMethod = null;
@ -1269,31 +1286,23 @@ public final class BufferUtils {
}
}
private static void loadCleanerMethods() {
// If its already true, exit, if not, set it to true.
if (BufferUtils.loadedMethods.getAndSet(true)) {
return;
static {
// Oracle JRE / OpenJDK
cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
if (viewedBufferMethod == null) {
// They changed the name in Java 7 (???)
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "attachment");
}
// This could potentially be called many times if used from multiple
// threads
synchronized (BufferUtils.loadedMethods) {
// Oracle JRE / OpenJDK
cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
if (viewedBufferMethod == null) {
// They changed the name in Java 7 (???)
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "attachment");
}
// Apache Harmony
ByteBuffer bb = BufferUtils.createByteBuffer(1);
Class<?> clazz = bb.getClass();
try {
freeMethod = clazz.getMethod("free");
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
}
// Apache Harmony
ByteBuffer bb = BufferUtils.createByteBuffer(1);
Class<?> clazz = bb.getClass();
try {
freeMethod = clazz.getMethod("free");
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
}
}
@ -1314,8 +1323,6 @@ public final class BufferUtils {
return;
}
BufferUtils.loadCleanerMethods();
try {
if (freeMethod != null) {
freeMethod.invoke(toBeDestroyed);

@ -0,0 +1,97 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.util.mikktspace;
/**
*
* @author Nehon
*/
public interface MikkTSpaceContext {
/**
* Returns the number of faces (triangles/quads) on the mesh to be
* processed.
*
* @return
*/
public int getNumFaces();
/**
* Returns the number of vertices on face number iFace iFace is a number in
* the range {0, 1, ..., getNumFaces()-1}
*
* @param face
* @return
*/
public int getNumVerticesOfFace(int face);
/**
* returns the position/normal/texcoord of the referenced face of vertex
* number iVert. iVert is in the range {0,1,2} for triangles and {0,1,2,3}
* for quads.
*
* @param posOut
* @param face
* @param vert
*/
public void getPosition(float posOut[], int face, int vert);
public void getNormal(float normOut[], int face, int vert);
public void getTexCoord(float texOut[], int face, int vert);
/**
* The call-backsetTSpaceBasic() is sufficient for basic normal mapping.
* This function is used to return the tangent and sign to the application.
* tangent is a unit length vector. For normal maps it is sufficient to use
* the following simplified version of the bitangent which is generated at
* pixel/vertex level.
*
* bitangent = fSign * cross(vN, tangent);
*
* Note that the results are returned unindexed. It is possible to generate
* a new index list But averaging/overwriting tangent spaces by using an
* already existing index list WILL produce INCRORRECT results. DO NOT! use
* an already existing index list.
*
* @param tangent
* @param sign
* @param face
* @param vert
*/
public void setTSpaceBasic(float tangent[], float sign, int face, int vert);
/**
* This function is used to return tangent space results to the application.
* tangent and biTangent are unit length vectors and fMagS and fMagT are
* their true magnitudes which can be used for relief mapping effects.
*
* biTangent is the "real" bitangent and thus may not be perpendicular to
* tangent. However, both are perpendicular to the vertex normal. For normal
* maps it is sufficient to use the following simplified version of the
* bitangent which is generated at pixel/vertex level.
*
* <pre>
* fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
* bitangent = fSign * cross(vN, tangent);
* </pre>
*
* Note that the results are returned unindexed. It is possible to generate
* a new index list. But averaging/overwriting tangent spaces by using an
* already existing index list WILL produce INCRORRECT results. DO NOT! use
* an already existing index list.
*
* @param tangent
* @param biTangent
* @param magS
* @param magT
* @param isOrientationPreserving
* @param face
* @param vert
*/
void setTSpace(float tangent[], float biTangent[], float magS, float magT,
boolean isOrientationPreserving, int face, int vert);
}

@ -0,0 +1,100 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.util.mikktspace;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.mesh.IndexBuffer;
import com.jme3.util.BufferUtils;
import java.nio.FloatBuffer;
/**
*
* @author Nehon
*/
public class MikkTSpaceImpl implements MikkTSpaceContext {
Mesh mesh;
public MikkTSpaceImpl(Mesh mesh) {
this.mesh = mesh;
VertexBuffer tangentBuffer = mesh.getBuffer(VertexBuffer.Type.Tangent);
if(tangentBuffer == null){
FloatBuffer fb = BufferUtils.createFloatBuffer(mesh.getVertexCount() * 4);
mesh.setBuffer(VertexBuffer.Type.Tangent, 4, fb);
}
//TODO ensure the Tangent buffer exists, else create one.
}
@Override
public int getNumFaces() {
return mesh.getTriangleCount();
}
@Override
public int getNumVerticesOfFace(int face) {
return 3;
}
@Override
public void getPosition(float[] posOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer position = mesh.getBuffer(VertexBuffer.Type.Position);
FloatBuffer pos = (FloatBuffer) position.getData();
pos.position(vertIndex * 3);
posOut[0] = pos.get();
posOut[1] = pos.get();
posOut[2] = pos.get();
}
@Override
public void getNormal(float[] normOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer normal = mesh.getBuffer(VertexBuffer.Type.Normal);
FloatBuffer norm = (FloatBuffer) normal.getData();
norm.position(vertIndex * 3);
normOut[0] = norm.get();
normOut[1] = norm.get();
normOut[2] = norm.get();
}
@Override
public void getTexCoord(float[] texOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer texCoord = mesh.getBuffer(VertexBuffer.Type.TexCoord);
FloatBuffer tex = (FloatBuffer) texCoord.getData();
tex.position(vertIndex * 2);
texOut[0] = tex.get();
texOut[1] = tex.get();
}
@Override
public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer tangentBuffer = mesh.getBuffer(VertexBuffer.Type.Tangent);
FloatBuffer tan = (FloatBuffer) tangentBuffer.getData();
tan.position(vertIndex * 4);
tan.put(tangent);
tan.put(sign);
tan.rewind();
tangentBuffer.setUpdateNeeded();
}
@Override
public void setTSpace(float[] tangent, float[] biTangent, float magS, float magT, boolean isOrientationPreserving, int face, int vert) {
//Do nothing
}
private int getIndex(int face, int vert) {
IndexBuffer index = mesh.getIndexBuffer();
int vertIndex = index.get(face * 3 + vert);
return vertIndex;
}
}

@ -32,11 +32,12 @@ void main(){
#ifdef POINT_SPRITE
vec4 worldPos = g_WorldMatrix * pos;
float d = distance(g_CameraPosition.xyz, worldPos.xyz);
gl_PointSize = max(1.0, (inSize * SIZE_MULTIPLIER * m_Quadratic) / d);
float size = (inSize * SIZE_MULTIPLIER * m_Quadratic) / d;
gl_PointSize = max(1.0, size);
//vec4 worldViewPos = g_WorldViewMatrix * pos;
//gl_PointSize = (inSize * SIZE_MULTIPLIER * m_Quadratic)*100.0 / worldViewPos.z;
color.a *= min(gl_PointSize, 1.0);
color.a *= min(size, 1.0);
#endif
}

@ -95,6 +95,25 @@ Gamepad\ F310\ (Controller).ry=rz
# keeps it from confusing the .rx mapping.
Gamepad\ F310\ (Controller).z=trigger
# Logitech F310 gamepad with dip switch XInput for Windows 10
Controller\ (Gamepad\ F310).0=2
Controller\ (Gamepad\ F310).1=1
Controller\ (Gamepad\ F310).2=3
Controller\ (Gamepad\ F310).3=0
Controller\ (Gamepad\ F310).6=8
Controller\ (Gamepad\ F310).7=9
Controller\ (Gamepad\ F310).8=10
Controller\ (Gamepad\ F310).9=11
Controller\ (Gamepad\ F310).rx=z
Controller\ (Gamepad\ F310).ry=rz
# requires custom code to support trigger buttons but this
# keeps it from confusing the .rx mapping.
Controller\ (Gamepad\ F310).z=trigger
# Alternate version of the XBOX 360 controller
XBOX\ 360\ For\ Windows\ (Controller).0=2
XBOX\ 360\ For\ Windows\ (Controller).1=1

@ -155,7 +155,7 @@ public class TextureAtlas {
return false;
} else {
if (normal != null && normal.getKey() != null) {
addTexture(diffuse, "NormalMap", keyName);
addTexture(normal, "NormalMap", keyName);
}
if (specular != null && specular.getKey() != null) {
addTexture(specular, "SpecularMap", keyName);

@ -360,7 +360,7 @@ public final class SettingsDialog extends JFrame {
vsyncBox.setSelected(source.isVSync());
gammaBox = new JCheckBox(resourceBundle.getString("checkbox.gamma"));
gammaBox.setSelected(source.getGammaCorrection());
gammaBox.setSelected(source.isGammaCorrection());
gbc = new GridBagConstraints();
gbc.weightx = 0.5;

@ -19,6 +19,6 @@ void main(void)
#ifdef NUM_BONES
Skinning_Compute(modelSpacePos,modelSpaceNormals);
#endif
normal = normalize(g_NormalMatrix * modelSpaceNormals);
normal = normalize(TransformNormal(modelSpaceNormals));
gl_Position = TransformWorldViewProjection(modelSpacePos);
}

@ -5,11 +5,15 @@ if (!hasProperty('mainClass')) {
}
task run(dependsOn: 'build', type:JavaExec) {
main = mainClass
classpath = sourceSets.main.runtimeClasspath
if( assertions == "true" ){
enableAssertions = true;
}
main = mainClass
classpath = sourceSets.main.runtimeClasspath
if (System.properties['os.name'].toLowerCase().contains('mac')) {
jvmArgs "-XstartOnFirstThread"
jvmArgs "-Djava.awt.headless=true"
}
if( assertions == "true" ){
enableAssertions = true;
}
}
dependencies {

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

@ -456,7 +456,7 @@ public class PhysicsVehicle extends PhysicsRigidBody {
/**
* Get the current forward vector of the vehicle in world coordinates
* @param vector The object to write the forward vector values to.
* Passing null will cause a new {@link Vector3f) to be created.
* Passing null will cause a new {@link Vector3f} to be created.
* @return The forward vector
*/
public Vector3f getForwardVector(Vector3f vector) {

@ -54,6 +54,7 @@ import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.NanoTimer;
import com.jme3.system.NativeLibraryLoader;
import com.jme3.system.NullRenderer;
import com.jme3.system.SystemListener;
import com.jme3.system.Timer;
@ -202,8 +203,8 @@ public abstract class JoglContext implements JmeContext {
GLContext.getCurrent().addGLDebugListener(new JoglGLDebugOutputHandler());
}
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection());
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection());
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
// Init input
if (keyInput != null) {

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.system.lwjgl;
import com.jme3.input.lwjgl.JInputJoyInput;
@ -53,6 +52,7 @@ import com.jme3.renderer.opengl.GLTiming;
import com.jme3.renderer.opengl.GLTimingState;
import com.jme3.renderer.opengl.GLTracer;
import com.jme3.system.*;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
@ -82,18 +82,18 @@ public abstract class LwjglContext implements JmeContext {
protected Timer timer;
protected SystemListener listener;
public void setSystemListener(SystemListener listener){
public void setSystemListener(SystemListener listener) {
this.listener = listener;
}
protected void printContextInitInfo() {
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n" +
" * Graphics Adapter: {2}\n" +
" * Driver Version: {3}\n" +
" * Scaling Factor: {4}",
new Object[]{ Sys.getVersion(), Thread.currentThread().getName(),
Display.getAdapter(), Display.getVersion(),
Display.getPixelScaleFactor() });
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
+ " * Graphics Adapter: {2}\n"
+ " * Driver Version: {3}\n"
+ " * Scaling Factor: {4}",
new Object[]{Sys.getVersion(), Thread.currentThread().getName(),
Display.getAdapter(), Display.getVersion(),
Display.getPixelScaleFactor()});
}
protected ContextAttribs createContextAttribs() {
@ -162,6 +162,7 @@ public abstract class LwjglContext implements JmeContext {
}
}
}
protected void loadNatives() {
if (JmeSystem.isLowPermissions()) {
return;
@ -181,7 +182,7 @@ public abstract class LwjglContext implements JmeContext {
protected int getNumSamplesToUse() {
int samples = 0;
if (settings.getSamples() > 1){
if (settings.getSamples() > 1) {
samples = settings.getSamples();
int supportedSamples = determineMaxSamples(samples);
if (supportedSamples < samples) {
@ -196,14 +197,14 @@ public abstract class LwjglContext implements JmeContext {
return samples;
}
protected void initContextFirstTime(){
protected void initContextFirstTime() {
if (!GLContext.getCapabilities().OpenGL20) {
throw new RendererException("OpenGL 2.0 or higher is " +
"required for jMonkeyEngine");
throw new RendererException("OpenGL 2.0 or higher is "
+ "required for jMonkeyEngine");
}
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL2)
|| settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) {
|| settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) {
GL gl = new LwjglGL();
GLExt glext = new LwjglGLExt();
GLFbo glfbo;
@ -215,20 +216,20 @@ public abstract class LwjglContext implements JmeContext {
}
if (settings.getBoolean("GraphicsDebug")) {
gl = new GLDebugDesktop(gl, glext, glfbo);
gl = new GLDebugDesktop(gl, glext, glfbo);
glext = (GLExt) gl;
glfbo = (GLFbo) gl;
}
if (settings.getBoolean("GraphicsTiming")) {
GLTimingState timingState = new GLTimingState();
gl = (GL) GLTiming.createGLTiming(gl, timingState, GL.class, GL2.class, GL3.class, GL4.class);
gl = (GL) GLTiming.createGLTiming(gl, timingState, GL.class, GL2.class, GL3.class, GL4.class);
glext = (GLExt) GLTiming.createGLTiming(glext, timingState, GLExt.class);
glfbo = (GLFbo) GLTiming.createGLTiming(glfbo, timingState, GLFbo.class);
}
if (settings.getBoolean("GraphicsTrace")) {
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class);
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class);
glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class);
glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class);
}
@ -243,8 +244,8 @@ public abstract class LwjglContext implements JmeContext {
ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback(new LwjglGLDebugOutputHandler()));
}
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection());
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection());
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
// Init input
if (keyInput != null) {
@ -260,42 +261,42 @@ public abstract class LwjglContext implements JmeContext {
}
}
public void internalDestroy(){
public void internalDestroy() {
renderer = null;
timer = null;
renderable.set(false);
synchronized (createdLock){
synchronized (createdLock) {
created.set(false);
createdLock.notifyAll();
}
}
public void internalCreate(){
public void internalCreate() {
timer = new LwjglTimer();
synchronized (createdLock){
synchronized (createdLock) {
created.set(true);
createdLock.notifyAll();
}
if (renderable.get()){
if (renderable.get()) {
initContextFirstTime();
}else{
} else {
assert getType() == Type.Canvas;
}
}
public void create(){
public void create() {
create(false);
}
public void destroy(){
public void destroy() {
destroy(false);
}
protected void waitFor(boolean createdVal){
synchronized (createdLock){
while (created.get() != createdVal){
protected void waitFor(boolean createdVal) {
synchronized (createdLock) {
while (created.get() != createdVal) {
try {
createdLock.wait();
} catch (InterruptedException ex) {
@ -304,11 +305,11 @@ public abstract class LwjglContext implements JmeContext {
}
}
public boolean isCreated(){
public boolean isCreated() {
return created.get();
}
public boolean isRenderable(){
public boolean isRenderable() {
return renderable.get();
}
@ -316,7 +317,7 @@ public abstract class LwjglContext implements JmeContext {
this.settings.copyFrom(settings);
}
public AppSettings getSettings(){
public AppSettings getSettings() {
return settings;
}

@ -2,14 +2,14 @@ if (!hasProperty('mainClass')) {
ext.mainClass = ''
}
repositories {
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
}
def lwjglVersion = '3.0.0b'
dependencies {
compile project(':jme3-core')
compile project(':jme3-desktop')
compile 'org.lwjgl:lwjgl:3.0.0b'
compile "org.lwjgl:lwjgl:${lwjglVersion}"
compile "org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-windows"
compile "org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-linux"
compile "org.lwjgl:lwjgl-platform:${lwjglVersion}:natives-osx"
}

@ -32,32 +32,38 @@
package com.jme3.audio.lwjgl;
import com.jme3.audio.openal.ALC;
import java.nio.IntBuffer;
import org.lwjgl.openal.ALC10;
import org.lwjgl.openal.ALContext;
import org.lwjgl.openal.ALDevice;
import java.nio.IntBuffer;
import static org.lwjgl.openal.ALC10.alcGetContextsDevice;
import static org.lwjgl.openal.ALC10.alcGetCurrentContext;
import org.lwjgl.openal.SOFTPauseDevice;
public class LwjglALC implements ALC {
private ALDevice device;
private ALContext context;
private long contextId;
private long deviceId;
public void createALC() {
device = ALDevice.create();
context = ALContext.create(device);
context.makeCurrent();
contextId = ALC10.alcGetCurrentContext();
deviceId = ALC10.alcGetContextsDevice(contextId);
}
public void destroyALC() {
if (context != null) {
context.destroy();
context = null;
}
if (device != null) {
device.destroy();
device = null;
}
}
@ -66,31 +72,29 @@ public class LwjglALC implements ALC {
}
public String alcGetString(final int parameter) {
final long context = alcGetCurrentContext();
final long device = alcGetContextsDevice(context);
return ALC10.alcGetString(device, parameter);
return ALC10.alcGetString(deviceId, parameter);
}
public boolean alcIsExtensionPresent(final String extension) {
final long context = alcGetCurrentContext();
final long device = alcGetContextsDevice(context);
return ALC10.alcIsExtensionPresent(device, extension);
return ALC10.alcIsExtensionPresent(deviceId, extension);
}
public void alcGetInteger(final int param, final IntBuffer buffer, final int size) {
if (buffer.position() != 0) throw new AssertionError();
if (buffer.limit() != size) throw new AssertionError();
final long context = alcGetCurrentContext();
final long device = alcGetContextsDevice(context);
final int value = ALC10.alcGetInteger(device, param);
//buffer.put(value);
if (buffer.position() != 0) {
throw new AssertionError();
}
if (buffer.limit() != size) {
throw new AssertionError();
}
ALC10.alcGetIntegerv(deviceId, param, buffer);
}
public void alcDevicePauseSOFT() {
SOFTPauseDevice.alcDevicePauseSOFT(deviceId);
}
public void alcDeviceResumeSOFT() {
SOFTPauseDevice.alcDeviceResumeSOFT(deviceId);
}
}

@ -66,7 +66,8 @@ public class GlfwKeyInput implements KeyInput {
glfwSetKeyCallback(context.getWindowHandle(), keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
final KeyInputEvent evt = new KeyInputEvent(scancode, (char) key, GLFW_PRESS == action, GLFW_REPEAT == action);
int jmeKey = GlfwKeyMap.toJmeKeyCode(key);
final KeyInputEvent evt = new KeyInputEvent(jmeKey, (char) key, GLFW_PRESS == action, GLFW_REPEAT == action);
evt.setTime(getInputTimeNanos());
keyInputEvents.add(evt);
}

@ -0,0 +1,171 @@
/*
* 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 com.jme3.input.lwjgl;
import static org.lwjgl.glfw.GLFW.*;
import static com.jme3.input.KeyInput.*;
public class GlfwKeyMap {
private static final int[] glfwToJmeKeyMap = new int[GLFW_KEY_LAST + 1];
private static void reg(int jmeKey, int glfwKey) {
glfwToJmeKeyMap[glfwKey] = jmeKey;
}
static {
reg(KEY_ESCAPE, GLFW_KEY_ESCAPE);
reg(KEY_1, GLFW_KEY_1);
reg(KEY_2, GLFW_KEY_2);
reg(KEY_3, GLFW_KEY_3);
reg(KEY_4, GLFW_KEY_4);
reg(KEY_5, GLFW_KEY_5);
reg(KEY_6, GLFW_KEY_6);
reg(KEY_7, GLFW_KEY_7);
reg(KEY_8, GLFW_KEY_8);
reg(KEY_9, GLFW_KEY_9);
reg(KEY_0, GLFW_KEY_0);
reg(KEY_MINUS, GLFW_KEY_MINUS);
reg(KEY_EQUALS, GLFW_KEY_EQUAL);
reg(KEY_BACK, GLFW_KEY_BACKSPACE);
reg(KEY_TAB, GLFW_KEY_TAB);
reg(KEY_Q, GLFW_KEY_Q);
reg(KEY_W, GLFW_KEY_W);
reg(KEY_E, GLFW_KEY_E);
reg(KEY_R, GLFW_KEY_R);
reg(KEY_T, GLFW_KEY_T);
reg(KEY_Y, GLFW_KEY_Y);
reg(KEY_U, GLFW_KEY_U);
reg(KEY_I, GLFW_KEY_I);
reg(KEY_O, GLFW_KEY_O);
reg(KEY_P, GLFW_KEY_P);
reg(KEY_LBRACKET, GLFW_KEY_LEFT_BRACKET);
reg(KEY_RBRACKET, GLFW_KEY_RIGHT_BRACKET);
reg(KEY_RETURN, GLFW_KEY_ENTER);
reg(KEY_LCONTROL, GLFW_KEY_LEFT_CONTROL);
reg(KEY_A, GLFW_KEY_A);
reg(KEY_S, GLFW_KEY_S);
reg(KEY_D, GLFW_KEY_D);
reg(KEY_F, GLFW_KEY_F);
reg(KEY_G, GLFW_KEY_G);
reg(KEY_H, GLFW_KEY_H);
reg(KEY_J, GLFW_KEY_J);
reg(KEY_K, GLFW_KEY_K);
reg(KEY_L, GLFW_KEY_L);
reg(KEY_SEMICOLON, GLFW_KEY_SEMICOLON);
reg(KEY_APOSTROPHE, GLFW_KEY_APOSTROPHE);
reg(KEY_GRAVE, GLFW_KEY_GRAVE_ACCENT);
reg(KEY_LSHIFT, GLFW_KEY_LEFT_SHIFT);
reg(KEY_BACKSLASH, GLFW_KEY_BACKSLASH);
reg(KEY_Z, GLFW_KEY_Z);
reg(KEY_X, GLFW_KEY_X);
reg(KEY_C, GLFW_KEY_C);
reg(KEY_V, GLFW_KEY_V);
reg(KEY_B, GLFW_KEY_B);
reg(KEY_N, GLFW_KEY_N);
reg(KEY_M, GLFW_KEY_M);
reg(KEY_COMMA, GLFW_KEY_COMMA);
reg(KEY_PERIOD, GLFW_KEY_PERIOD);
reg(KEY_SLASH, GLFW_KEY_SLASH);
reg(KEY_RSHIFT, GLFW_KEY_RIGHT_SHIFT);
reg(KEY_MULTIPLY, GLFW_KEY_KP_MULTIPLY);
reg(KEY_LMENU, GLFW_KEY_LEFT_ALT);
reg(KEY_SPACE, GLFW_KEY_SPACE);
reg(KEY_CAPITAL, GLFW_KEY_CAPS_LOCK);
reg(KEY_F1, GLFW_KEY_F1);
reg(KEY_F2, GLFW_KEY_F2);
reg(KEY_F3, GLFW_KEY_F3);
reg(KEY_F4, GLFW_KEY_F4);
reg(KEY_F5, GLFW_KEY_F5);
reg(KEY_F6, GLFW_KEY_F6);
reg(KEY_F7, GLFW_KEY_F7);
reg(KEY_F8, GLFW_KEY_F8);
reg(KEY_F9, GLFW_KEY_F9);
reg(KEY_F10, GLFW_KEY_F10);
reg(KEY_NUMLOCK, GLFW_KEY_NUM_LOCK);
reg(KEY_SCROLL, GLFW_KEY_SCROLL_LOCK);
reg(KEY_NUMPAD7, GLFW_KEY_KP_7);
reg(KEY_NUMPAD8, GLFW_KEY_KP_8);
reg(KEY_NUMPAD9, GLFW_KEY_KP_9);
reg(KEY_SUBTRACT, GLFW_KEY_KP_SUBTRACT);
reg(KEY_NUMPAD4, GLFW_KEY_KP_4);
reg(KEY_NUMPAD5, GLFW_KEY_KP_5);
reg(KEY_NUMPAD6, GLFW_KEY_KP_6);
reg(KEY_ADD, GLFW_KEY_KP_ADD);
reg(KEY_NUMPAD1, GLFW_KEY_KP_1);
reg(KEY_NUMPAD2, GLFW_KEY_KP_2);
reg(KEY_NUMPAD3, GLFW_KEY_KP_3);
reg(KEY_NUMPAD0, GLFW_KEY_KP_0);
reg(KEY_DECIMAL, GLFW_KEY_KP_DECIMAL);
reg(KEY_F11, GLFW_KEY_F11);
reg(KEY_F12, GLFW_KEY_F12);
reg(KEY_F13, GLFW_KEY_F13);
reg(KEY_F14, GLFW_KEY_F14);
reg(KEY_F15, GLFW_KEY_F15);
//reg(KEY_KANA, GLFW_KEY_);
//reg(KEY_CONVERT, GLFW_KEY_);
//reg(KEY_NOCONVERT, GLFW_KEY_);
//reg(KEY_YEN, GLFW_KEY_);
//reg(KEY_NUMPADEQUALS, GLFW_KEY_);
//reg(KEY_CIRCUMFLEX, GLFW_KEY_);
//reg(KEY_AT, GLFW_KEY_);
//reg(KEY_COLON, GLFW_KEY_);
//reg(KEY_UNDERLINE, GLFW_KEY_);
//reg(KEY_KANJI, GLFW_KEY_);
//reg(KEY_STOP, GLFW_KEY_);
//reg(KEY_AX, GLFW_KEY_);
//reg(KEY_UNLABELED, GLFW_KEY_);
reg(KEY_NUMPADENTER, GLFW_KEY_KP_ENTER);
reg(KEY_RCONTROL, GLFW_KEY_RIGHT_CONTROL);
//reg(KEY_NUMPADCOMMA, GLFW_KEY_);
reg(KEY_DIVIDE, GLFW_KEY_KP_DIVIDE);
reg(KEY_SYSRQ, GLFW_KEY_PRINT_SCREEN);
reg(KEY_RMENU, GLFW_KEY_RIGHT_ALT);
reg(KEY_PAUSE, GLFW_KEY_PAUSE);
reg(KEY_HOME, GLFW_KEY_HOME);
reg(KEY_UP, GLFW_KEY_UP);
reg(KEY_PRIOR, GLFW_KEY_PAGE_UP);
reg(KEY_LEFT, GLFW_KEY_LEFT);
reg(KEY_RIGHT, GLFW_KEY_RIGHT);
reg(KEY_END, GLFW_KEY_END);
reg(KEY_DOWN, GLFW_KEY_DOWN);
reg(KEY_NEXT, GLFW_KEY_PAGE_DOWN);
reg(KEY_INSERT, GLFW_KEY_INSERT);
reg(KEY_DELETE, GLFW_KEY_DELETE);
reg(KEY_LMETA, GLFW_KEY_LEFT_SUPER);
reg(KEY_RMETA, GLFW_KEY_RIGHT_SUPER);
}
public static int toJmeKeyCode(int glfwKey) {
return glfwToJmeKeyMap[glfwKey];
}
}

@ -38,16 +38,22 @@ import com.jme3.input.RawInputListener;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.system.lwjgl.LwjglWindow;
import com.jme3.util.BufferUtils;
import org.lwjgl.glfw.GLFWCursorPosCallback;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import org.lwjgl.glfw.GLFWScrollCallback;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.logging.Logger;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFWImage;
import org.lwjgl.system.MemoryUtil;
/**
* Captures mouse input using GLFW callbacks. It then temporarily stores these in event queues which are processed in the
@ -74,57 +80,70 @@ public class GlfwMouseInput implements MouseInput {
private Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<MouseMotionEvent>();
private Queue<MouseButtonEvent> mouseButtonEvents = new LinkedList<MouseButtonEvent>();
public GlfwMouseInput(final LwjglWindow context) {
private Map<JmeCursor, Long> jmeToGlfwCursorMap = new HashMap<JmeCursor, Long>();
public GlfwMouseInput(LwjglWindow context) {
this.context = context;
}
private void onCursorPos(long window, double xpos, double ypos) {
int xDelta;
int yDelta;
int x = (int) Math.round(xpos);
int y = context.getSettings().getHeight() - (int) Math.round(ypos);
if (mouseX == 0) {
mouseX = x;
}
if (mouseY == 0) {
mouseY = y;
}
xDelta = x - mouseX;
yDelta = y - mouseY;
mouseX = x;
mouseY = y;
if (xDelta != 0 || yDelta != 0) {
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(x, y, xDelta, yDelta, mouseWheel, 0);
mouseMotionEvent.setTime(getInputTimeNanos());
mouseMotionEvents.add(mouseMotionEvent);
}
}
private void onWheelScroll(long window, double xOffset, double yOffset) {
mouseWheel += yOffset;
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(mouseX, mouseY, 0, 0, mouseWheel, (int) Math.round(yOffset));
mouseMotionEvent.setTime(getInputTimeNanos());
mouseMotionEvents.add(mouseMotionEvent);
}
private void onMouseButton(final long window, final int button, final int action, final int mods) {
final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), action == GLFW_PRESS, mouseX, mouseY);
mouseButtonEvent.setTime(getInputTimeNanos());
mouseButtonEvents.add(mouseButtonEvent);
}
public void initialize() {
glfwSetCursorPosCallback(context.getWindowHandle(), cursorPosCallback = new GLFWCursorPosCallback() {
@Override
public void invoke(long window, double xpos, double ypos) {
int xDelta;
int yDelta;
int x = (int) Math.round(xpos);
int y = context.getSettings().getHeight() - (int) Math.round(ypos);
if (mouseX == 0) {
mouseX = x;
}
if (mouseY == 0) {
mouseY = y;
}
xDelta = x - mouseX;
yDelta = y - mouseY;
mouseX = x;
mouseY = y;
if (xDelta != 0 || yDelta != 0) {
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(x, y, xDelta, yDelta, mouseWheel, 0);
mouseMotionEvent.setTime(getInputTimeNanos());
mouseMotionEvents.add(mouseMotionEvent);
}
onCursorPos(window, xpos, ypos);
}
});
glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
@Override
public void invoke(final long window, final double xOffset, final double yOffset) {
mouseWheel += yOffset;
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(mouseX, mouseY, 0, 0, mouseWheel, (int) Math.round(yOffset));
mouseMotionEvent.setTime(getInputTimeNanos());
mouseMotionEvents.add(mouseMotionEvent);
onWheelScroll(window, xOffset, yOffset);
}
});
glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(final long window, final int button, final int action, final int mods) {
final MouseButtonEvent mouseButtonEvent = new MouseButtonEvent(convertButton(button), action == GLFW_PRESS, mouseX, mouseY);
mouseButtonEvent.setTime(getInputTimeNanos());
mouseButtonEvents.add(mouseButtonEvent);
onMouseButton(window, button, action, mods);
}
});
@ -160,6 +179,10 @@ public class GlfwMouseInput implements MouseInput {
scrollCallback.release();
mouseButtonCallback.release();
for (long glfwCursor : jmeToGlfwCursorMap.values()) {
glfwDestroyCursor(glfwCursor);
}
logger.fine("Mouse destroyed.");
}
@ -185,31 +208,52 @@ public class GlfwMouseInput implements MouseInput {
return (long) (glfwGetTime() * 1000000000);
}
public void setNativeCursor(final JmeCursor jmeCursor) {
private long createGlfwCursor(JmeCursor jmeCursor) {
GLFWImage glfwImage = new GLFWImage(BufferUtils.createByteBuffer(GLFWImage.SIZEOF));
// TODO: currently animated cursors are not supported
IntBuffer imageData = jmeCursor.getImagesData();
ByteBuffer buf = BufferUtils.createByteBuffer(imageData.capacity());
buf.asIntBuffer().put(imageData);
glfwImage.set(jmeCursor.getWidth(), jmeCursor.getHeight(), buf);
return glfwCreateCursor(glfwImage, jmeCursor.getXHotSpot(), jmeCursor.getYHotSpot());
}
public void setNativeCursor(JmeCursor jmeCursor) {
if (jmeCursor != null) {
final ByteBuffer byteBuffer = org.lwjgl.BufferUtils.createByteBuffer(jmeCursor.getImagesData().capacity());
byteBuffer.asIntBuffer().put(jmeCursor.getImagesData().array());
final long cursor = glfwCreateCursor(byteBuffer, jmeCursor.getXHotSpot(), jmeCursor.getYHotSpot());
glfwSetCursor(context.getWindowHandle(), cursor);
Long glfwCursor = jmeToGlfwCursorMap.get(jmeCursor);
if (glfwCursor == null) {
glfwCursor = createGlfwCursor(jmeCursor);
jmeToGlfwCursorMap.put(jmeCursor, glfwCursor);
}
glfwSetCursor(context.getWindowHandle(), glfwCursor);
} else {
glfwSetCursor(context.getWindowHandle(), MemoryUtil.NULL);
}
}
/**
* Simply converts the GLFW button code to a JME button code. If there is no match it just returns the GLFW button
* code. Bare in mind GLFW supports 8 different mouse buttons.
* Simply converts the GLFW button code to a JME button code. If there is no
* match it just returns the GLFW button code. Bear in mind GLFW supports 8
* different mouse buttons.
*
* @param glfwButton the raw GLFW button index.
* @return the mapped {@link MouseInput} button id.
*/
private int convertButton(final int glfwButton) {
if (glfwButton == GLFW_MOUSE_BUTTON_LEFT) {
return MouseInput.BUTTON_LEFT;
} else if(glfwButton == GLFW_MOUSE_BUTTON_MIDDLE) {
return MouseInput.BUTTON_MIDDLE;
} else if(glfwButton == GLFW_MOUSE_BUTTON_RIGHT) {
return MouseInput.BUTTON_RIGHT;
switch (glfwButton) {
case GLFW_MOUSE_BUTTON_LEFT:
return MouseInput.BUTTON_LEFT;
case GLFW_MOUSE_BUTTON_MIDDLE:
return MouseInput.BUTTON_MIDDLE;
case GLFW_MOUSE_BUTTON_RIGHT:
return MouseInput.BUTTON_RIGHT;
default:
return glfwButton;
}
return glfwButton;
}
}

@ -43,9 +43,7 @@ import com.jme3.renderer.lwjgl.LwjglGLFboEXT;
import com.jme3.renderer.lwjgl.LwjglGLFboGL3;
import com.jme3.renderer.opengl.*;
import com.jme3.system.*;
import org.lwjgl.Sys;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.ARBDebugOutput;
import org.lwjgl.opengl.ARBFramebufferObject;
import org.lwjgl.opengl.EXTFramebufferMultisample;
import org.lwjgl.opengl.GLCapabilities;
@ -53,9 +51,10 @@ import org.lwjgl.opengl.GLCapabilities;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import org.lwjgl.opengl.ARBDebugOutput;
import static org.lwjgl.opengl.GL.createCapabilities;
import static org.lwjgl.opengl.GL11.GL_TRUE;
import static org.lwjgl.opengl.GL11.glGetInteger;
/**
@ -84,40 +83,22 @@ public abstract class LwjglContext implements JmeContext {
}
protected void printContextInitInfo() {
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n" +
" * Graphics Adapter: GLFW {2}",
new Object[]{Sys.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
+ " * Graphics Adapter: GLFW {2}",
new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
}
protected int determineMaxSamples() {
// If we already have a valid context, determine samples using current context.
if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object") == GL_TRUE) {
if (GLFW.glfwExtensionSupported("GL_ARB_framebuffer_object") == GLFW_TRUE) {
return glGetInteger(ARBFramebufferObject.GL_MAX_SAMPLES);
} else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample") == GL_TRUE) {
} else if (GLFW.glfwExtensionSupported("GL_EXT_framebuffer_multisample") == GLFW_TRUE) {
return glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT);
}
return Integer.MAX_VALUE;
}
protected void loadNatives() {
if (JmeSystem.isLowPermissions()) {
return;
}
if ("LWJGL".equals(settings.getAudioRenderer())) {
NativeLibraryLoader.loadNativeLibrary("openal-lwjgl3", true);
}
if (NativeLibraryLoader.isUsingNativeBullet()) {
NativeLibraryLoader.loadNativeLibrary("bulletjme", true);
}
NativeLibraryLoader.loadNativeLibrary("glfw-lwjgl3", true);
NativeLibraryLoader.loadNativeLibrary("jemalloc-lwjgl3", true);
NativeLibraryLoader.loadNativeLibrary("lwjgl3", true);
}
protected int getNumSamplesToUse() {
int samples = 0;
if (settings.getSamples() > 1) {
@ -135,6 +116,17 @@ public abstract class LwjglContext implements JmeContext {
return samples;
}
protected void loadNatives() {
if (JmeSystem.isLowPermissions()) {
return;
}
if (NativeLibraryLoader.isUsingNativeBullet()) {
NativeLibraryLoader.loadNativeLibrary("bulletjme", true);
}
}
protected void initContextFirstTime() {
final GLCapabilities capabilities = createCapabilities(settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3));
@ -180,11 +172,11 @@ public abstract class LwjglContext implements JmeContext {
}
if (capabilities.GL_ARB_debug_output && settings.getBoolean("GraphicsDebug")) {
ARBDebugOutput.glDebugMessageCallbackARB(new LwjglGLDebugOutputHandler(), 0); // User param is zero. Not sure what we could use that for.
ARBDebugOutput.glDebugMessageCallbackARB(new LwjglGLDebugOutputHandler(), 0);
}
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection());
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection());
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
// Init input
if (keyInput != null) {
@ -198,7 +190,6 @@ public abstract class LwjglContext implements JmeContext {
if (joyInput != null) {
joyInput.initialize();
}
renderable.set(true);
}
@ -240,26 +231,32 @@ public abstract class LwjglContext implements JmeContext {
}
}
@Override
public boolean isCreated() {
return created.get();
}
@Override
public boolean isRenderable() {
return renderable.get();
}
@Override
public void setSettings(AppSettings settings) {
this.settings.copyFrom(settings);
}
@Override
public AppSettings getSettings() {
return settings;
}
@Override
public Renderer getRenderer() {
return renderer;
}
@Override
public Timer getTimer() {
return timer;
}

@ -43,7 +43,6 @@ import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.JmeSystem;
import com.jme3.system.NanoTimer;
import org.lwjgl.Sys;
import org.lwjgl.glfw.*;
import java.awt.*;
@ -52,6 +51,7 @@ import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.Version;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.GL_FALSE;
@ -72,7 +72,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
protected boolean wasActive = false;
protected boolean autoFlush = true;
protected boolean allowSwapBuffers = false;
private long window = -1;
private long window = NULL;
private final JmeContext.Type type;
private int frameRateLimit = -1;
private double frameSleepTime;
@ -81,6 +81,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
private GLFWWindowSizeCallback windowSizeCallback;
private GLFWWindowFocusCallback windowFocusCallback;
private Thread mainThread;
public LwjglWindow(final JmeContext.Type type) {
if (!JmeContext.Type.Display.equals(type) && !JmeContext.Type.OffscreenSurface.equals(type) && !JmeContext.Type.Canvas.equals(type)) {
throw new IllegalArgumentException("Unsupported type '" + type.name() + "' provided");
@ -102,7 +104,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
* @param title the title to set
*/
public void setTitle(final String title) {
if (created.get() && window != -1) {
if (created.get() && window != NULL) {
glfwSetWindowTitle(window, title);
}
}
@ -127,45 +129,45 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() {
@Override
public void invoke(int error, long description) {
final String message = Callbacks.errorCallbackDescriptionString(description);
final String message = GLFWErrorCallback.getDescription(description);
listener.handleError(message, new Exception(message));
}
});
if (glfwInit() != GL_TRUE) {
if (glfwInit() != GLFW_TRUE) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
// TODO: Add support for monitor selection
long monitor = NULL;
if (settings.isFullscreen()) {
monitor = glfwGetPrimaryMonitor();
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
} else {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
}
final ByteBuffer videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
if (settings.getWidth() <= 0 || settings.getHeight() <= 0) {
settings.setResolution(GLFWvidmode.width(videoMode), GLFWvidmode.height(videoMode));
if (settings.getBoolean("RendererDebug")) {
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
}
window = glfwCreateWindow(settings.getWidth(), settings.getHeight(), settings.getTitle(), monitor, NULL);
if (window == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
if (settings.isGammaCorrection()) {
glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
}
glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GL_TRUE : GL_FALSE);
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GLFW_TRUE : GLFW_FALSE);
glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits());
glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits());
glfwWindowHint(GLFW_SAMPLES, settings.getSamples());
glfwWindowHint(GLFW_STEREO, settings.useStereo3D() ? GL_TRUE : GL_FALSE);
glfwWindowHint(GLFW_STEREO, settings.useStereo3D() ? GLFW_TRUE : GLFW_FALSE);
glfwWindowHint(GLFW_REFRESH_RATE, settings.getFrequency());
// Not sure how else to support bits per pixel
if (settings.getBitsPerPixel() == 24) {
glfwWindowHint(GLFW_RED_BITS, 8);
glfwWindowHint(GLFW_GREEN_BITS, 8);
@ -178,11 +180,38 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
glfwWindowHint(GLFW_ALPHA_BITS, settings.getAlphaBits());
// TODO: Add support for monitor selection
long monitor = NULL;
if (settings.isFullscreen()) {
monitor = glfwGetPrimaryMonitor();
}
final GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
if (settings.getWidth() <= 0 || settings.getHeight() <= 0) {
settings.setResolution(videoMode.width(), videoMode.height());
}
window = glfwCreateWindow(settings.getWidth(), settings.getHeight(), settings.getTitle(), monitor, NULL);
if (window == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
// Add a resize callback which delegates to the listener
glfwSetWindowSizeCallback(window, windowSizeCallback = new GLFWWindowSizeCallback() {
@Override
public void invoke(final long window, final int width, final int height) {
settings.setResolution(width, height);
listener.reshape(width, height);
}
});
glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() {
@Override
public void invoke(final long window, final int focused) {
final boolean focus = (focused == GL_TRUE);
if (wasActive != focus) {
if (!wasActive) {
listener.gainFocus();
@ -197,8 +226,10 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
});
// Center the window
if (!settings.isFullscreen() && Type.Display.equals(type)) {
glfwSetWindowPos(window, (GLFWvidmode.width(videoMode) - settings.getWidth()) / 2, (GLFWvidmode.height(videoMode) - settings.getHeight()) / 2);
if (!settings.isFullscreen()) {
glfwSetWindowPos(window,
(videoMode.width() - settings.getWidth()) / 2,
(videoMode.height() - settings.getHeight()) / 2);
}
// Make the OpenGL context current
@ -211,19 +242,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
glfwSwapInterval(0);
}
// Make the window visible
if (Type.Display.equals(type)) {
glfwShowWindow(window);
}
// Add a resize callback which delegates to the listener
glfwSetWindowSizeCallback(window, windowSizeCallback = new GLFWWindowSizeCallback() {
@Override
public void invoke(final long window, final int width, final int height) {
settings.setResolution(width, height);
listener.reshape(width, height);
}
});
glfwShowWindow(window);
allowSwapBuffers = settings.isSwapBuffers();
@ -239,29 +259,40 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
renderer.cleanup();
}
errorCallback.release();
windowSizeCallback.release();
windowFocusCallback.release();
if (errorCallback != null) {
errorCallback.release();
errorCallback = null;
}
if (windowSizeCallback != null) {
windowSizeCallback.release();
windowSizeCallback = null;
}
if (windowFocusCallback != null) {
windowFocusCallback.release();
windowFocusCallback = null;
}
if (window != 0) {
if (window != NULL) {
glfwDestroyWindow(window);
window = NULL;
}
} catch (Exception ex) {
listener.handleError("Failed to destroy context", ex);
}
}
@Override
public void create(boolean waitFor) {
if (created.get()) {
LOGGER.warning("create() called when display is already created!");
return;
}
new Thread(this, THREAD_NAME).start();
if (waitFor) {
waitFor(true);
}
// NOTE: this is required for Mac OS X!
mainThread = Thread.currentThread();
run();
}
/**
@ -272,6 +303,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
if (!JmeSystem.isLowPermissions()) {
// Enable uncaught exception handler only for current thread
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable thrown) {
listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown);
if (needClose.get()) {
@ -283,6 +315,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
});
}
loadNatives();
timer = new NanoTimer();
// For canvas, this will create a pbuffer,
@ -296,8 +330,9 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
super.internalCreate();
} catch (Exception ex) {
try {
if (window != -1) {
if (window != NULL) {
glfwDestroyWindow(window);
window = NULL;
}
} catch (Exception ex2) {
LOGGER.log(Level.WARNING, null, ex2);
@ -318,6 +353,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
// If a restart is required, lets recreate the context.
if (needRestart.getAndSet(false)) {
try {
destroyContext();
createContext(settings);
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Failed to set display settings!", ex);
@ -346,8 +382,6 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
}
}
glfwPollEvents();
// Subclasses just call GLObjectManager clean up objects here
// it is safe .. for now.
if (renderer != null) {
@ -377,6 +411,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
}
}
}
glfwPollEvents();
}
private void setFrameRateLimit(int frameRateLimit) {
@ -389,21 +425,22 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
*/
protected void deinitInThread() {
listener.destroy();
destroyContext();
super.internalDestroy();
listener.destroy();
LOGGER.fine("Display destroyed.");
super.internalDestroy();
}
@Override
public void run() {
if (listener == null) {
throw new IllegalStateException("SystemListener is not set on context!"
+ "Must set with JmeContext.setSystemListener().");
}
loadNatives();
LOGGER.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion());
LOGGER.log(Level.FINE, "Using LWJGL {0}", Version.getVersion());
if (!initInThread()) {
LOGGER.log(Level.SEVERE, "Display initialization failed. Cannot continue.");
@ -411,15 +448,16 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
}
while (true) {
if (glfwWindowShouldClose(window) == GL_TRUE) {
listener.requestClose(false);
}
runLoop();
if (needClose.get()) {
break;
}
if (glfwWindowShouldClose(window) == GL_TRUE) {
listener.requestClose(false);
}
}
deinitInThread();
@ -458,6 +496,11 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
public void destroy(boolean waitFor) {
needClose.set(true);
if (mainThread == Thread.currentThread()) {
// Ignore waitFor.
return;
}
if (waitFor) {
waitFor(false);
}

@ -301,35 +301,38 @@ public class DefaultClient implements Client
protected void closeConnections( DisconnectInfo info )
{
if( !isRunning )
return;
if( services.isStarted() ) {
// Let the services get a chance to stop before we
// kill the connection.
services.stop();
}
synchronized(this) {
if( !isRunning )
return;
if( services.isStarted() ) {
// Let the services get a chance to stop before we
// kill the connection.
services.stop();
}
// Send a close message
// Send a close message
// Tell the thread it's ok to die
for( ConnectorAdapter ca : channels ) {
if( ca == null )
continue;
ca.close();
}
// Tell the thread it's ok to die
for( ConnectorAdapter ca : channels ) {
if( ca == null )
continue;
ca.close();
}
// Wait for the threads?
// Wait for the threads?
// Just in case we never fully connected
connecting.countDown();
// Just in case we never fully connected
connecting.countDown();
fireDisconnected(info);
isRunning = false;
isRunning = false;
// Terminate the services
services.terminate();
}
// Terminate the services
services.terminate();
// Make sure we aren't synched while firing events
fireDisconnected(info);
}
@Override
@ -462,11 +465,17 @@ public class DefaultClient implements Client
this.id = (int)crm.getId();
log.log( Level.FINE, "Connection established, id:{0}.", this.id );
connecting.countDown();
fireConnected();
//fireConnected();
} else {
// Else it's a message letting us know that the
// hosted services have been started
startServices();
// Delay firing 'connected' until the services have all
// been started to avoid odd race conditions. If there is some
// need to get some kind of event before the services have been
// started then we should create a new event step.
fireConnected();
}
return;
} else if( m instanceof ChannelInfoMessage ) {

@ -608,7 +608,7 @@ public class DefaultServer implements Server
// should always already be closed through all paths that I
// can conceive... but it doesn't hurt to be sure.
for( Endpoint p : channels ) {
if( p == null )
if( p == null || !p.isConnected() )
continue;
p.close();
}

@ -112,6 +112,8 @@ public class KernelAdapter extends Thread
// Kill the kernel
kernel.terminate();
join();
}
protected void reportError( Endpoint p, Object context, Exception e )
@ -120,8 +122,10 @@ public class KernelAdapter extends Thread
// retrieve them. For now we'll just log it. FIXME
log.log( Level.SEVERE, "Unhandled error, endpoint:" + p + ", context:" + context, e );
// In lieu of other options, at least close the endpoint
p.close();
if( p.isConnected() ) {
// In lieu of other options, at least close the endpoint
p.close();
}
}
protected HostedConnection getConnection( Endpoint p )

@ -181,7 +181,7 @@ public class MessageProtocol
Message m = (Message)obj;
messages.add(m);
} catch( IOException e ) {
throw new RuntimeException( "Error deserializing object, clas ID:" + buffer.getShort(0), e );
throw new RuntimeException( "Error deserializing object, class ID:" + buffer.getShort(0), e );
}
}
}

@ -76,6 +76,18 @@ public abstract class AbstractKernel implements Kernel
log.log( Level.SEVERE, "Unhanddled kernel error", e );
}
protected void wakeupReader() {
// If there are no pending messages then add one so that the
// kernel-user knows to wake up if it is only listening for
// envelopes.
if( !hasEnvelopes() ) {
// Note: this is not really a race condition. At worst, our
// event has already been handled by now and it does no harm
// to check again.
addEnvelope( EVENTS_PENDING );
}
}
protected long nextEndpointId()
{
return nextId.getAndIncrement();

@ -106,6 +106,9 @@ public class SelectorKernel extends AbstractKernel
try {
thread.close();
thread = null;
// Need to let any caller waiting for a read() wakeup
wakeupReader();
} catch( IOException e ) {
throw new KernelException( "Error closing host connection:" + address, e );
}
@ -164,15 +167,7 @@ public class SelectorKernel extends AbstractKernel
// Enqueue an endpoint event for the listeners
addEvent( EndpointEvent.createRemove( this, p ) );
// If there are no pending messages then add one so that the
// kernel-user knows to wake up if it is only listening for
// envelopes.
if( !hasEnvelopes() ) {
// Note: this is not really a race condition. At worst, our
// event has already been handled by now and it does no harm
// to check again.
addEnvelope( EVENTS_PENDING );
}
wakeupReader();
}
/**

@ -110,6 +110,9 @@ public class UdpKernel extends AbstractKernel
thread.close();
writer.shutdown();
thread = null;
// Need to let any caller waiting for a read() wakeup
wakeupReader();
} catch( IOException e ) {
throw new KernelException( "Error closing host connection:" + address, e );
}
@ -170,15 +173,7 @@ public class UdpKernel extends AbstractKernel
addEvent( EndpointEvent.createRemove( this, p ) );
// If there are no pending messages then add one so that the
// kernel-user knows to wake up if it is only listening for
// envelopes.
if( !hasEnvelopes() ) {
// Note: this is not really a race condition. At worst, our
// event has already been handled by now and it does no harm
// to check again.
addEnvelope( EVENTS_PENDING );
}
wakeupReader();
}
protected void newData( DatagramPacket packet )

@ -146,15 +146,17 @@ public class SerializerRegistrationsMessage extends AbstractMessage {
// that also run their own servers but realistically they would have
// to disable the ServerSerializerRegistrationsServer anyway.
if( compiled != null ) {
log.log( Level.INFO, "Skipping registration as registry is locked, presumably by a local server process.");
log.log(Level.INFO, "Skipping registration as registry is locked, presumably by a local server process.");
return;
}
}
log.log(Level.FINE, "Registering {0} classes...", registrations.length);
for( Registration reg : registrations ) {
log.log( Level.INFO, "Registering:{0}", reg);
log.log(Level.INFO, "Registering:{0}", reg);
reg.register();
}
log.log(Level.FINE, "Done registering serializable classes.");
}
@Serializable
@ -187,7 +189,7 @@ public class SerializerRegistrationsMessage extends AbstractMessage {
serializer = (Serializer)serializerType.newInstance();
}
SerializerRegistration result = Serializer.registerClassForId(id, type, serializer);
log.log( Level.FINE, " result:{0}", result);
log.log(Level.FINE, " result:{0}", result);
} catch( ClassNotFoundException e ) {
throw new RuntimeException( "Class not found attempting to register:" + this, e );
} catch( InstantiationException e ) {

@ -425,6 +425,22 @@ public abstract class Serializer {
return;
}
SerializerRegistration reg = writeClass(buffer, object.getClass());
// If the caller (or us) has registered a generic base class (like Enum)
// that is meant to steer automatic resolution for things like FieldSerializer
// that have final classes in fields... then there are cases where the exact
// type isn't known by the outer class. (Think of a message object
// that has an Object field but tries to send an Enum subclass in it.)
// In that case, the SerializerRegistration object we get back isn't
// really going to be capable of recreating the object on the other
// end because it won't know what class to use. This only comes up
// in writeclassAndObejct() because we just wrote an ID to a more generic
// class than will be readable on the other end. The check is simple, though.
if( reg.getType() != object.getClass() ) {
throw new IllegalArgumentException("Class has not been registered:"
+ object.getClass() + " but resolved to generic serializer for:" + reg.getType());
}
reg.getSerializer().writeObject(buffer, object);
}

@ -48,8 +48,9 @@ public class EnumSerializer extends Serializer {
if (ordinal == -1) return null;
T[] enumConstants = c.getEnumConstants();
if (enumConstants == null)
throw new SerializerException( "Class has no enum constants:" + c );
if (enumConstants == null) {
throw new SerializerException("Class has no enum constants:" + c + " Ordinal:" + ordinal);
}
return enumConstants[ordinal];
} catch (IndexOutOfBoundsException ex) {
return null;

@ -34,11 +34,14 @@ package com.jme3.network.serializing.serializers;
import com.jme3.network.serializing.Serializer;
import com.jme3.network.serializing.SerializerException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* The field serializer is the default serializer used for custom class.
@ -46,16 +49,35 @@ import java.util.*;
* @author Lars Wesselius, Nathan Sweet
*/
public class FieldSerializer extends Serializer {
static final Logger log = Logger.getLogger(FieldSerializer.class.getName());
private static Map<Class, SavedField[]> savedFields = new HashMap<Class, SavedField[]>();
private static Map<Class, Constructor> savedCtors = new HashMap<Class, Constructor>();
protected void checkClass(Class clazz) {
// See if the class has a public no-arg constructor
try {
clazz.getConstructor();
savedCtors.put(clazz, clazz.getConstructor());
return;
} catch( NoSuchMethodException e ) {
throw new RuntimeException( "Registration error: no-argument constructor not found on:" + clazz );
//throw new RuntimeException( "Registration error: no-argument constructor not found on:" + clazz );
}
// See if it has a non-public no-arg constructor
try {
Constructor ctor = clazz.getDeclaredConstructor();
// Make sure we can call it later.
ctor.setAccessible(true);
savedCtors.put(clazz, ctor);
return;
} catch( NoSuchMethodException e ) {
}
throw new RuntimeException( "Registration error: no-argument constructor not found on:" + clazz );
}
public void initialize(Class clazz) {
@ -121,7 +143,8 @@ public class FieldSerializer extends Serializer {
T object;
try {
object = c.newInstance();
Constructor<T> ctor = (Constructor<T>)savedCtors.get(c);
object = ctor.newInstance();
} catch (Exception e) {
throw new SerializerException( "Error creating object of type:" + c, e );
}
@ -129,6 +152,9 @@ public class FieldSerializer extends Serializer {
for (SavedField savedField : fields) {
Field field = savedField.field;
Serializer serializer = savedField.serializer;
if( log.isLoggable(Level.FINER) ) {
log.log(Level.FINER, "Reading field:{0} using serializer:{1}", new Object[]{field, serializer});
}
Object value;
if (serializer != null) {
@ -164,9 +190,12 @@ public class FieldSerializer extends Serializer {
try {
val = savedField.field.get(object);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new SerializerException("Unable to access field:" + savedField.field + " on:" + object, e);
}
Serializer serializer = savedField.serializer;
if( log.isLoggable(Level.FINER) ) {
log.log(Level.FINER, "Writing field:{0} using serializer:{1}", new Object[]{savedField.field, serializer});
}
try {
if (serializer != null) {

@ -351,6 +351,11 @@ public class RmiRegistry {
}
public Object invoke( short procId, Object[] args ) {
if( log.isLoggable(Level.FINEST) ) {
log.finest("SharedObject->invoking:" + classInfo.getMethod(procId)
+ " on:" + object
+ " with:" + (args == null ? "null" : Arrays.asList(args)));
}
return classInfo.getMethod(procId).invoke(object, args);
}
}

@ -1 +0,0 @@
X-Comment: Created with jMonkeyPlatform

@ -1,76 +0,0 @@
<?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="BasicGameTemplate" default="default" basedir=".">
<description>Builds, tests, and runs the project BasicGameTemplate.</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-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
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="BasicGameTemplate-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>

@ -1,22 +0,0 @@
<jnlp spec="1.0+" codebase="${jnlp.codebase}" href="launch.jnlp">
<information>
<title>${APPLICATION.TITLE}</title>
<vendor>${APPLICATION.VENDOR}</vendor>
<homepage href="${APPLICATION.HOMEPAGE}"/>
<description>${APPLICATION.DESC}</description>
<description kind="short">${APPLICATION.DESC.SHORT}</description>
<!--${JNLP.ICONS}-->
<!--${JNLP.OFFLINE.ALLOWED}-->
</information>
<!--${JNLP.SECURITY}-->
<resources>
<!--${JNLP.RESOURCES.RUNTIME}-->
<!--${JNLP.RESOURCES.MAIN.JAR}-->
<!--${JNLP.RESOURCES.JARS}-->
<jar href='lib/assets.jar'/>
<!--${JNLP.RESOURCES.EXTENSIONS}-->
</resources>
<application-desc main-class="${jnlp.main.class}">
<!--${JNLP.APPLICATION.ARGS}-->
</application-desc>
</jnlp>

@ -1,8 +0,0 @@
build.xml.data.CRC32=94bf7c61
build.xml.script.CRC32=79a29eb7
build.xml.stylesheet.CRC32=958a1d3e@1.32.1.45
# 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=1ac6e2f9
nbproject/build-impl.xml.script.CRC32=28b1a2c2
nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48

@ -1,92 +0,0 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
application.title=MyGame
application.vendor=MyCompany
assets.jar.name=assets.jar
assets.excludes=**/*.j3odata,**/*.mesh,**/*.skeleton,**/*.mesh\.xml,**/*.skeleton\.xml,**/*.scene,**/*.material,**/*.obj,**/*.mtl,**/*.3ds,**/*.dae,**/*.blend,**/*.blend*[0-9]
assets.folder.name=assets
assets.compress=true
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
compile.on.save=true
# 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}/${application.title}.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-jbullet.classpath}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
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.codebase.type=local
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
main.class=mygame.Main
meta.inf.dir=${src.dir}/META-INF
manifest.file=MANIFEST.MF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${assets.folder.name}
# 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

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1">
<extension file="assets-impl.xml" id="assets">
<dependency dependsOn="-init-assets" target="-do-init"/>
</extension>
</buildExtensions>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>BasicGameTemplate</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>

@ -1,43 +0,0 @@
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/**
* test
* @author normenhansen
*/
public class Main extends SimpleApplication {
public static void main(String[] args) {
Main app = new Main();
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.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
rootNode.attachChild(geom);
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}

@ -1,73 +0,0 @@
<?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="JME3TestsTemplate" default="default" basedir=".">
<description>Builds, tests, and runs the project JME3TestsTemplate.</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="JME3TestsTemplate-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>

@ -1,880 +0,0 @@
<?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>

@ -1,8 +0,0 @@
build.xml.data.CRC32=0f706f4a
build.xml.script.CRC32=82b8b23d
build.xml.stylesheet.CRC32=8064a381@1.75.2.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

@ -1,83 +0,0 @@
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-jbullet.classpath}:\
${libs.jme3-test-data.classpath}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.source=1.6
javac.target=1.6
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

@ -1,13 +0,0 @@
<?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>JME3TestsTemplate</name>
<source-roots>
<root id="src.dir" name="JME3 Examples"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>

@ -1 +0,0 @@
X-Comment: Created with jMonkeyPlatform

@ -1,76 +0,0 @@
<?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="BasicGameTemplate" default="default" basedir=".">
<description>Builds, tests, and runs the project BasicGameTemplate.</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-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
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="BasicGameTemplate-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>

@ -1,22 +0,0 @@
<jnlp spec="1.0+" codebase="${jnlp.codebase}" href="launch.jnlp">
<information>
<title>${APPLICATION.TITLE}</title>
<vendor>${APPLICATION.VENDOR}</vendor>
<homepage href="${APPLICATION.HOMEPAGE}"/>
<description>${APPLICATION.DESC}</description>
<description kind="short">${APPLICATION.DESC.SHORT}</description>
<!--${JNLP.ICONS}-->
<!--${JNLP.OFFLINE.ALLOWED}-->
</information>
<!--${JNLP.SECURITY}-->
<resources>
<!--${JNLP.RESOURCES.RUNTIME}-->
<!--${JNLP.RESOURCES.MAIN.JAR}-->
<!--${JNLP.RESOURCES.JARS}-->
<jar href='lib/assets.jar'/>
<!--${JNLP.RESOURCES.EXTENSIONS}-->
</resources>
<application-desc main-class="${jnlp.main.class}">
<!--${JNLP.APPLICATION.ARGS}-->
</application-desc>
</jnlp>

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.jmonkeyengine.tests">
<application android:label="@string/app_name">
<activity android:label="@string/app_name" android:name="MainActivity" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:label="@string/app_name" android:name="TestsHarness" android:launchMode="singleTask" android:screenOrientation="landscape">
</activity>
</application>
<uses-sdk android:minSdkVersion="8"/>
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
</manifest>

@ -1,17 +0,0 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked into Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="jMonkeyEngine Test Applications" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

@ -1,20 +0,0 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

@ -1,14 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MainActivity"
/>
</LinearLayout>

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

Loading…
Cancel
Save