Merge branch 'master' into experimental

experimental
Kirill Vainer 9 years ago
commit 0aaa28e66b
  1. 5
      .travis.yml
  2. 29
      bintray.gradle
  3. 8
      build.gradle
  4. 63
      common.gradle
  5. 4
      gradle.properties
  6. 2
      jme3-core/src/main/java/com/jme3/asset/AssetKey.java
  7. 38
      jme3-core/src/main/java/com/jme3/audio/AudioNode.java
  8. 11
      jme3-core/src/main/java/com/jme3/effect/ParticleEmitter.java
  9. 117
      jme3-core/src/main/java/com/jme3/scene/BatchNode.java
  10. 97
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikkTSpaceContext.java
  11. 100
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikkTSpaceImpl.java
  12. 1717
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java
  13. 1
      sdk/build.gradle
  14. 2
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java
  15. 1
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java
  16. 14
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorToolBar.java
  17. 27
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/TechniqueBlock.java
  18. 5
      sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java
  19. 2
      sdk/jme3-welcome-screen/src/com/jme3/gde/welcome/Bundle.properties
  20. 254
      version.gradle

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

@ -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,8 +5,8 @@
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'maven' apply plugin: 'maven'
group = 'com.jme3' group = 'org.jmonkeyengine'
version = releaseInfo.pomVersion version = jmePomVersion
sourceCompatibility = '1.6' sourceCompatibility = '1.6'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
@ -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
}
}
}
} }
} }

@ -35,3 +35,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=

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

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

@ -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>();
/** /**
@ -119,7 +120,6 @@ public class BatchNode extends GeometryGroupNode {
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;
}
} }

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

@ -109,6 +109,7 @@ task createBaseXml(dependsOn: configurations.corelibs) <<{
dep.dependencyProject.configurations.archives.allArtifacts.each{ artifact-> dep.dependencyProject.configurations.archives.allArtifacts.each{ artifact->
if(artifact.classifier == "sources"){ if(artifact.classifier == "sources"){
} else if(artifact.classifier == "javadoc"){ } else if(artifact.classifier == "javadoc"){
} else if(artifact.file.name.endsWith('.pom')) {
} else{ } else{
if(!jmeJarFiles.contains(artifact.file)){ if(!jmeJarFiles.contains(artifact.file)){
jmeJarFiles.add(artifact.file) jmeJarFiles.add(artifact.file)

@ -186,7 +186,7 @@ public class EditableMatDefFile {
return ""; return "";
} catch (Exception e) { } catch (Exception e) {
Exceptions.printStackTrace(e); Exceptions.printStackTrace(e);
return "error generating shader " + e.getMessage(); return "Error generating shader: " + e.getMessage();
} }
} }

@ -142,6 +142,7 @@ public class MatDefDataObject extends MultiDataObject {
findAssetManager(); findAssetManager();
final MatDefMetaData metaData = new MatDefMetaData(this); final MatDefMetaData metaData = new MatDefMetaData(this);
lookupContents.add(metaData); lookupContents.add(metaData);
lookupContents.add(new MatDefNavigatorPanel());
pf.addFileChangeListener(new FileChangeAdapter() { pf.addFileChangeListener(new FileChangeAdapter() {
@Override @Override
public void fileChanged(FileEvent fe) { public void fileChanged(FileEvent fe) {

@ -8,6 +8,8 @@ package com.jme3.gde.materialdefinition.editor;
import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock; import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock;
import java.awt.Component; import java.awt.Component;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -23,6 +25,7 @@ public class MatDefEditorToolBar extends javax.swing.JPanel {
private MatDefEditorlElement parent; private MatDefEditorlElement parent;
private final DefaultComboBoxModel<TechniqueBlock> comboModel = new DefaultComboBoxModel<TechniqueBlock>(); private final DefaultComboBoxModel<TechniqueBlock> comboModel = new DefaultComboBoxModel<TechniqueBlock>();
private final static Logger logger = Logger.getLogger(MatDefEditorToolBar.class.getName());
/** /**
* Creates new form MatDefEditorToolBar * Creates new form MatDefEditorToolBar
@ -130,6 +133,17 @@ public class MatDefEditorToolBar extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void techniqueComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_techniqueComboBoxActionPerformed private void techniqueComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_techniqueComboBoxActionPerformed
if (techniqueComboBox.getSelectedItem() == null) {
if (techniqueComboBox.getItemCount() > 0) {
if (techniqueComboBox.getItemCount() > 1) {
logger.log(Level.WARNING, "No Technique selected, taking the first one!"); /* Don't be over verbose: When there's only one Element, you can't select itself again, thus null */
}
techniqueComboBox.setSelectedIndex(0); /* Take the first one available */
} else {
logger.log(Level.WARNING, "No Techniques known for this MaterialDef. Please add one using the button to the right!");
return;
}
}
parent.switchTechnique((TechniqueBlock) techniqueComboBox.getSelectedItem()); parent.switchTechnique((TechniqueBlock) techniqueComboBox.getSelectedItem());
}//GEN-LAST:event_techniqueComboBoxActionPerformed }//GEN-LAST:event_techniqueComboBoxActionPerformed

@ -15,6 +15,8 @@ import com.jme3.util.blockparser.Statement;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.util.WeakListeners; import org.openide.util.WeakListeners;
/** /**
@ -29,6 +31,8 @@ public class TechniqueBlock extends UberStatement {
public static final String REMOVE_WORLD_PARAM = "removeWorldParam"; public static final String REMOVE_WORLD_PARAM = "removeWorldParam";
protected String name; protected String name;
private static final Logger logger = Logger.getLogger(TechniqueBlock.class.getName());
protected TechniqueBlock(int lineNumber, String line) { protected TechniqueBlock(int lineNumber, String line) {
super(lineNumber, line); super(lineNumber, line);
} }
@ -102,7 +106,13 @@ public class TechniqueBlock extends UberStatement {
} }
public List<WorldParamBlock> getWorldParams() { public List<WorldParamBlock> getWorldParams() {
return getWorldParameters().getWorldParams(); WorldParametersBlock block = getWorldParameters();
if (block != null)
return getWorldParameters().getWorldParams();
else {
logger.log(Level.WARNING, "Unable to build ShaderNodes: Could not find any WorldParameters. Most likely the technique {0} is broken.", line);
return new ArrayList<WorldParamBlock>();
}
} }
public void addWorldParam(WorldParamBlock block) { public void addWorldParam(WorldParamBlock block) {
@ -180,8 +190,19 @@ public class TechniqueBlock extends UberStatement {
public List<ShaderNodeBlock> getShaderNodes() { public List<ShaderNodeBlock> getShaderNodes() {
List<ShaderNodeBlock> list = new ArrayList<ShaderNodeBlock>(); List<ShaderNodeBlock> list = new ArrayList<ShaderNodeBlock>();
list.addAll(getBlock(VertexShaderNodesBlock.class).getShaderNodes());
list.addAll(getBlock(FragmentShaderNodesBlock.class).getShaderNodes()); VertexShaderNodesBlock vert_block = getBlock(VertexShaderNodesBlock.class);
if (vert_block == null)
logger.log(Level.WARNING, "Unable to build ShaderNodes: Could not find any VertexShaderNode. Most likely the technique {0} is broken.", line);
else
list.addAll(vert_block.getShaderNodes());
FragmentShaderNodesBlock frag_block = getBlock(FragmentShaderNodesBlock.class);
if (frag_block == null)
logger.log(Level.WARNING, "Unable to build ShaderNodes: Could not find any FragmentShaderNode. Most likely the technique {0} is broken.", line);
else
list.addAll(frag_block.getShaderNodes());
return list; return list;
} }

@ -148,7 +148,7 @@ public class MaterialPreviewRenderer implements SceneListener {
}); });
} }
private int lastErrorHash = 0; private static int lastErrorHash = 0;
private void smartLog(String expText, String message) { private void smartLog(String expText, String message) {
int hash = message.hashCode(); int hash = message.hashCode();
@ -183,7 +183,8 @@ public class MaterialPreviewRenderer implements SceneListener {
//compilation error, the shader code will be output to the console //compilation error, the shader code will be output to the console
//the following code will output the error //the following code will output the error
//System.err.println(e.getMessage()); //System.err.println(e.getMessage());
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, e.getMessage()); //Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, e.getMessage());
smartLog("{0}", e.getMessage());
java.awt.EventQueue.invokeLater(new Runnable() { java.awt.EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {

@ -3,6 +3,6 @@ OpenIDE-Module-Long-Description=\
The jMonkeyEngine GDE Welcome Screen The jMonkeyEngine GDE Welcome Screen
OpenIDE-Module-Name=Welcome Screen OpenIDE-Module-Name=Welcome Screen
OpenIDE-Module-Short-Description=The jMonkeyEngine GDE Welcome Screen OpenIDE-Module-Short-Description=The jMonkeyEngine GDE Welcome Screen
WelcomeScreenTopComponent.http.link=http://hub.jmonkeyengine.org/wiki/doku.php/sdk:welcome:3_0?do=export_xhtmlbody WelcomeScreenTopComponent.http.link=http://hub.jmonkeyengine.org/wiki/doku.php/sdk:welcome:3_1?do=export_xhtmlbody
WelcomeScreenTopComponent.rss.link=http://hub.jmonkeyengine.org/feed/rdf/ WelcomeScreenTopComponent.rss.link=http://hub.jmonkeyengine.org/feed/rdf/
WelcomeScreenTopComponent.local.link=nbres:/com/jme3/gde/docs/sdk/welcome/local.html WelcomeScreenTopComponent.local.link=nbres:/com/jme3/gde/docs/sdk/welcome/local.html

@ -2,21 +2,33 @@
Version Info Examples Version Info Examples
===================== =====================
Nightly Build Snapshot (no git tag) Nightly Build Snapshot
* Full Version: 3.1.0-5124 * git tag:
* POM Version: 3.1.0-SNAPSHOT * Full Version: 3.1-5124
* POM Version: 3.1.0-SNAPSHOT
Nightly Build Snapshot (PBRIsComing branch) (no git tag) * NBM Revision: 5124
* Full Version: 3.1.0-PBRIsComing-5124 * NBM UC Suffix: nightly/3.1/plugins
* POM Version: 3.1.0-PBRIsComing-SNAPSHOT
Nightly Build Snapshot (PBRIsComing branch)
Alpha1 Release (git tag: v3.1-alpha1) * git tag:
* Full Version: 3.1.0-alpha1 * Full Version: 3.1-PBRIsComing-5124
* POM Version: 3.1.0-alpha1 * POM Version: 3.1.0-PBRIsComing-SNAPSHOT
* NBM Revision: 5124
Final Release (git tag: v3.1) * NBM UC Suffix: PBRIsComing-nightly/3.1/plugins
* Full Version: 3.1.0
* POM Version: 3.1.0 Alpha1 Release
* git tag: v3.1.0-alpha1
* Full Version: 3.1-alpha1
* POM Version: 3.1.0-alpha1
* NBM Revision: 0
* NBM UC Suffix: stable/3.1/plugins
Final Release
* git tag: v3.1.0
* Full Version: 3.1
* POM Version: 3.1.0
* NBM Revision: 0
* NBM UC Suffix: stable/3.1/plugins
*/ */
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -35,143 +47,113 @@ ext {
releaseInfo = null; releaseInfo = null;
} }
enum ReleaseType { def getReleaseInfo(String tag) {
Unknown, if (tag == null) {
Snapshot, // not a tagged commit
PreRelease, return null;
Release;
}
class ReleaseInfo {
String tag;
String version;
String releaseName;
ReleaseType releaseType;
String buildDate;
String branch;
String hash;
String shortHash;
int revision;
String fullVersion;
String pomVersion;
ReleaseInfo(String version, Grgit repo) {
loadBuildDate();
loadRepoInfo(version, repo);
} }
if (!tag.startsWith("v")) {
ReleaseInfo(String version) { // syntax error
loadBuildDate(); return null;
loadUnknownInfo(version); }
tag = tag.substring(1)
String[] parts = tag.split("-", 2);
String mainVersion;
boolean prerelease;
String releaseName = null;
if (parts.length == 2) {
// prerelease
prerelease = true;
mainVersion = parts[0];
releaseName = parts[1];
if (releaseName.size() == 0) {
// syntax error
return null;
}
} else if (parts.length == 1) {
// final release
prerelease = false;
mainVersion = parts[0];
} else {
// error
return null;
} }
final void loadBuildDate() { if (mainVersion.size() == 0) {
this.buildDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); // syntax error
return null;
} }
final void loadUnknownInfo(String version) { parts = mainVersion.split("\\.");
this.releaseType = ReleaseType.Unknown; if (parts.size() != 3) {
this.version = version; // syntax error
this.releaseName = "unknown"; return null;
this.tag = "";
this.revision = 0;
this.branch = "unknown";
this.hash = "";
this.shortHash = "";
this.fullVersion = "${version}-UNKNOWN";
this.pomVersion = "${version}-UNKNOWN";
} }
final void loadRepoInfo(String version, Grgit repo) { String baseVersion = parts[0] + "." + parts[1];
this.releaseType = ReleaseType.Snapshot;
this.version = version;
Commit head = repo.head(); return [
this.revision = repo.log(includes:[head]).size(); "tag" : tag,
this.hash = head.id; "baseVersion" : baseVersion,
this.shortHash = head.abbreviatedId; "mainVersion" : mainVersion,
this.branch = repo.branch.current.name; "prerelease" : prerelease,
"releaseName" : releaseName,
"releaseSuffix": (prerelease ? "-${releaseName}": "")
]
}
Tag gitTag = repo.tag.list().find { it.commit == head } task configureVersionInfo {
if (gitTag != null){ try {
this.tag = gitTag.name; def grgit = Grgit.open(project.file('.'))
def head = grgit.head()
jmeRevision = grgit.log(includes: [head]).size()
jmeGitHash = head.id
jmeShortGitHash = head.abbreviatedId
jmeBranchName = grgit.branch.current.name
jmeGitTag = grgit.tag.list().find { it.commit == head }
if (jmeGitTag != null) {
jmeGitTag = jmeGitTag.name
} else { } else {
this.tag = ""; jmeGitTag = System.env.TRAVIS_TAG
}
if (System.env.TRAVIS_BRANCH != null) {
this.branch = System.env.TRAVIS_BRANCH
}
if (System.env.TRAVIS_TAG != null) {
this.tag = System.env.TRAVIS_TAG
}
if (System.env.TRAVIS_PULL_REQUEST != null && System.env.TRAVIS_PULL_REQUEST != "false") {
this.branch += "-pr-" + System.env.TRAVIS_PULL_REQUEST
} }
loadTagInfo(this.tag); def releaseInfo = getReleaseInfo(jmeGitTag)
if (releaseInfo != null) {
this.fullVersion = version; jmeFullVersion = "${releaseInfo.baseVersion}${releaseInfo.releaseSuffix}"
if (this.branch != "master") { jmePomVersion = "${releaseInfo.mainVersion}${releaseInfo.releaseSuffix}"
this.fullVersion += "-${branch}"; jmeNbmRevision = "0"
} jmeNbmUcSuffix = "stable/${releaseInfo.baseVersion}/plugins"
} else {
switch (this.releaseType) { // SNAPSHOT
case ReleaseType.Snapshot: jmeFullVersion = jmeMainVersion
this.pomVersion = "${fullVersion}-SNAPSHOT"; jmePomVersion = jmeVersion
this.fullVersion += "-${revision}"; if (System.env.TRAVIS_BRANCH != null) {
break; jmeBranchName = System.env.TRAVIS_BRANCH
case ReleaseType.PreRelease:
this.pomVersion = "${fullVersion}-${releaseName}";
this.fullVersion += "-${releaseName}";
break;
case ReleaseType.Release:
this.pomVersion = "${fullVersion}";
break;
}
}
final void loadTagInfo(String tag) {
this.tag = tag;
if (tag == null || !tag.startsWith("v")) {
return;
}
String[] parts = tag.split("-");
if (parts.length == 2) {
if (parts[0].size() < 1 || parts[1].size() < 1) {
return;
} }
if (System.env.TRAVIS_PULL_REQUEST != null &&
releaseType = ReleaseType.PreRelease; System.env.TRAVIS_PULL_REQUEST != "false") {
version = parts[0].substring(1); jmeBranchName += "-pr-" + System.env.TRAVIS_PULL_REQUEST
releaseName = parts[1];
} else if (parts.length == 1) {
if (parts[0].size() < 1) {
return;
} }
if (jmeBranchName != "master") {
releaseType = ReleaseType.Release; jmeFullVersion += "-${jmeBranchName}"
version = parts[0]; jmePomVersion += "-${jmeBranchName}"
jmeNbmUcSuffix = "${jmeBranchName}-"
} else {
jmeNbmUcSuffix = ""
}
jmeNbmUcSuffix += "nightly/" + jmeMainVersion + "/plugins"
jmeFullVersion += "-${jmeRevision}"
jmePomVersion += "-SNAPSHOT"
jmeNbmRevision = jmeRevision
} }
}
public String toString() { logger.warn("Full Version: ${jmeFullVersion}")
return "tag = ${tag}, base_ver = ${baseVersion}, main_ver = ${mainVersion}, " + logger.warn("POM Version: ${jmePomVersion}")
"prerelease = ${prerelease}, release_name = ${releaseName}" logger.warn("NBM Revision: ${jmeNbmRevision}")
} logger.warn("NBM UC Suffix: ${jmeNbmUcSuffix}")
}
task configureVersionInfo {
try {
def repo = Grgit.open(project.file('.'))
releaseInfo = new ReleaseInfo(jmeVersion, repo);
logger.warn("Full Version: ${releaseInfo.fullVersion}")
logger.warn("POM Version: ${releaseInfo.pomVersion}")
} catch (ex) { } catch (ex) {
// Failed to get repo info // Failed to get repo info
logger.warn("Failed to get repository info: " + ex.message + ". " + \ logger.warn("Failed to get repository info: " + ex.message + ". " + \

Loading…
Cancel
Save