Merged with master after pull.
This commit is contained in:
commit
e530fa644b
@ -25,7 +25,6 @@ install:
|
|||||||
script:
|
script:
|
||||||
- ./gradlew check
|
- ./gradlew check
|
||||||
- ./gradlew createZipDistribution
|
- ./gradlew createZipDistribution
|
||||||
- "[ $TRAVIS_BRANCH == 'master' ] && [ $TRAVIS_PULL_REQUEST == 'false' ] && ./gradlew uploadArchives || :"
|
|
||||||
|
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- export RELEASE_DIST=$(ls build/distributions/*.zip)
|
- 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
|
# wget http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin -O ndk.bin
|
||||||
# 7z x ndk.bin -y > /dev/null
|
# 7z x ndk.bin -y > /dev/null
|
||||||
# export ANDROID_NDK=`pwd`/android-ndk-r10c
|
# 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 || :'
|
||||||
|
29
bintray.gradle
Normal file
29
bintray.gradle
Normal file
@ -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 {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.1.0'
|
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 {
|
subprojects {
|
||||||
if(!project.name.equals('jme3-android-examples')) {
|
if(!project.name.equals('jme3-android-examples')) {
|
||||||
apply from: rootProject.file('common.gradle')
|
apply from: rootProject.file('common.gradle')
|
||||||
|
if (!['jme3-testdata', 'sdk'].contains(project.name)) {
|
||||||
|
apply from: rootProject.file('bintray.gradle')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
apply from: rootProject.file('common-android-app.gradle')
|
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'
|
title = 'jMonkeyEngine3'
|
||||||
destinationDir = mkdir("dist/javadoc")
|
destinationDir = mkdir("dist/javadoc")
|
||||||
|
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
|
||||||
// Allows Javadoc to be generated on Java 8 despite doclint errors.
|
// Allows Javadoc to be generated on Java 8 despite doclint errors.
|
||||||
if (JavaVersion.current().isJava8Compatible()) {
|
if (JavaVersion.current().isJava8Compatible()) {
|
||||||
options.addStringOption('Xdoclint:none', '-quiet')
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
|
|
||||||
group = 'com.jme3'
|
group = 'org.jmonkeyengine'
|
||||||
version = jmePomVersion
|
version = jmePomVersion
|
||||||
|
|
||||||
sourceCompatibility = '1.6'
|
sourceCompatibility = '1.6'
|
||||||
@ -61,12 +61,53 @@ task javadocJar(type: Jar, dependsOn: javadoc, description: 'Creates a jar from
|
|||||||
from javadoc.destinationDir
|
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 {
|
artifacts {
|
||||||
archives jar
|
archives jar
|
||||||
archives sourcesJar
|
archives sourcesJar
|
||||||
if(buildJavaDoc == "true"){
|
if(buildJavaDoc == "true"){
|
||||||
archives javadocJar
|
archives javadocJar
|
||||||
}
|
}
|
||||||
|
archives writeFullPom.outputs.files[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadArchives {
|
uploadArchives {
|
||||||
@ -80,23 +121,7 @@ uploadArchives {
|
|||||||
authentication(userName: "www-updater", privateKey: "private/www-updater.key")
|
authentication(userName: "www-updater", privateKey: "private/www-updater.key")
|
||||||
}
|
}
|
||||||
|
|
||||||
pom.project {
|
pom.project pomConfig
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ jmeVersionTagID = 0
|
|||||||
buildJavaDoc = true
|
buildJavaDoc = true
|
||||||
|
|
||||||
# specify if SDK and Native libraries get built
|
# specify if SDK and Native libraries get built
|
||||||
buildSdkProject = true
|
|
||||||
buildNativeProjects = false
|
buildNativeProjects = false
|
||||||
buildAndroidExamples = 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_NAME=New BSD (3-clause) License
|
||||||
POM_LICENSE_URL=http://opensource.org/licenses/BSD-3-Clause
|
POM_LICENSE_URL=http://opensource.org/licenses/BSD-3-Clause
|
||||||
POM_LICENSE_DISTRIBUTION=repo
|
POM_LICENSE_DISTRIBUTION=repo
|
||||||
|
|
||||||
|
# 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.FileBlockHeader.BlockCode;
|
||||||
import com.jme3.scene.plugins.blender.file.Structure;
|
import com.jme3.scene.plugins.blender.file.Structure;
|
||||||
import com.jme3.scene.plugins.blender.materials.MaterialContext;
|
import com.jme3.scene.plugins.blender.materials.MaterialContext;
|
||||||
|
import com.jme3.scene.plugins.blender.meshes.TemporalMesh;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -389,11 +390,11 @@ public class BlenderContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if("ME".equals(namePrefix)) {
|
} else if("ME".equals(namePrefix)) {
|
||||||
List<Node> features = (List<Node>) linkedFeatures.get("meshes");
|
List<TemporalMesh> temporalMeshes = (List<TemporalMesh>) linkedFeatures.get("meshes");
|
||||||
if(features != null) {
|
if(temporalMeshes != null) {
|
||||||
for(Node feature : features) {
|
for(TemporalMesh temporalMesh : temporalMeshes) {
|
||||||
if(featureName.equals(feature.getName())) {
|
if(featureName.equals(temporalMesh.getName())) {
|
||||||
return feature;
|
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.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||||
import com.jme3.scene.plugins.blender.file.Structure;
|
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;
|
import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,6 +25,8 @@ public class Edge {
|
|||||||
|
|
||||||
/** The vertices indexes. */
|
/** The vertices indexes. */
|
||||||
private int index1, index2;
|
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. */
|
/** The weight of the edge. */
|
||||||
private float crease;
|
private float crease;
|
||||||
/** A variable that indicates if this edge belongs to any face or not. */
|
/** 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. */
|
/** The mesh that owns the edge. */
|
||||||
private TemporalMesh temporalMesh;
|
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
|
* This constructor only stores the indexes of the vertices. The position vertices should be stored
|
||||||
* outside this class.
|
* outside this class.
|
||||||
@ -74,14 +84,14 @@ public class Edge {
|
|||||||
* @return the first vertex of the edge
|
* @return the first vertex of the edge
|
||||||
*/
|
*/
|
||||||
public Vector3f getFirstVertex() {
|
public Vector3f getFirstVertex() {
|
||||||
return temporalMesh.getVertices().get(index1);
|
return temporalMesh == null ? v1 : temporalMesh.getVertices().get(index1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the second vertex of the edge
|
* @return the second vertex of the edge
|
||||||
*/
|
*/
|
||||||
public Vector3f getSecondVertex() {
|
public Vector3f getSecondVertex() {
|
||||||
return temporalMesh.getVertices().get(index2);
|
return temporalMesh == null ? v2 : temporalMesh.getVertices().get(index2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,27 +198,81 @@ public class Edge {
|
|||||||
* @return <b>true</b> if the edges cross and false otherwise
|
* @return <b>true</b> if the edges cross and false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean cross(Edge edge) {
|
public boolean cross(Edge edge) {
|
||||||
Vector3f P1 = this.getFirstVertex();
|
return this.getCrossPoint(edge) != null;
|
||||||
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);
|
* The method computes the crossing pint of this edge and another edge. If
|
||||||
float t1 = (P2.x - P1.x + v.x * t2) / u.x;
|
* there is no crossing then null is returned.
|
||||||
Vector3f p1 = P1.add(u.mult(t1));
|
*
|
||||||
Vector3f p2 = P2.add(v.mult(t2));
|
* @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 (p1.distance(p2) <= FastMath.FLT_EPSILON) {
|
||||||
|
if(extendThisEdge && extendSecondEdge) {
|
||||||
|
return p1.toVector3f();
|
||||||
|
}
|
||||||
// the lines cross, check if p1 and p2 are within the edges
|
// the lines cross, check if p1 and p2 are within the edges
|
||||||
Vector3f p = p1.subtract(P1);
|
Vector3d p = p1.subtract(P1);
|
||||||
float cos = p.dot(u) / (p.length() * u.length());
|
double cos = p.dot(u) / p.length();
|
||||||
if (cos > 0 && p.length() <= u.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
|
// p1 is inside the first edge, lets check the other edge now
|
||||||
p = p2.subtract(P2);
|
p = p2.subtract(P2);
|
||||||
cos = p.dot(v) / (p.length() * v.length());
|
cos = p.dot(v) / p.length();
|
||||||
return cos > 0 && p.length() <= u.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
|
@Override
|
||||||
|
@ -276,6 +276,20 @@ public class Face implements Comparator<Integer> {
|
|||||||
List<Face> facesToTriangulate = new ArrayList<Face>(Arrays.asList(this.clone()));
|
List<Face> facesToTriangulate = new ArrayList<Face>(Arrays.asList(this.clone()));
|
||||||
while (facesToTriangulate.size() > 0) {
|
while (facesToTriangulate.size() > 0) {
|
||||||
Face face = facesToTriangulate.remove(0);
|
Face face = facesToTriangulate.remove(0);
|
||||||
|
// 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;
|
int previousIndex1 = -1, previousIndex2 = -1, previousIndex3 = -1;
|
||||||
while (face.vertexCount() > 0) {
|
while (face.vertexCount() > 0) {
|
||||||
indexes[0] = face.getIndex(0);
|
indexes[0] = face.getIndex(0);
|
||||||
@ -298,8 +312,9 @@ public class Face implements Comparator<Integer> {
|
|||||||
triangulatedFaces.add(new IndexesLoop(indexes));
|
triangulatedFaces.add(new IndexesLoop(indexes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (BlenderFileException e) {
|
} 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);
|
indexes[0] = this.getIndex(0);
|
||||||
for (int i = 1; i < this.vertexCount() - 1; ++i) {
|
for (int i = 1; i < this.vertexCount() - 1; ++i) {
|
||||||
indexes[1] = this.getIndex(i);
|
indexes[1] = this.getIndex(i);
|
||||||
@ -338,12 +353,18 @@ public class Face implements Comparator<Integer> {
|
|||||||
/**
|
/**
|
||||||
* The method finds the closest vertex to the one specified by <b>index</b>.
|
* 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.
|
* 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
|
* The closest vertex must be able to create an edge that is fully contained
|
||||||
* any other edges.
|
* 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
|
* @param index
|
||||||
* the index of the vertex that needs to have found the nearest neighbour
|
* the index of the vertex that needs to have found the nearest
|
||||||
|
* neighbour
|
||||||
* @param indexToIgnore
|
* @param indexToIgnore
|
||||||
* the index to ignore in the result (pass -1 if none is to be ignored)
|
* 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
|
* @return the index of the closest vertex to the given one
|
||||||
*/
|
*/
|
||||||
private int findClosestVertex(int index, int indexToIgnore) {
|
private int findClosestVertex(int index, int indexToIgnore) {
|
||||||
@ -355,7 +376,7 @@ public class Face implements Comparator<Integer> {
|
|||||||
if (i != index && i != indexToIgnore) {
|
if (i != index && i != indexToIgnore) {
|
||||||
Vector3f v2 = vertices.get(i);
|
Vector3f v2 = vertices.get(i);
|
||||||
float d = v2.distance(v1);
|
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;
|
result = i;
|
||||||
distance = d;
|
distance = d;
|
||||||
}
|
}
|
||||||
@ -376,11 +397,9 @@ public class Face implements Comparator<Integer> {
|
|||||||
int index2 = edge.getSecondIndex();
|
int index2 = edge.getSecondIndex();
|
||||||
// check if the line between the vertices is not a border edge of the face
|
// check if the line between the vertices is not a border edge of the face
|
||||||
if (!indexes.areNeighbours(index1, index2)) {
|
if (!indexes.areNeighbours(index1, index2)) {
|
||||||
List<Vector3f> vertices = temporalMesh.getVertices();
|
|
||||||
|
|
||||||
for (int i = 0; i < indexes.size(); ++i) {
|
for (int i = 0; i < indexes.size(); ++i) {
|
||||||
int i1 = this.getIndex(i);
|
int i1 = this.getIndex(i - 1);
|
||||||
int i2 = this.getIndex(i + 1);
|
int i2 = this.getIndex(i);
|
||||||
// check if the edges have no common verts (because if they do, they cannot cross)
|
// 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 (i1 != index1 && i1 != index2 && i2 != index1 && i2 != index2) {
|
||||||
if (edge.cross(new Edge(i1, i2, 0, false, temporalMesh))) {
|
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
|
// computing the edge's middle point
|
||||||
// we check it by comparing the angle that is created by vertices: [index1 - 1, index1, index1 + 1]
|
Vector3f edgeMiddlePoint = edge.computeCentroid();
|
||||||
// with the one creaded by vertices: [index1 - 1, index1, index2]
|
// computing the edge that is perpendicular to the given edge and has a length of 1 (length actually does not matter)
|
||||||
// if the latter is greater than it means that the edge is outside the face
|
Vector3f edgeVector = edge.getSecondVertex().subtract(edge.getFirstVertex());
|
||||||
// IMPORTANT: we assume that all vertices are in one plane (this should be ensured before creating the Face)
|
Vector3f edgeNormal = temporalMesh.getNormals().get(index1).cross(edgeVector).normalizeLocal();
|
||||||
int indexOfIndex1 = indexes.indexOf(index1);
|
Edge e = new Edge(edgeMiddlePoint, edgeNormal.add(edgeMiddlePoint));
|
||||||
int indexMinus1 = this.getIndex(indexOfIndex1 - 1);// indexOfIndex1 == 0 ? indexes.get(indexes.size() - 1) : indexes.get(indexOfIndex1 - 1);
|
// compute the vectors from the middle point to the crossing between the extended edge 'e' and other edges of the face
|
||||||
int indexPlus1 = this.getIndex(indexOfIndex1 + 1);// indexOfIndex1 == indexes.size() - 1 ? 0 : indexes.get(indexOfIndex1 + 1);
|
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
|
||||||
|
}
|
||||||
|
|
||||||
Vector3f edge1 = vertices.get(indexMinus1).subtract(vertices.get(index1)).normalizeLocal();
|
// use only distinct vertices (doubles may appear if the crossing point is a vertex)
|
||||||
Vector3f edge2 = vertices.get(indexPlus1).subtract(vertices.get(index1)).normalizeLocal();
|
List<Vector3f> distinctCrossingVectors = new ArrayList<Vector3f>();
|
||||||
Vector3f newEdge = vertices.get(index2).subtract(vertices.get(index1)).normalizeLocal();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// verify f the later computed angle is inside or outside the face
|
if(distinctCrossingVectors.size() == 0) {
|
||||||
Vector3f direction1 = edge1.cross(edge2).normalizeLocal();
|
throw new IllegalStateException("There MUST be at least 2 crossing vertices!");
|
||||||
Vector3f direction2 = edge1.cross(newEdge).normalizeLocal();
|
}
|
||||||
Vector3f normal = temporalMesh.getNormals().get(index1);
|
// 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
|
||||||
boolean isAngle1Interior = normal.dot(direction1) < 0;
|
for(int i=1;i<distinctCrossingVectors.size();++i) {
|
||||||
boolean isAngle2Interior = normal.dot(direction2) < 0;
|
if(direction != Math.signum(distinctCrossingVectors.get(i).dot(edgeNormal))) {
|
||||||
|
return true;
|
||||||
float angle1 = isAngle1Interior ? edge1.angleBetween(edge2) : FastMath.TWO_PI - edge1.angleBetween(edge2);
|
}
|
||||||
float angle2 = isAngle2Interior ? edge1.angleBetween(newEdge) : FastMath.TWO_PI - edge1.angleBetween(newEdge);
|
}
|
||||||
|
return false;
|
||||||
return angle1 >= angle2;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,10 @@ public class SphereCollisionShape extends CollisionShape {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setScale(Vector3f scale) {
|
public void setScale(Vector3f scale) {
|
||||||
|
if (!scale.equals(Vector3f.UNIT_XYZ)) {
|
||||||
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "SphereCollisionShape cannot be scaled");
|
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "SphereCollisionShape cannot be scaled");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void createShape() {
|
protected void createShape() {
|
||||||
objectId = createShape(radius);
|
objectId = createShape(radius);
|
||||||
@ -91,7 +93,7 @@ public class SphereCollisionShape extends CollisionShape {
|
|||||||
// new SphereShape(radius);
|
// new SphereShape(radius);
|
||||||
// objectId.setLocalScaling(Converter.convert(getScale()));
|
// objectId.setLocalScaling(Converter.convert(getScale()));
|
||||||
// objectId.setMargin(margin);
|
// objectId.setMargin(margin);
|
||||||
setScale(scale);
|
setScale(scale); // Set the scale to 1
|
||||||
setMargin(margin);
|
setMargin(margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,11 +139,7 @@ public final class Bone implements Savable {
|
|||||||
/**
|
/**
|
||||||
* Special-purpose copy constructor.
|
* Special-purpose copy constructor.
|
||||||
* <p>
|
* <p>
|
||||||
* Only copies the name and bind pose from the original.
|
* Only copies the name, user control state and bind pose transforms 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.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The rest of the data is <em>NOT</em> copied, as it will be
|
* The rest of the data is <em>NOT</em> copied, as it will be
|
||||||
* generated automatically when the bone is animated.
|
* generated automatically when the bone is animated.
|
||||||
@ -155,13 +151,13 @@ public final class Bone implements Savable {
|
|||||||
|
|
||||||
userControl = source.userControl;
|
userControl = source.userControl;
|
||||||
|
|
||||||
bindPos = source.bindPos;
|
bindPos = source.bindPos.clone();
|
||||||
bindRot = source.bindRot;
|
bindRot = source.bindRot.clone();
|
||||||
bindScale = source.bindScale;
|
bindScale = source.bindScale.clone();
|
||||||
|
|
||||||
modelBindInversePos = source.modelBindInversePos;
|
modelBindInversePos = source.modelBindInversePos.clone();
|
||||||
modelBindInverseRot = source.modelBindInverseRot;
|
modelBindInverseRot = source.modelBindInverseRot.clone();
|
||||||
modelBindInverseScale = source.modelBindInverseScale;
|
modelBindInverseScale = source.modelBindInverseScale.clone();
|
||||||
|
|
||||||
// parent and children will be assigned manually..
|
// 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.
|
* Callables are executed right at the beginning of the main loop.
|
||||||
* They are executed even if the application is currently paused
|
* They are executed even if the application is currently paused
|
||||||
* or out of focus.
|
* or out of focus.
|
||||||
|
*
|
||||||
|
* @param callable The callable to run in the main jME3 thread
|
||||||
*/
|
*/
|
||||||
public <V> Future<V> enqueue(Callable<V> callable) {
|
public <V> Future<V> enqueue(Callable<V> callable) {
|
||||||
AppTask<V> task = new AppTask<V>(callable);
|
AppTask<V> task = new AppTask<V>(callable);
|
||||||
@ -657,6 +659,20 @@ public class Application implements SystemListener {
|
|||||||
return task;
|
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)}
|
* Runs tasks enqueued via {@link #enqueue(Callable)}
|
||||||
*/
|
*/
|
||||||
@ -740,4 +756,19 @@ public class Application implements SystemListener {
|
|||||||
return viewPort;
|
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();
|
list.removeLast();
|
||||||
} else {
|
} else {
|
||||||
list.add("..");
|
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 {
|
} else {
|
||||||
list.add(string);
|
list.add(string);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
* Copyright (c) 2009-2012, 2016 jMonkeyEngine
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -33,6 +33,7 @@ package com.jme3.audio;
|
|||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.asset.AssetNotFoundException;
|
import com.jme3.asset.AssetNotFoundException;
|
||||||
|
import com.jme3.audio.AudioData.DataType;
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.InputCapsule;
|
||||||
import com.jme3.export.JmeExporter;
|
import com.jme3.export.JmeExporter;
|
||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
@ -128,6 +129,17 @@ public class AudioNode extends Node implements AudioSource {
|
|||||||
setAudioData(audioData, audioKey);
|
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.
|
* 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
|
* the stream cache is used. When enabled, the audio stream will
|
||||||
* be read entirely but not decoded, allowing features such as
|
* be read entirely but not decoded, allowing features such as
|
||||||
* seeking, looping and determining duration.
|
* 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) {
|
public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
|
||||||
this.audioKey = new AudioKey(name, stream, 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 name The filename of the audio file
|
||||||
* @param stream If true, the audio will be streamed gradually from disk,
|
* @param stream If true, the audio will be streamed gradually from disk,
|
||||||
* otherwise, it will be buffered.
|
* 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) {
|
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.
|
* @deprecated AudioRenderer parameter is ignored.
|
||||||
*/
|
*/
|
||||||
public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name) {
|
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 assetManager The asset manager to use to load the audio file
|
||||||
* @param name The filename of 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) {
|
public AudioNode(AssetManager assetManager, String name) {
|
||||||
this(assetManager, name, false);
|
this(assetManager, name, DataType.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AudioRenderer getRenderer() {
|
protected AudioRenderer getRenderer() {
|
||||||
@ -310,6 +327,19 @@ public class AudioNode extends Node implements AudioSource {
|
|||||||
this.status = status;
|
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,
|
* @return True if the audio will keep looping after it is done playing,
|
||||||
* otherwise, false.
|
* otherwise, false.
|
||||||
|
@ -109,8 +109,11 @@ public class BIHTree implements CollisionData {
|
|||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
this.maxTrisPerNode = maxTrisPerNode;
|
this.maxTrisPerNode = maxTrisPerNode;
|
||||||
|
|
||||||
if (maxTrisPerNode < 1 || mesh == null) {
|
if (maxTrisPerNode < 1) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException("maxTrisPerNode cannot be less than 1");
|
||||||
|
}
|
||||||
|
if (mesh == null) {
|
||||||
|
throw new IllegalArgumentException("Mesh cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
bihSwapTmp = new float[9];
|
bihSwapTmp = new float[9];
|
||||||
@ -451,7 +454,7 @@ public class BIHTree implements CollisionData {
|
|||||||
} else if (bv instanceof BoundingBox) {
|
} else if (bv instanceof BoundingBox) {
|
||||||
bbox = new BoundingBox((BoundingBox) bv);
|
bbox = new BoundingBox((BoundingBox) bv);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException("BoundingVolume:" + bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bbox.transform(worldMatrix.invert(), bbox);
|
bbox.transform(worldMatrix.invert(), bbox);
|
||||||
@ -470,7 +473,7 @@ public class BIHTree implements CollisionData {
|
|||||||
BoundingVolume bv = (BoundingVolume) other;
|
BoundingVolume bv = (BoundingVolume) other;
|
||||||
return collideWithBoundingVolume(bv, worldMatrix, results);
|
return collideWithBoundingVolume(bv, worldMatrix, results);
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedCollisionException();
|
throw new UnsupportedCollisionException("Collidable:" + other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ public class ParticleEmitter extends Geometry {
|
|||||||
private boolean worldSpace = true;
|
private boolean worldSpace = true;
|
||||||
//variable that helps with computations
|
//variable that helps with computations
|
||||||
private transient Vector3f temp = new Vector3f();
|
private transient Vector3f temp = new Vector3f();
|
||||||
|
private transient Vector3f lastPos;
|
||||||
|
|
||||||
public static class ParticleEmitterControl implements Control {
|
public static class ParticleEmitterControl implements Control {
|
||||||
|
|
||||||
@ -1013,12 +1014,16 @@ public class ParticleEmitter extends Geometry {
|
|||||||
|
|
||||||
// Spawns particles within the tpf timeslot with proper age
|
// Spawns particles within the tpf timeslot with proper age
|
||||||
float interval = 1f / particlesPerSec;
|
float interval = 1f / particlesPerSec;
|
||||||
|
float originalTpf = tpf;
|
||||||
tpf += timeDifference;
|
tpf += timeDifference;
|
||||||
while (tpf > interval){
|
while (tpf > interval){
|
||||||
tpf -= interval;
|
tpf -= interval;
|
||||||
Particle p = emitParticle(min, max);
|
Particle p = emitParticle(min, max);
|
||||||
if (p != null){
|
if (p != null){
|
||||||
p.life -= tpf;
|
p.life -= tpf;
|
||||||
|
if (lastPos != null && isInWorldSpace()) {
|
||||||
|
p.position.interpolateLocal(lastPos, 1 - tpf / originalTpf);
|
||||||
|
}
|
||||||
if (p.life <= 0){
|
if (p.life <= 0){
|
||||||
freeParticle(lastUsed);
|
freeParticle(lastUsed);
|
||||||
}else{
|
}else{
|
||||||
@ -1028,6 +1033,12 @@ public class ParticleEmitter extends Geometry {
|
|||||||
}
|
}
|
||||||
timeDifference = tpf;
|
timeDifference = tpf;
|
||||||
|
|
||||||
|
if (lastPos == null) {
|
||||||
|
lastPos = new Vector3f();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPos.set(getWorldTranslation());
|
||||||
|
|
||||||
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
|
||||||
bbox.setMinMax(min, max);
|
bbox.setMinMax(min, max);
|
||||||
this.setBoundRefresh();
|
this.setBoundRefresh();
|
||||||
|
@ -36,6 +36,11 @@ package com.jme3.input;
|
|||||||
*/
|
*/
|
||||||
public interface KeyInput extends Input {
|
public interface KeyInput extends Input {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unmapped key.
|
||||||
|
*/
|
||||||
|
public static final int KEY_UNKNOWN = 0x00;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* escape key.
|
* escape key.
|
||||||
*/
|
*/
|
||||||
@ -539,4 +544,8 @@ public interface KeyInput extends Input {
|
|||||||
*/
|
*/
|
||||||
public static final int KEY_SLEEP = 0xDF;
|
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];
|
private static final String[] KEY_NAMES = new String[0xFF];
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
KEY_NAMES[KEY_UNKNOWN] = "Unknown";
|
||||||
KEY_NAMES[KEY_0] = "0";
|
KEY_NAMES[KEY_0] = "0";
|
||||||
KEY_NAMES[KEY_1] = "1";
|
KEY_NAMES[KEY_1] = "1";
|
||||||
KEY_NAMES[KEY_2] = "2";
|
KEY_NAMES[KEY_2] = "2";
|
||||||
@ -105,9 +106,10 @@ public class KeyNames {
|
|||||||
|
|
||||||
KEY_NAMES[KEY_NUMPADEQUALS] = "Numpad =";
|
KEY_NAMES[KEY_NUMPADEQUALS] = "Numpad =";
|
||||||
KEY_NAMES[KEY_NUMPADENTER] = "Numpad Enter";
|
KEY_NAMES[KEY_NUMPADENTER] = "Numpad Enter";
|
||||||
KEY_NAMES[KEY_NUMPADCOMMA] = "Numpad .";
|
KEY_NAMES[KEY_NUMPADCOMMA] = "Numpad ,";
|
||||||
KEY_NAMES[KEY_DIVIDE] = "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_LMENU] = "Left Alt";
|
||||||
KEY_NAMES[KEY_RMENU] = "Right Alt";
|
KEY_NAMES[KEY_RMENU] = "Right Alt";
|
||||||
@ -178,7 +180,7 @@ public class KeyNames {
|
|||||||
KEY_NAMES[KEY_UNLABELED] = "Unlabeled";
|
KEY_NAMES[KEY_UNLABELED] = "Unlabeled";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName(int keyId){
|
public static String getName(int keyId) {
|
||||||
return KEY_NAMES[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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -146,4 +146,10 @@ public class DirectionalLight extends Light {
|
|||||||
direction = (Vector3f) ic.readSavable("direction", null);
|
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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -228,7 +228,9 @@ public abstract class Light implements Savable, Cloneable {
|
|||||||
@Override
|
@Override
|
||||||
public Light clone(){
|
public Light clone(){
|
||||||
try {
|
try {
|
||||||
return (Light) super.clone();
|
Light l = (Light) super.clone();
|
||||||
|
l.color = color.clone();
|
||||||
|
return l;
|
||||||
} catch (CloneNotSupportedException ex) {
|
} catch (CloneNotSupportedException ex) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2012, 2015 jMonkeyEngine
|
* Copyright (c) 2009-2012, 2015-2016 jMonkeyEngine
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -241,4 +241,11 @@ public class PointLight extends Light {
|
|||||||
this.invRadius = 0;
|
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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -448,5 +448,13 @@ public class SpotLight extends Light {
|
|||||||
this.invSpotRange = 0;
|
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()) {
|
if (texKey.isFlipY()) {
|
||||||
ret += "Flip ";
|
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()+ " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret + texKey.getName();
|
if(texVal.getMagFilter() != Texture.MagFilter.Bilinear){
|
||||||
|
ret += "Mag" + texVal.getMagFilter().name()+ " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret + "\"" + texKey.getName() + "\"";
|
||||||
default:
|
default:
|
||||||
return null; // parameter type not supported in J3M
|
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
|
@Override
|
||||||
public MatParam clone() {
|
public MatParam clone() {
|
||||||
try {
|
try {
|
||||||
|
@ -1236,12 +1236,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
oc.write(def.getAssetName(), "material_def", null);
|
oc.write(def.getAssetName(), "material_def", null);
|
||||||
oc.write(additionalState, "render_state", null);
|
oc.write(additionalState, "render_state", null);
|
||||||
oc.write(transparent, "is_transparent", false);
|
oc.write(transparent, "is_transparent", false);
|
||||||
|
oc.write(name, "name", null);
|
||||||
oc.writeStringSavableMap(paramValues, "parameters", null);
|
oc.writeStringSavableMap(paramValues, "parameters", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
|
||||||
|
name = ic.readString("name", null);
|
||||||
additionalState = (RenderState) ic.readSavable("render_state", null);
|
additionalState = (RenderState) ic.readSavable("render_state", null);
|
||||||
transparent = ic.readBoolean("is_transparent", false);
|
transparent = ic.readBoolean("is_transparent", false);
|
||||||
|
|
||||||
|
@ -31,14 +31,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.scene;
|
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.Buffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -48,13 +40,22 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
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.
|
* 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.
|
* There is one geometry per different material in the sub tree.
|
||||||
* The geometries are directly attached to the node in the scene graph.
|
* 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
|
* 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)
|
* (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.
|
* 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 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.
|
* 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);
|
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>();
|
protected Map<Geometry, Batch> batchesByGeom = new HashMap<Geometry, Batch>();
|
||||||
/**
|
/**
|
||||||
@ -115,11 +116,10 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGeoemtryUnassociated(Geometry geom) {
|
public void onGeometryUnassociated(Geometry geom) {
|
||||||
setNeedsFullRebatch(true);
|
setNeedsFullRebatch(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Matrix4f getTransformMatrix(Geometry g){
|
protected Matrix4f getTransformMatrix(Geometry g){
|
||||||
return g.cachedWorldMat;
|
return g.cachedWorldMat;
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
|
Map<Material, List<Geometry>> matMap = new HashMap<Material, List<Geometry>>();
|
||||||
int nbGeoms = 0;
|
int nbGeoms = 0;
|
||||||
|
|
||||||
gatherGeomerties(matMap, this, needsFullRebatch);
|
gatherGeometries(matMap, this, needsFullRebatch);
|
||||||
if (needsFullRebatch) {
|
if (needsFullRebatch) {
|
||||||
for (Batch batch : batches.getArray()) {
|
for (Batch batch : batches.getArray()) {
|
||||||
batch.geometry.removeFromParent();
|
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) {
|
if (n instanceof Geometry) {
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
if (child instanceof BatchNode) {
|
if (child instanceof BatchNode) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gatherGeomerties(map, child, rebatch);
|
gatherGeometries(map, child, rebatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBatch(Spatial s) {
|
public final boolean isBatch(Spatial s) {
|
||||||
for (Batch batch : batches.getArray()) {
|
for (Batch batch : batches.getArray()) {
|
||||||
if (batch.geometry == s) {
|
if (batch.geometry == s) {
|
||||||
return true;
|
return true;
|
||||||
@ -336,9 +336,6 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMaterial(Material material) {
|
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");
|
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();
|
Batch b = batches.iterator().next();
|
||||||
return b.geometry.getMaterial();
|
return b.geometry.getMaterial();
|
||||||
}
|
}
|
||||||
return null;//material;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 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);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -510,8 +440,7 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
outMesh.setMode(mode);
|
outMesh.setMode(mode);
|
||||||
outMesh.setLineWidth(lineWidth);
|
outMesh.setLineWidth(lineWidth);
|
||||||
if (totalVerts >= 65536) {
|
if (totalVerts >= 65536) {
|
||||||
// make sure we create an UnsignedInt buffer so
|
// make sure we create an UnsignedInt buffer so we can fit all of the meshes
|
||||||
// we can fit all of the meshes
|
|
||||||
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt;
|
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedInt;
|
||||||
} else {
|
} else {
|
||||||
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort;
|
formatForBuf[VertexBuffer.Type.Index.ordinal()] = VertexBuffer.Format.UnsignedShort;
|
||||||
@ -733,7 +662,6 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected class Batch {
|
protected class Batch {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update the batchesByGeom map for this batch with the given List of geometries
|
* update the batchesByGeom map for this batch with the given List of geometries
|
||||||
* @param list
|
* @param list
|
||||||
@ -771,4 +699,15 @@ public class BatchNode extends GeometryGroupNode {
|
|||||||
}
|
}
|
||||||
return clone;
|
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) {
|
if (groupNode != null) {
|
||||||
// Once the geometry is removed
|
// Once the geometry is removed
|
||||||
// from the parent, the group node needs to be updated.
|
// from the parent, the group node needs to be updated.
|
||||||
groupNode.onGeoemtryUnassociated(this);
|
groupNode.onGeometryUnassociated(this);
|
||||||
groupNode = null;
|
groupNode = null;
|
||||||
|
|
||||||
// change the default to -1 to make error detection easier
|
// 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.
|
* @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;
|
// childClone.parent = nodeClone;
|
||||||
// nodeClone.children.add(childClone);
|
// 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;
|
return nodeClone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ public class InstancedNode extends GeometryGroupNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGeoemtryUnassociated(Geometry geom) {
|
public void onGeometryUnassociated(Geometry geom) {
|
||||||
removeFromInstancedGeometry(geom);
|
removeFromInstancedGeometry(geom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ public class Cylinder extends Mesh {
|
|||||||
*/
|
*/
|
||||||
public void updateGeometry(int axisSamples, int radialSamples,
|
public void updateGeometry(int axisSamples, int radialSamples,
|
||||||
float radius, float radius2, float height, boolean closed, boolean inverted) {
|
float radius, float radius2, float height, boolean closed, boolean inverted) {
|
||||||
this.axisSamples = axisSamples + (closed ? 2 : 0);
|
this.axisSamples = axisSamples;
|
||||||
this.radialSamples = radialSamples;
|
this.radialSamples = radialSamples;
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.radius2 = radius2;
|
this.radius2 = radius2;
|
||||||
@ -222,6 +222,7 @@ public class Cylinder extends Mesh {
|
|||||||
// VertexBuffer pvb = getBuffer(Type.Position);
|
// VertexBuffer pvb = getBuffer(Type.Position);
|
||||||
// VertexBuffer nvb = getBuffer(Type.Normal);
|
// VertexBuffer nvb = getBuffer(Type.Normal);
|
||||||
// VertexBuffer tvb = getBuffer(Type.TexCoord);
|
// VertexBuffer tvb = getBuffer(Type.TexCoord);
|
||||||
|
axisSamples += (closed ? 2 : 0);
|
||||||
|
|
||||||
// Vertices
|
// Vertices
|
||||||
int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0);
|
int vertCount = axisSamples * (radialSamples + 1) + (closed ? 2 : 0);
|
||||||
|
@ -963,7 +963,7 @@ public final class AppSettings extends HashMap<String, Object> {
|
|||||||
return getString("SettingsDialogImage");
|
return getString("SettingsDialogImage");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getGammaCorrection() {
|
public boolean isGammaCorrection() {
|
||||||
return getBoolean("GammaCorrection");
|
return getBoolean("GammaCorrection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ import java.nio.IntBuffer;
|
|||||||
import java.nio.LongBuffer;
|
import java.nio.LongBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -401,6 +400,25 @@ public final class BufferUtils {
|
|||||||
vector.z = buf.get(index * 3 + 2);
|
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.
|
* Generates a Vector3f array from the given FloatBuffer.
|
||||||
*
|
*
|
||||||
@ -1249,7 +1267,6 @@ public final class BufferUtils {
|
|||||||
System.out.println(store.toString());
|
System.out.println(store.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static final AtomicBoolean loadedMethods = new AtomicBoolean(false);
|
|
||||||
private static Method cleanerMethod = null;
|
private static Method cleanerMethod = null;
|
||||||
private static Method cleanMethod = null;
|
private static Method cleanMethod = null;
|
||||||
private static Method viewedBufferMethod = null;
|
private static Method viewedBufferMethod = null;
|
||||||
@ -1269,14 +1286,7 @@ public final class BufferUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCleanerMethods() {
|
static {
|
||||||
// If its already true, exit, if not, set it to true.
|
|
||||||
if (BufferUtils.loadedMethods.getAndSet(true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// This could potentially be called many times if used from multiple
|
|
||||||
// threads
|
|
||||||
synchronized (BufferUtils.loadedMethods) {
|
|
||||||
// Oracle JRE / OpenJDK
|
// Oracle JRE / OpenJDK
|
||||||
cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
|
cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
|
||||||
cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
|
cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
|
||||||
@ -1295,7 +1305,6 @@ public final class BufferUtils {
|
|||||||
} catch (SecurityException ex) {
|
} catch (SecurityException ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Direct buffers are garbage collected by using a phantom reference and a
|
* Direct buffers are garbage collected by using a phantom reference and a
|
||||||
@ -1314,8 +1323,6 @@ public final class BufferUtils {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferUtils.loadCleanerMethods();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (freeMethod != null) {
|
if (freeMethod != null) {
|
||||||
freeMethod.invoke(toBeDestroyed);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -32,11 +32,12 @@ void main(){
|
|||||||
#ifdef POINT_SPRITE
|
#ifdef POINT_SPRITE
|
||||||
vec4 worldPos = g_WorldMatrix * pos;
|
vec4 worldPos = g_WorldMatrix * pos;
|
||||||
float d = distance(g_CameraPosition.xyz, worldPos.xyz);
|
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;
|
//vec4 worldViewPos = g_WorldViewMatrix * pos;
|
||||||
//gl_PointSize = (inSize * SIZE_MULTIPLIER * m_Quadratic)*100.0 / worldViewPos.z;
|
//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
|
#endif
|
||||||
}
|
}
|
@ -95,6 +95,25 @@ Gamepad\ F310\ (Controller).ry=rz
|
|||||||
# keeps it from confusing the .rx mapping.
|
# keeps it from confusing the .rx mapping.
|
||||||
Gamepad\ F310\ (Controller).z=trigger
|
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
|
# Alternate version of the XBOX 360 controller
|
||||||
XBOX\ 360\ For\ Windows\ (Controller).0=2
|
XBOX\ 360\ For\ Windows\ (Controller).0=2
|
||||||
XBOX\ 360\ For\ Windows\ (Controller).1=1
|
XBOX\ 360\ For\ Windows\ (Controller).1=1
|
||||||
|
@ -155,7 +155,7 @@ public class TextureAtlas {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (normal != null && normal.getKey() != null) {
|
if (normal != null && normal.getKey() != null) {
|
||||||
addTexture(diffuse, "NormalMap", keyName);
|
addTexture(normal, "NormalMap", keyName);
|
||||||
}
|
}
|
||||||
if (specular != null && specular.getKey() != null) {
|
if (specular != null && specular.getKey() != null) {
|
||||||
addTexture(specular, "SpecularMap", keyName);
|
addTexture(specular, "SpecularMap", keyName);
|
||||||
|
@ -360,7 +360,7 @@ public final class SettingsDialog extends JFrame {
|
|||||||
vsyncBox.setSelected(source.isVSync());
|
vsyncBox.setSelected(source.isVSync());
|
||||||
|
|
||||||
gammaBox = new JCheckBox(resourceBundle.getString("checkbox.gamma"));
|
gammaBox = new JCheckBox(resourceBundle.getString("checkbox.gamma"));
|
||||||
gammaBox.setSelected(source.getGammaCorrection());
|
gammaBox.setSelected(source.isGammaCorrection());
|
||||||
|
|
||||||
gbc = new GridBagConstraints();
|
gbc = new GridBagConstraints();
|
||||||
gbc.weightx = 0.5;
|
gbc.weightx = 0.5;
|
||||||
|
@ -19,6 +19,6 @@ void main(void)
|
|||||||
#ifdef NUM_BONES
|
#ifdef NUM_BONES
|
||||||
Skinning_Compute(modelSpacePos,modelSpaceNormals);
|
Skinning_Compute(modelSpacePos,modelSpaceNormals);
|
||||||
#endif
|
#endif
|
||||||
normal = normalize(g_NormalMatrix * modelSpaceNormals);
|
normal = normalize(TransformNormal(modelSpaceNormals));
|
||||||
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
||||||
}
|
}
|
@ -7,6 +7,10 @@ if (!hasProperty('mainClass')) {
|
|||||||
task run(dependsOn: 'build', type:JavaExec) {
|
task run(dependsOn: 'build', type:JavaExec) {
|
||||||
main = mainClass
|
main = mainClass
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
if (System.properties['os.name'].toLowerCase().contains('mac')) {
|
||||||
|
jvmArgs "-XstartOnFirstThread"
|
||||||
|
jvmArgs "-Djava.awt.headless=true"
|
||||||
|
}
|
||||||
if( assertions == "true" ){
|
if( assertions == "true" ){
|
||||||
enableAssertions = true;
|
enableAssertions = true;
|
||||||
}
|
}
|
||||||
|
@ -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
|
* Get the current forward vector of the vehicle in world coordinates
|
||||||
* @param vector The object to write the forward vector values to.
|
* @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
|
* @return The forward vector
|
||||||
*/
|
*/
|
||||||
public Vector3f getForwardVector(Vector3f vector) {
|
public Vector3f getForwardVector(Vector3f vector) {
|
||||||
|
@ -54,6 +54,7 @@ import com.jme3.system.AppSettings;
|
|||||||
import com.jme3.system.JmeContext;
|
import com.jme3.system.JmeContext;
|
||||||
import com.jme3.system.NanoTimer;
|
import com.jme3.system.NanoTimer;
|
||||||
import com.jme3.system.NativeLibraryLoader;
|
import com.jme3.system.NativeLibraryLoader;
|
||||||
|
import com.jme3.system.NullRenderer;
|
||||||
import com.jme3.system.SystemListener;
|
import com.jme3.system.SystemListener;
|
||||||
import com.jme3.system.Timer;
|
import com.jme3.system.Timer;
|
||||||
|
|
||||||
@ -202,8 +203,8 @@ public abstract class JoglContext implements JmeContext {
|
|||||||
GLContext.getCurrent().addGLDebugListener(new JoglGLDebugOutputHandler());
|
GLContext.getCurrent().addGLDebugListener(new JoglGLDebugOutputHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection());
|
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection());
|
||||||
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
|
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
|
||||||
|
|
||||||
// Init input
|
// Init input
|
||||||
if (keyInput != null) {
|
if (keyInput != null) {
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.system.lwjgl;
|
package com.jme3.system.lwjgl;
|
||||||
|
|
||||||
import com.jme3.input.lwjgl.JInputJoyInput;
|
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.GLTimingState;
|
||||||
import com.jme3.renderer.opengl.GLTracer;
|
import com.jme3.renderer.opengl.GLTracer;
|
||||||
import com.jme3.system.*;
|
import com.jme3.system.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -82,18 +82,18 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
protected Timer timer;
|
protected Timer timer;
|
||||||
protected SystemListener listener;
|
protected SystemListener listener;
|
||||||
|
|
||||||
public void setSystemListener(SystemListener listener){
|
public void setSystemListener(SystemListener listener) {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void printContextInitInfo() {
|
protected void printContextInitInfo() {
|
||||||
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n" +
|
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
|
||||||
" * Graphics Adapter: {2}\n" +
|
+ " * Graphics Adapter: {2}\n"
|
||||||
" * Driver Version: {3}\n" +
|
+ " * Driver Version: {3}\n"
|
||||||
" * Scaling Factor: {4}",
|
+ " * Scaling Factor: {4}",
|
||||||
new Object[]{ Sys.getVersion(), Thread.currentThread().getName(),
|
new Object[]{Sys.getVersion(), Thread.currentThread().getName(),
|
||||||
Display.getAdapter(), Display.getVersion(),
|
Display.getAdapter(), Display.getVersion(),
|
||||||
Display.getPixelScaleFactor() });
|
Display.getPixelScaleFactor()});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContextAttribs createContextAttribs() {
|
protected ContextAttribs createContextAttribs() {
|
||||||
@ -162,6 +162,7 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadNatives() {
|
protected void loadNatives() {
|
||||||
if (JmeSystem.isLowPermissions()) {
|
if (JmeSystem.isLowPermissions()) {
|
||||||
return;
|
return;
|
||||||
@ -181,7 +182,7 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
|
|
||||||
protected int getNumSamplesToUse() {
|
protected int getNumSamplesToUse() {
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
if (settings.getSamples() > 1){
|
if (settings.getSamples() > 1) {
|
||||||
samples = settings.getSamples();
|
samples = settings.getSamples();
|
||||||
int supportedSamples = determineMaxSamples(samples);
|
int supportedSamples = determineMaxSamples(samples);
|
||||||
if (supportedSamples < samples) {
|
if (supportedSamples < samples) {
|
||||||
@ -196,10 +197,10 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initContextFirstTime(){
|
protected void initContextFirstTime() {
|
||||||
if (!GLContext.getCapabilities().OpenGL20) {
|
if (!GLContext.getCapabilities().OpenGL20) {
|
||||||
throw new RendererException("OpenGL 2.0 or higher is " +
|
throw new RendererException("OpenGL 2.0 or higher is "
|
||||||
"required for jMonkeyEngine");
|
+ "required for jMonkeyEngine");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL2)
|
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL2)
|
||||||
@ -243,8 +244,8 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback(new LwjglGLDebugOutputHandler()));
|
ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback(new LwjglGLDebugOutputHandler()));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.setMainFrameBufferSrgb(settings.getGammaCorrection());
|
renderer.setMainFrameBufferSrgb(settings.isGammaCorrection());
|
||||||
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
|
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
|
||||||
|
|
||||||
// Init input
|
// Init input
|
||||||
if (keyInput != null) {
|
if (keyInput != null) {
|
||||||
@ -260,42 +261,42 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void internalDestroy(){
|
public void internalDestroy() {
|
||||||
renderer = null;
|
renderer = null;
|
||||||
timer = null;
|
timer = null;
|
||||||
renderable.set(false);
|
renderable.set(false);
|
||||||
synchronized (createdLock){
|
synchronized (createdLock) {
|
||||||
created.set(false);
|
created.set(false);
|
||||||
createdLock.notifyAll();
|
createdLock.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void internalCreate(){
|
public void internalCreate() {
|
||||||
timer = new LwjglTimer();
|
timer = new LwjglTimer();
|
||||||
|
|
||||||
synchronized (createdLock){
|
synchronized (createdLock) {
|
||||||
created.set(true);
|
created.set(true);
|
||||||
createdLock.notifyAll();
|
createdLock.notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderable.get()){
|
if (renderable.get()) {
|
||||||
initContextFirstTime();
|
initContextFirstTime();
|
||||||
}else{
|
} else {
|
||||||
assert getType() == Type.Canvas;
|
assert getType() == Type.Canvas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(){
|
public void create() {
|
||||||
create(false);
|
create(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy(){
|
public void destroy() {
|
||||||
destroy(false);
|
destroy(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void waitFor(boolean createdVal){
|
protected void waitFor(boolean createdVal) {
|
||||||
synchronized (createdLock){
|
synchronized (createdLock) {
|
||||||
while (created.get() != createdVal){
|
while (created.get() != createdVal) {
|
||||||
try {
|
try {
|
||||||
createdLock.wait();
|
createdLock.wait();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
@ -304,11 +305,11 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCreated(){
|
public boolean isCreated() {
|
||||||
return created.get();
|
return created.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRenderable(){
|
public boolean isRenderable() {
|
||||||
return renderable.get();
|
return renderable.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +317,7 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
this.settings.copyFrom(settings);
|
this.settings.copyFrom(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppSettings getSettings(){
|
public AppSettings getSettings() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,14 @@ if (!hasProperty('mainClass')) {
|
|||||||
ext.mainClass = ''
|
ext.mainClass = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
def lwjglVersion = '3.0.0b'
|
||||||
maven {
|
|
||||||
url "https://oss.sonatype.org/content/repositories/snapshots"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':jme3-core')
|
compile project(':jme3-core')
|
||||||
compile project(':jme3-desktop')
|
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"
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
@ -32,32 +32,38 @@
|
|||||||
package com.jme3.audio.lwjgl;
|
package com.jme3.audio.lwjgl;
|
||||||
|
|
||||||
import com.jme3.audio.openal.ALC;
|
import com.jme3.audio.openal.ALC;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
import org.lwjgl.openal.ALC10;
|
import org.lwjgl.openal.ALC10;
|
||||||
import org.lwjgl.openal.ALContext;
|
import org.lwjgl.openal.ALContext;
|
||||||
import org.lwjgl.openal.ALDevice;
|
import org.lwjgl.openal.ALDevice;
|
||||||
|
import org.lwjgl.openal.SOFTPauseDevice;
|
||||||
import java.nio.IntBuffer;
|
|
||||||
|
|
||||||
import static org.lwjgl.openal.ALC10.alcGetContextsDevice;
|
|
||||||
import static org.lwjgl.openal.ALC10.alcGetCurrentContext;
|
|
||||||
|
|
||||||
public class LwjglALC implements ALC {
|
public class LwjglALC implements ALC {
|
||||||
|
|
||||||
private ALDevice device;
|
private ALDevice device;
|
||||||
private ALContext context;
|
private ALContext context;
|
||||||
|
|
||||||
|
private long contextId;
|
||||||
|
private long deviceId;
|
||||||
|
|
||||||
public void createALC() {
|
public void createALC() {
|
||||||
device = ALDevice.create();
|
device = ALDevice.create();
|
||||||
context = ALContext.create(device);
|
context = ALContext.create(device);
|
||||||
|
context.makeCurrent();
|
||||||
|
|
||||||
|
contextId = ALC10.alcGetCurrentContext();
|
||||||
|
deviceId = ALC10.alcGetContextsDevice(contextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroyALC() {
|
public void destroyALC() {
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.destroy();
|
context.destroy();
|
||||||
|
context = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device != null) {
|
if (device != null) {
|
||||||
device.destroy();
|
device.destroy();
|
||||||
|
device = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,31 +72,29 @@ public class LwjglALC implements ALC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String alcGetString(final int parameter) {
|
public String alcGetString(final int parameter) {
|
||||||
final long context = alcGetCurrentContext();
|
return ALC10.alcGetString(deviceId, parameter);
|
||||||
final long device = alcGetContextsDevice(context);
|
|
||||||
return ALC10.alcGetString(device, parameter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean alcIsExtensionPresent(final String extension) {
|
public boolean alcIsExtensionPresent(final String extension) {
|
||||||
final long context = alcGetCurrentContext();
|
return ALC10.alcIsExtensionPresent(deviceId, extension);
|
||||||
final long device = alcGetContextsDevice(context);
|
|
||||||
return ALC10.alcIsExtensionPresent(device, extension);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alcGetInteger(final int param, final IntBuffer buffer, final int size) {
|
public void alcGetInteger(final int param, final IntBuffer buffer, final int size) {
|
||||||
if (buffer.position() != 0) throw new AssertionError();
|
if (buffer.position() != 0) {
|
||||||
if (buffer.limit() != size) throw new AssertionError();
|
throw new AssertionError();
|
||||||
|
}
|
||||||
final long context = alcGetCurrentContext();
|
if (buffer.limit() != size) {
|
||||||
final long device = alcGetContextsDevice(context);
|
throw new AssertionError();
|
||||||
final int value = ALC10.alcGetInteger(device, param);
|
}
|
||||||
//buffer.put(value);
|
ALC10.alcGetIntegerv(deviceId, param, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alcDevicePauseSOFT() {
|
public void alcDevicePauseSOFT() {
|
||||||
|
SOFTPauseDevice.alcDevicePauseSOFT(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alcDeviceResumeSOFT() {
|
public void alcDeviceResumeSOFT() {
|
||||||
|
SOFTPauseDevice.alcDeviceResumeSOFT(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@ public class GlfwKeyInput implements KeyInput {
|
|||||||
glfwSetKeyCallback(context.getWindowHandle(), keyCallback = new GLFWKeyCallback() {
|
glfwSetKeyCallback(context.getWindowHandle(), keyCallback = new GLFWKeyCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
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());
|
evt.setTime(getInputTimeNanos());
|
||||||
keyInputEvents.add(evt);
|
keyInputEvents.add(evt);
|
||||||
}
|
}
|
||||||
|
171
jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyMap.java
Normal file
171
jme3-lwjgl3/src/main/java/com/jme3/input/lwjgl/GlfwKeyMap.java
Normal file
@ -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.MouseButtonEvent;
|
||||||
import com.jme3.input.event.MouseMotionEvent;
|
import com.jme3.input.event.MouseMotionEvent;
|
||||||
import com.jme3.system.lwjgl.LwjglWindow;
|
import com.jme3.system.lwjgl.LwjglWindow;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
import org.lwjgl.glfw.GLFWCursorPosCallback;
|
import org.lwjgl.glfw.GLFWCursorPosCallback;
|
||||||
import org.lwjgl.glfw.GLFWMouseButtonCallback;
|
import org.lwjgl.glfw.GLFWMouseButtonCallback;
|
||||||
import org.lwjgl.glfw.GLFWScrollCallback;
|
import org.lwjgl.glfw.GLFWScrollCallback;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
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
|
* Captures mouse input using GLFW callbacks. It then temporarily stores these in event queues which are processed in the
|
||||||
@ -74,14 +80,13 @@ public class GlfwMouseInput implements MouseInput {
|
|||||||
private Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<MouseMotionEvent>();
|
private Queue<MouseMotionEvent> mouseMotionEvents = new LinkedList<MouseMotionEvent>();
|
||||||
private Queue<MouseButtonEvent> mouseButtonEvents = new LinkedList<MouseButtonEvent>();
|
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;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
private void onCursorPos(long window, double xpos, double ypos) {
|
||||||
glfwSetCursorPosCallback(context.getWindowHandle(), cursorPosCallback = new GLFWCursorPosCallback() {
|
|
||||||
@Override
|
|
||||||
public void invoke(long window, double xpos, double ypos) {
|
|
||||||
int xDelta;
|
int xDelta;
|
||||||
int yDelta;
|
int yDelta;
|
||||||
int x = (int) Math.round(xpos);
|
int x = (int) Math.round(xpos);
|
||||||
@ -106,25 +111,39 @@ public class GlfwMouseInput implements MouseInput {
|
|||||||
mouseMotionEvents.add(mouseMotionEvent);
|
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) {
|
||||||
|
onCursorPos(window, xpos, ypos);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
|
glfwSetScrollCallback(context.getWindowHandle(), scrollCallback = new GLFWScrollCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(final long window, final double xOffset, final double yOffset) {
|
public void invoke(final long window, final double xOffset, final double yOffset) {
|
||||||
mouseWheel += yOffset;
|
onWheelScroll(window, xOffset, yOffset);
|
||||||
|
|
||||||
final MouseMotionEvent mouseMotionEvent = new MouseMotionEvent(mouseX, mouseY, 0, 0, mouseWheel, (int) Math.round(yOffset));
|
|
||||||
mouseMotionEvent.setTime(getInputTimeNanos());
|
|
||||||
mouseMotionEvents.add(mouseMotionEvent);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() {
|
glfwSetMouseButtonCallback(context.getWindowHandle(), mouseButtonCallback = new GLFWMouseButtonCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(final long window, final int button, final int action, final int mods) {
|
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);
|
onMouseButton(window, button, action, mods);
|
||||||
mouseButtonEvent.setTime(getInputTimeNanos());
|
|
||||||
mouseButtonEvents.add(mouseButtonEvent);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -160,6 +179,10 @@ public class GlfwMouseInput implements MouseInput {
|
|||||||
scrollCallback.release();
|
scrollCallback.release();
|
||||||
mouseButtonCallback.release();
|
mouseButtonCallback.release();
|
||||||
|
|
||||||
|
for (long glfwCursor : jmeToGlfwCursorMap.values()) {
|
||||||
|
glfwDestroyCursor(glfwCursor);
|
||||||
|
}
|
||||||
|
|
||||||
logger.fine("Mouse destroyed.");
|
logger.fine("Mouse destroyed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,31 +208,52 @@ public class GlfwMouseInput implements MouseInput {
|
|||||||
return (long) (glfwGetTime() * 1000000000);
|
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) {
|
if (jmeCursor != null) {
|
||||||
final ByteBuffer byteBuffer = org.lwjgl.BufferUtils.createByteBuffer(jmeCursor.getImagesData().capacity());
|
Long glfwCursor = jmeToGlfwCursorMap.get(jmeCursor);
|
||||||
byteBuffer.asIntBuffer().put(jmeCursor.getImagesData().array());
|
|
||||||
final long cursor = glfwCreateCursor(byteBuffer, jmeCursor.getXHotSpot(), jmeCursor.getYHotSpot());
|
if (glfwCursor == null) {
|
||||||
glfwSetCursor(context.getWindowHandle(), cursor);
|
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
|
* Simply converts the GLFW button code to a JME button code. If there is no
|
||||||
* code. Bare in mind GLFW supports 8 different mouse buttons.
|
* match it just returns the GLFW button code. Bear in mind GLFW supports 8
|
||||||
|
* different mouse buttons.
|
||||||
*
|
*
|
||||||
* @param glfwButton the raw GLFW button index.
|
* @param glfwButton the raw GLFW button index.
|
||||||
* @return the mapped {@link MouseInput} button id.
|
* @return the mapped {@link MouseInput} button id.
|
||||||
*/
|
*/
|
||||||
private int convertButton(final int glfwButton) {
|
private int convertButton(final int glfwButton) {
|
||||||
if (glfwButton == GLFW_MOUSE_BUTTON_LEFT) {
|
switch (glfwButton) {
|
||||||
|
case GLFW_MOUSE_BUTTON_LEFT:
|
||||||
return MouseInput.BUTTON_LEFT;
|
return MouseInput.BUTTON_LEFT;
|
||||||
} else if(glfwButton == GLFW_MOUSE_BUTTON_MIDDLE) {
|
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||||
return MouseInput.BUTTON_MIDDLE;
|
return MouseInput.BUTTON_MIDDLE;
|
||||||
} else if(glfwButton == GLFW_MOUSE_BUTTON_RIGHT) {
|
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||||
return MouseInput.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.lwjgl.LwjglGLFboGL3;
|
||||||
import com.jme3.renderer.opengl.*;
|
import com.jme3.renderer.opengl.*;
|
||||||
import com.jme3.system.*;
|
import com.jme3.system.*;
|
||||||
import org.lwjgl.Sys;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.lwjgl.opengl.ARBDebugOutput;
|
|
||||||
import org.lwjgl.opengl.ARBFramebufferObject;
|
import org.lwjgl.opengl.ARBFramebufferObject;
|
||||||
import org.lwjgl.opengl.EXTFramebufferMultisample;
|
import org.lwjgl.opengl.EXTFramebufferMultisample;
|
||||||
import org.lwjgl.opengl.GLCapabilities;
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
@ -53,9 +51,10 @@ import org.lwjgl.opengl.GLCapabilities;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
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.GL.createCapabilities;
|
||||||
import static org.lwjgl.opengl.GL11.GL_TRUE;
|
|
||||||
import static org.lwjgl.opengl.GL11.glGetInteger;
|
import static org.lwjgl.opengl.GL11.glGetInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,40 +83,22 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void printContextInitInfo() {
|
protected void printContextInitInfo() {
|
||||||
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n" +
|
logger.log(Level.INFO, "LWJGL {0} context running on thread {1}\n"
|
||||||
" * Graphics Adapter: GLFW {2}",
|
+ " * Graphics Adapter: GLFW {2}",
|
||||||
new Object[]{Sys.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
|
new Object[]{org.lwjgl.Version.getVersion(), Thread.currentThread().getName(), GLFW.glfwGetVersionString()});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int determineMaxSamples() {
|
protected int determineMaxSamples() {
|
||||||
// If we already have a valid context, determine samples using current context.
|
// 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);
|
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 glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Integer.MAX_VALUE;
|
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() {
|
protected int getNumSamplesToUse() {
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
if (settings.getSamples() > 1) {
|
if (settings.getSamples() > 1) {
|
||||||
@ -135,6 +116,17 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void loadNatives() {
|
||||||
|
if (JmeSystem.isLowPermissions()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NativeLibraryLoader.isUsingNativeBullet()) {
|
||||||
|
NativeLibraryLoader.loadNativeLibrary("bulletjme", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void initContextFirstTime() {
|
protected void initContextFirstTime() {
|
||||||
final GLCapabilities capabilities = createCapabilities(settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3));
|
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")) {
|
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.setMainFrameBufferSrgb(settings.isGammaCorrection());
|
||||||
renderer.setLinearizeSrgbImages(settings.getGammaCorrection());
|
renderer.setLinearizeSrgbImages(settings.isGammaCorrection());
|
||||||
|
|
||||||
// Init input
|
// Init input
|
||||||
if (keyInput != null) {
|
if (keyInput != null) {
|
||||||
@ -198,7 +190,6 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
if (joyInput != null) {
|
if (joyInput != null) {
|
||||||
joyInput.initialize();
|
joyInput.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderable.set(true);
|
renderable.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,26 +231,32 @@ public abstract class LwjglContext implements JmeContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isCreated() {
|
public boolean isCreated() {
|
||||||
return created.get();
|
return created.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isRenderable() {
|
public boolean isRenderable() {
|
||||||
return renderable.get();
|
return renderable.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setSettings(AppSettings settings) {
|
public void setSettings(AppSettings settings) {
|
||||||
this.settings.copyFrom(settings);
|
this.settings.copyFrom(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public AppSettings getSettings() {
|
public AppSettings getSettings() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Renderer getRenderer() {
|
public Renderer getRenderer() {
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Timer getTimer() {
|
public Timer getTimer() {
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ import com.jme3.system.AppSettings;
|
|||||||
import com.jme3.system.JmeContext;
|
import com.jme3.system.JmeContext;
|
||||||
import com.jme3.system.JmeSystem;
|
import com.jme3.system.JmeSystem;
|
||||||
import com.jme3.system.NanoTimer;
|
import com.jme3.system.NanoTimer;
|
||||||
import org.lwjgl.Sys;
|
|
||||||
import org.lwjgl.glfw.*;
|
import org.lwjgl.glfw.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@ -52,6 +51,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import org.lwjgl.Version;
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
import static org.lwjgl.opengl.GL11.GL_FALSE;
|
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 wasActive = false;
|
||||||
protected boolean autoFlush = true;
|
protected boolean autoFlush = true;
|
||||||
protected boolean allowSwapBuffers = false;
|
protected boolean allowSwapBuffers = false;
|
||||||
private long window = -1;
|
private long window = NULL;
|
||||||
private final JmeContext.Type type;
|
private final JmeContext.Type type;
|
||||||
private int frameRateLimit = -1;
|
private int frameRateLimit = -1;
|
||||||
private double frameSleepTime;
|
private double frameSleepTime;
|
||||||
@ -81,6 +81,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
private GLFWWindowSizeCallback windowSizeCallback;
|
private GLFWWindowSizeCallback windowSizeCallback;
|
||||||
private GLFWWindowFocusCallback windowFocusCallback;
|
private GLFWWindowFocusCallback windowFocusCallback;
|
||||||
|
|
||||||
|
private Thread mainThread;
|
||||||
|
|
||||||
public LwjglWindow(final JmeContext.Type type) {
|
public LwjglWindow(final JmeContext.Type type) {
|
||||||
if (!JmeContext.Type.Display.equals(type) && !JmeContext.Type.OffscreenSurface.equals(type) && !JmeContext.Type.Canvas.equals(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");
|
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
|
* @param title the title to set
|
||||||
*/
|
*/
|
||||||
public void setTitle(final String title) {
|
public void setTitle(final String title) {
|
||||||
if (created.get() && window != -1) {
|
if (created.get() && window != NULL) {
|
||||||
glfwSetWindowTitle(window, title);
|
glfwSetWindowTitle(window, title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,45 +129,45 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() {
|
glfwSetErrorCallback(errorCallback = new GLFWErrorCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(int error, long description) {
|
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));
|
listener.handleError(message, new Exception(message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (glfwInit() != GL_TRUE) {
|
if (glfwInit() != GLFW_TRUE) {
|
||||||
throw new IllegalStateException("Unable to initialize GLFW");
|
throw new IllegalStateException("Unable to initialize GLFW");
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwDefaultWindowHints();
|
glfwDefaultWindowHints();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.getBoolean("RendererDebug")) {
|
||||||
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.isGammaCorrection()) {
|
||||||
|
glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
|
||||||
// TODO: Add support for monitor selection
|
glfwWindowHint(GLFW_DOUBLE_BUFFER, GLFW_TRUE);
|
||||||
long monitor = NULL;
|
|
||||||
|
|
||||||
if (settings.isFullscreen()) {
|
|
||||||
monitor = glfwGetPrimaryMonitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ByteBuffer videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
|
||||||
|
|
||||||
if (settings.getWidth() <= 0 || settings.getHeight() <= 0) {
|
|
||||||
settings.setResolution(GLFWvidmode.width(videoMode), GLFWvidmode.height(videoMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
window = glfwCreateWindow(settings.getWidth(), settings.getHeight(), settings.getTitle(), monitor, NULL);
|
|
||||||
|
|
||||||
if (window == NULL) {
|
|
||||||
throw new RuntimeException("Failed to create the GLFW window");
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, settings.isResizable() ? GL_TRUE : GL_FALSE);
|
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits());
|
glfwWindowHint(GLFW_DEPTH_BITS, settings.getDepthBits());
|
||||||
glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits());
|
glfwWindowHint(GLFW_STENCIL_BITS, settings.getStencilBits());
|
||||||
glfwWindowHint(GLFW_SAMPLES, settings.getSamples());
|
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());
|
glfwWindowHint(GLFW_REFRESH_RATE, settings.getFrequency());
|
||||||
|
|
||||||
// Not sure how else to support bits per pixel
|
|
||||||
if (settings.getBitsPerPixel() == 24) {
|
if (settings.getBitsPerPixel() == 24) {
|
||||||
glfwWindowHint(GLFW_RED_BITS, 8);
|
glfwWindowHint(GLFW_RED_BITS, 8);
|
||||||
glfwWindowHint(GLFW_GREEN_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());
|
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() {
|
glfwSetWindowFocusCallback(window, windowFocusCallback = new GLFWWindowFocusCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(final long window, final int focused) {
|
public void invoke(final long window, final int focused) {
|
||||||
final boolean focus = (focused == GL_TRUE);
|
final boolean focus = (focused == GL_TRUE);
|
||||||
|
|
||||||
if (wasActive != focus) {
|
if (wasActive != focus) {
|
||||||
if (!wasActive) {
|
if (!wasActive) {
|
||||||
listener.gainFocus();
|
listener.gainFocus();
|
||||||
@ -197,8 +226,10 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Center the window
|
// Center the window
|
||||||
if (!settings.isFullscreen() && Type.Display.equals(type)) {
|
if (!settings.isFullscreen()) {
|
||||||
glfwSetWindowPos(window, (GLFWvidmode.width(videoMode) - settings.getWidth()) / 2, (GLFWvidmode.height(videoMode) - settings.getHeight()) / 2);
|
glfwSetWindowPos(window,
|
||||||
|
(videoMode.width() - settings.getWidth()) / 2,
|
||||||
|
(videoMode.height() - settings.getHeight()) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the OpenGL context current
|
// Make the OpenGL context current
|
||||||
@ -211,19 +242,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the window visible
|
|
||||||
if (Type.Display.equals(type)) {
|
|
||||||
glfwShowWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a resize callback which delegates to the listener
|
glfwShowWindow(window);
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
allowSwapBuffers = settings.isSwapBuffers();
|
allowSwapBuffers = settings.isSwapBuffers();
|
||||||
|
|
||||||
@ -239,29 +259,40 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
renderer.cleanup();
|
renderer.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errorCallback != null) {
|
||||||
errorCallback.release();
|
errorCallback.release();
|
||||||
windowSizeCallback.release();
|
errorCallback = null;
|
||||||
windowFocusCallback.release();
|
}
|
||||||
|
|
||||||
if (window != 0) {
|
if (windowSizeCallback != null) {
|
||||||
|
windowSizeCallback.release();
|
||||||
|
windowSizeCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowFocusCallback != null) {
|
||||||
|
windowFocusCallback.release();
|
||||||
|
windowFocusCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window != NULL) {
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
|
window = NULL;
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
listener.handleError("Failed to destroy context", ex);
|
listener.handleError("Failed to destroy context", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void create(boolean waitFor) {
|
public void create(boolean waitFor) {
|
||||||
if (created.get()) {
|
if (created.get()) {
|
||||||
LOGGER.warning("create() called when display is already created!");
|
LOGGER.warning("create() called when display is already created!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new Thread(this, THREAD_NAME).start();
|
// NOTE: this is required for Mac OS X!
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
if (waitFor) {
|
run();
|
||||||
waitFor(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -272,6 +303,7 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
if (!JmeSystem.isLowPermissions()) {
|
if (!JmeSystem.isLowPermissions()) {
|
||||||
// Enable uncaught exception handler only for current thread
|
// Enable uncaught exception handler only for current thread
|
||||||
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
|
@Override
|
||||||
public void uncaughtException(Thread thread, Throwable thrown) {
|
public void uncaughtException(Thread thread, Throwable thrown) {
|
||||||
listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown);
|
listener.handleError("Uncaught exception thrown in " + thread.toString(), thrown);
|
||||||
if (needClose.get()) {
|
if (needClose.get()) {
|
||||||
@ -283,6 +315,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadNatives();
|
||||||
|
|
||||||
timer = new NanoTimer();
|
timer = new NanoTimer();
|
||||||
|
|
||||||
// For canvas, this will create a pbuffer,
|
// For canvas, this will create a pbuffer,
|
||||||
@ -296,8 +330,9 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
super.internalCreate();
|
super.internalCreate();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
try {
|
try {
|
||||||
if (window != -1) {
|
if (window != NULL) {
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
|
window = NULL;
|
||||||
}
|
}
|
||||||
} catch (Exception ex2) {
|
} catch (Exception ex2) {
|
||||||
LOGGER.log(Level.WARNING, null, 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 a restart is required, lets recreate the context.
|
||||||
if (needRestart.getAndSet(false)) {
|
if (needRestart.getAndSet(false)) {
|
||||||
try {
|
try {
|
||||||
|
destroyContext();
|
||||||
createContext(settings);
|
createContext(settings);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to set display settings!", 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
|
// Subclasses just call GLObjectManager clean up objects here
|
||||||
// it is safe .. for now.
|
// it is safe .. for now.
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
@ -377,6 +411,8 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFrameRateLimit(int frameRateLimit) {
|
private void setFrameRateLimit(int frameRateLimit) {
|
||||||
@ -389,21 +425,22 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
protected void deinitInThread() {
|
protected void deinitInThread() {
|
||||||
destroyContext();
|
|
||||||
|
|
||||||
listener.destroy();
|
listener.destroy();
|
||||||
LOGGER.fine("Display destroyed.");
|
|
||||||
|
destroyContext();
|
||||||
super.internalDestroy();
|
super.internalDestroy();
|
||||||
|
|
||||||
|
LOGGER.fine("Display destroyed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
throw new IllegalStateException("SystemListener is not set on context!"
|
throw new IllegalStateException("SystemListener is not set on context!"
|
||||||
+ "Must set with JmeContext.setSystemListener().");
|
+ "Must set with JmeContext.setSystemListener().");
|
||||||
}
|
}
|
||||||
|
|
||||||
loadNatives();
|
LOGGER.log(Level.FINE, "Using LWJGL {0}", Version.getVersion());
|
||||||
LOGGER.log(Level.FINE, "Using LWJGL {0}", Sys.getVersion());
|
|
||||||
|
|
||||||
if (!initInThread()) {
|
if (!initInThread()) {
|
||||||
LOGGER.log(Level.SEVERE, "Display initialization failed. Cannot continue.");
|
LOGGER.log(Level.SEVERE, "Display initialization failed. Cannot continue.");
|
||||||
@ -411,15 +448,16 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (glfwWindowShouldClose(window) == GL_TRUE) {
|
|
||||||
listener.requestClose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
runLoop();
|
runLoop();
|
||||||
|
|
||||||
if (needClose.get()) {
|
if (needClose.get()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (glfwWindowShouldClose(window) == GL_TRUE) {
|
||||||
|
listener.requestClose(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinitInThread();
|
deinitInThread();
|
||||||
@ -458,6 +496,11 @@ public abstract class LwjglWindow extends LwjglContext implements Runnable {
|
|||||||
public void destroy(boolean waitFor) {
|
public void destroy(boolean waitFor) {
|
||||||
needClose.set(true);
|
needClose.set(true);
|
||||||
|
|
||||||
|
if (mainThread == Thread.currentThread()) {
|
||||||
|
// Ignore waitFor.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (waitFor) {
|
if (waitFor) {
|
||||||
waitFor(false);
|
waitFor(false);
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ public class DefaultClient implements Client
|
|||||||
|
|
||||||
protected void closeConnections( DisconnectInfo info )
|
protected void closeConnections( DisconnectInfo info )
|
||||||
{
|
{
|
||||||
|
synchronized(this) {
|
||||||
if( !isRunning )
|
if( !isRunning )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -324,14 +325,16 @@ public class DefaultClient implements Client
|
|||||||
// Just in case we never fully connected
|
// Just in case we never fully connected
|
||||||
connecting.countDown();
|
connecting.countDown();
|
||||||
|
|
||||||
fireDisconnected(info);
|
|
||||||
|
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
|
|
||||||
// Terminate the services
|
// Terminate the services
|
||||||
services.terminate();
|
services.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we aren't synched while firing events
|
||||||
|
fireDisconnected(info);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addClientStateListener( ClientStateListener listener )
|
public void addClientStateListener( ClientStateListener listener )
|
||||||
{
|
{
|
||||||
@ -462,11 +465,17 @@ public class DefaultClient implements Client
|
|||||||
this.id = (int)crm.getId();
|
this.id = (int)crm.getId();
|
||||||
log.log( Level.FINE, "Connection established, id:{0}.", this.id );
|
log.log( Level.FINE, "Connection established, id:{0}.", this.id );
|
||||||
connecting.countDown();
|
connecting.countDown();
|
||||||
fireConnected();
|
//fireConnected();
|
||||||
} else {
|
} else {
|
||||||
// Else it's a message letting us know that the
|
// Else it's a message letting us know that the
|
||||||
// hosted services have been started
|
// hosted services have been started
|
||||||
startServices();
|
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;
|
return;
|
||||||
} else if( m instanceof ChannelInfoMessage ) {
|
} else if( m instanceof ChannelInfoMessage ) {
|
||||||
|
@ -608,7 +608,7 @@ public class DefaultServer implements Server
|
|||||||
// should always already be closed through all paths that I
|
// should always already be closed through all paths that I
|
||||||
// can conceive... but it doesn't hurt to be sure.
|
// can conceive... but it doesn't hurt to be sure.
|
||||||
for( Endpoint p : channels ) {
|
for( Endpoint p : channels ) {
|
||||||
if( p == null )
|
if( p == null || !p.isConnected() )
|
||||||
continue;
|
continue;
|
||||||
p.close();
|
p.close();
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,8 @@ public class KernelAdapter extends Thread
|
|||||||
|
|
||||||
// Kill the kernel
|
// Kill the kernel
|
||||||
kernel.terminate();
|
kernel.terminate();
|
||||||
|
|
||||||
|
join();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reportError( Endpoint p, Object context, Exception e )
|
protected void reportError( Endpoint p, Object context, Exception e )
|
||||||
@ -120,9 +122,11 @@ public class KernelAdapter extends Thread
|
|||||||
// retrieve them. For now we'll just log it. FIXME
|
// retrieve them. For now we'll just log it. FIXME
|
||||||
log.log( Level.SEVERE, "Unhandled error, endpoint:" + p + ", context:" + context, e );
|
log.log( Level.SEVERE, "Unhandled error, endpoint:" + p + ", context:" + context, e );
|
||||||
|
|
||||||
|
if( p.isConnected() ) {
|
||||||
// In lieu of other options, at least close the endpoint
|
// In lieu of other options, at least close the endpoint
|
||||||
p.close();
|
p.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected HostedConnection getConnection( Endpoint p )
|
protected HostedConnection getConnection( Endpoint p )
|
||||||
{
|
{
|
||||||
|
@ -181,7 +181,7 @@ public class MessageProtocol
|
|||||||
Message m = (Message)obj;
|
Message m = (Message)obj;
|
||||||
messages.add(m);
|
messages.add(m);
|
||||||
} catch( IOException e ) {
|
} 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 );
|
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()
|
protected long nextEndpointId()
|
||||||
{
|
{
|
||||||
return nextId.getAndIncrement();
|
return nextId.getAndIncrement();
|
||||||
|
@ -106,6 +106,9 @@ public class SelectorKernel extends AbstractKernel
|
|||||||
try {
|
try {
|
||||||
thread.close();
|
thread.close();
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
|
// Need to let any caller waiting for a read() wakeup
|
||||||
|
wakeupReader();
|
||||||
} catch( IOException e ) {
|
} catch( IOException e ) {
|
||||||
throw new KernelException( "Error closing host connection:" + address, 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
|
// Enqueue an endpoint event for the listeners
|
||||||
addEvent( EndpointEvent.createRemove( this, p ) );
|
addEvent( EndpointEvent.createRemove( this, p ) );
|
||||||
|
|
||||||
// If there are no pending messages then add one so that the
|
wakeupReader();
|
||||||
// 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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,6 +110,9 @@ public class UdpKernel extends AbstractKernel
|
|||||||
thread.close();
|
thread.close();
|
||||||
writer.shutdown();
|
writer.shutdown();
|
||||||
thread = null;
|
thread = null;
|
||||||
|
|
||||||
|
// Need to let any caller waiting for a read() wakeup
|
||||||
|
wakeupReader();
|
||||||
} catch( IOException e ) {
|
} catch( IOException e ) {
|
||||||
throw new KernelException( "Error closing host connection:" + address, e );
|
throw new KernelException( "Error closing host connection:" + address, e );
|
||||||
}
|
}
|
||||||
@ -170,15 +173,7 @@ public class UdpKernel extends AbstractKernel
|
|||||||
|
|
||||||
addEvent( EndpointEvent.createRemove( this, p ) );
|
addEvent( EndpointEvent.createRemove( this, p ) );
|
||||||
|
|
||||||
// If there are no pending messages then add one so that the
|
wakeupReader();
|
||||||
// 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 void newData( DatagramPacket packet )
|
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
|
// that also run their own servers but realistically they would have
|
||||||
// to disable the ServerSerializerRegistrationsServer anyway.
|
// to disable the ServerSerializerRegistrationsServer anyway.
|
||||||
if( compiled != null ) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.log(Level.FINE, "Registering {0} classes...", registrations.length);
|
||||||
for( Registration reg : registrations ) {
|
for( Registration reg : registrations ) {
|
||||||
log.log( Level.INFO, "Registering:{0}", reg);
|
log.log(Level.INFO, "Registering:{0}", reg);
|
||||||
reg.register();
|
reg.register();
|
||||||
}
|
}
|
||||||
|
log.log(Level.FINE, "Done registering serializable classes.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -187,7 +189,7 @@ public class SerializerRegistrationsMessage extends AbstractMessage {
|
|||||||
serializer = (Serializer)serializerType.newInstance();
|
serializer = (Serializer)serializerType.newInstance();
|
||||||
}
|
}
|
||||||
SerializerRegistration result = Serializer.registerClassForId(id, type, serializer);
|
SerializerRegistration result = Serializer.registerClassForId(id, type, serializer);
|
||||||
log.log( Level.FINE, " result:{0}", result);
|
log.log(Level.FINE, " result:{0}", result);
|
||||||
} catch( ClassNotFoundException e ) {
|
} catch( ClassNotFoundException e ) {
|
||||||
throw new RuntimeException( "Class not found attempting to register:" + this, e );
|
throw new RuntimeException( "Class not found attempting to register:" + this, e );
|
||||||
} catch( InstantiationException e ) {
|
} catch( InstantiationException e ) {
|
||||||
|
@ -425,6 +425,22 @@ public abstract class Serializer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SerializerRegistration reg = writeClass(buffer, object.getClass());
|
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);
|
reg.getSerializer().writeObject(buffer, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,9 @@ public class EnumSerializer extends Serializer {
|
|||||||
|
|
||||||
if (ordinal == -1) return null;
|
if (ordinal == -1) return null;
|
||||||
T[] enumConstants = c.getEnumConstants();
|
T[] enumConstants = c.getEnumConstants();
|
||||||
if (enumConstants == null)
|
if (enumConstants == null) {
|
||||||
throw new SerializerException( "Class has no enum constants:" + c );
|
throw new SerializerException("Class has no enum constants:" + c + " Ordinal:" + ordinal);
|
||||||
|
}
|
||||||
return enumConstants[ordinal];
|
return enumConstants[ordinal];
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -34,11 +34,14 @@ package com.jme3.network.serializing.serializers;
|
|||||||
import com.jme3.network.serializing.Serializer;
|
import com.jme3.network.serializing.Serializer;
|
||||||
import com.jme3.network.serializing.SerializerException;
|
import com.jme3.network.serializing.SerializerException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.nio.BufferOverflowException;
|
import java.nio.BufferOverflowException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The field serializer is the default serializer used for custom class.
|
* The field serializer is the default serializer used for custom class.
|
||||||
@ -46,16 +49,35 @@ import java.util.*;
|
|||||||
* @author Lars Wesselius, Nathan Sweet
|
* @author Lars Wesselius, Nathan Sweet
|
||||||
*/
|
*/
|
||||||
public class FieldSerializer extends Serializer {
|
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, SavedField[]> savedFields = new HashMap<Class, SavedField[]>();
|
||||||
|
private static Map<Class, Constructor> savedCtors = new HashMap<Class, Constructor>();
|
||||||
|
|
||||||
protected void checkClass(Class clazz) {
|
protected void checkClass(Class clazz) {
|
||||||
|
|
||||||
// See if the class has a public no-arg constructor
|
// See if the class has a public no-arg constructor
|
||||||
try {
|
try {
|
||||||
clazz.getConstructor();
|
savedCtors.put(clazz, clazz.getConstructor());
|
||||||
|
return;
|
||||||
} catch( NoSuchMethodException e ) {
|
} 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) {
|
public void initialize(Class clazz) {
|
||||||
@ -121,7 +143,8 @@ public class FieldSerializer extends Serializer {
|
|||||||
|
|
||||||
T object;
|
T object;
|
||||||
try {
|
try {
|
||||||
object = c.newInstance();
|
Constructor<T> ctor = (Constructor<T>)savedCtors.get(c);
|
||||||
|
object = ctor.newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SerializerException( "Error creating object of type:" + c, e );
|
throw new SerializerException( "Error creating object of type:" + c, e );
|
||||||
}
|
}
|
||||||
@ -129,6 +152,9 @@ public class FieldSerializer extends Serializer {
|
|||||||
for (SavedField savedField : fields) {
|
for (SavedField savedField : fields) {
|
||||||
Field field = savedField.field;
|
Field field = savedField.field;
|
||||||
Serializer serializer = savedField.serializer;
|
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;
|
Object value;
|
||||||
|
|
||||||
if (serializer != null) {
|
if (serializer != null) {
|
||||||
@ -164,9 +190,12 @@ public class FieldSerializer extends Serializer {
|
|||||||
try {
|
try {
|
||||||
val = savedField.field.get(object);
|
val = savedField.field.get(object);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
throw new SerializerException("Unable to access field:" + savedField.field + " on:" + object, e);
|
||||||
}
|
}
|
||||||
Serializer serializer = savedField.serializer;
|
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 {
|
try {
|
||||||
if (serializer != null) {
|
if (serializer != null) {
|
||||||
|
@ -351,6 +351,11 @@ public class RmiRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object invoke( short procId, Object[] args ) {
|
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);
|
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 "${ant.java.version}"/>
|
|
||||||
<condition property="have-jdk-older-than-1.4">
|
|
||||||
<or>
|
|
||||||
<contains string="${version-output}" substring="java version "1.0"/>
|
|
||||||
<contains string="${version-output}" substring="java version "1.1"/>
|
|
||||||
<contains string="${version-output}" substring="java version "1.2"/>
|
|
||||||
<contains string="${version-output}" substring="java version "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…
x
Reference in New Issue
Block a user