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

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

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

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

@ -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_URL=http://opensource.org/licenses/BSD-3-Clause
POM_LICENSE_DISTRIBUTION=repo
# Bintray settings to override in $HOME/.gradle/gradle.properties or ENV or commandline
bintray_user=
bintray_api_key=

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

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

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

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

@ -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->
if(artifact.classifier == "sources"){
} else if(artifact.classifier == "javadoc"){
} else if(artifact.file.name.endsWith('.pom')) {
} else{
if(!jmeJarFiles.contains(artifact.file)){
jmeJarFiles.add(artifact.file)

@ -186,7 +186,7 @@ public class EditableMatDefFile {
return "";
} catch (Exception 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();
final MatDefMetaData metaData = new MatDefMetaData(this);
lookupContents.add(metaData);
lookupContents.add(new MatDefNavigatorPanel());
pf.addFileChangeListener(new FileChangeAdapter() {
@Override
public void fileChanged(FileEvent fe) {

@ -8,6 +8,8 @@ package com.jme3.gde.materialdefinition.editor;
import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock;
import java.awt.Component;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
@ -23,6 +25,7 @@ public class MatDefEditorToolBar extends javax.swing.JPanel {
private MatDefEditorlElement parent;
private final DefaultComboBoxModel<TechniqueBlock> comboModel = new DefaultComboBoxModel<TechniqueBlock>();
private final static Logger logger = Logger.getLogger(MatDefEditorToolBar.class.getName());
/**
* Creates new form MatDefEditorToolBar
@ -130,6 +133,17 @@ public class MatDefEditorToolBar extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents
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());
}//GEN-LAST:event_techniqueComboBoxActionPerformed

@ -15,6 +15,8 @@ import com.jme3.util.blockparser.Statement;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.util.WeakListeners;
/**
@ -29,6 +31,8 @@ public class TechniqueBlock extends UberStatement {
public static final String REMOVE_WORLD_PARAM = "removeWorldParam";
protected String name;
private static final Logger logger = Logger.getLogger(TechniqueBlock.class.getName());
protected TechniqueBlock(int lineNumber, String line) {
super(lineNumber, line);
}
@ -102,7 +106,13 @@ public class TechniqueBlock extends UberStatement {
}
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) {
@ -180,8 +190,19 @@ public class TechniqueBlock extends UberStatement {
public List<ShaderNodeBlock> getShaderNodes() {
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;
}

@ -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) {
int hash = message.hashCode();
@ -183,7 +183,8 @@ public class MaterialPreviewRenderer implements SceneListener {
//compilation error, the shader code will be output to the console
//the following code will output the error
//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() {
public void run() {

@ -3,6 +3,6 @@ OpenIDE-Module-Long-Description=\
The jMonkeyEngine GDE Welcome Screen
OpenIDE-Module-Name=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.local.link=nbres:/com/jme3/gde/docs/sdk/welcome/local.html

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

Loading…
Cancel
Save