Merge branch 'master' into PBRisComing

Conflicts:
	jme3-core/src/main/java/com/jme3/material/Material.java
	jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
define_list_fix
Nehon 10 years ago
commit 327e0125d9
  1. 7
      CONTRIBUTING.md
  2. 6
      jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java
  3. 146
      jme3-core/src/main/java/com/jme3/material/Material.java
  4. 131
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
  5. 20
      jme3-core/src/main/java/com/jme3/scene/BatchNode.java
  6. 2
      jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
  7. 2
      jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java
  8. 2
      jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java
  9. 2
      jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java
  10. 6
      jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java
  11. 94
      jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java

@ -16,13 +16,6 @@ When you're ready to submit your code, just make a [pull request](https://help.g
- When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing. - When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing.
- If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks! - If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks!
**Note to Eclipse users:** The Eclipse [git client does not support https](http://hub.jmonkeyengine.org/forum/topic/problem-cloning-the-new-git-repository/#post-265594). The current workaround is to use the command line to clone the repository.
To import the local repository as a project follow these steps:
1. Add a line 'apply plugin: eclipse' to your common.gradle file in the main project directory.
2. Navigate to the project directory in command line and execute command 'gradle eclipse'. This will load all the dependancies for eclipse.
3. In Eclipse, add the repository as an existing Java Project.
p.s. We will try hold ourselves to a [certain standard](http://www.defmacro.org/2013/04/03/issue-etiquette.html) when it comes to GitHub etiquette. If at any point we fail to uphold this standard, let us know. p.s. We will try hold ourselves to a [certain standard](http://www.defmacro.org/2013/04/03/issue-etiquette.html) when it comes to GitHub etiquette. If at any point we fail to uphold this standard, let us know.
#### Core Contributors #### Core Contributors

@ -72,8 +72,10 @@ public class DefaultJoystickAxis implements JoystickAxis {
* @param negativeMapping The mapping to receive events when the axis is positive * @param negativeMapping The mapping to receive events when the axis is positive
*/ */
public void assignAxis(String positiveMapping, String negativeMapping){ public void assignAxis(String positiveMapping, String negativeMapping){
inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false)); if (axisIndex != -1) {
inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true)); inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false));
inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true));
}
} }
/** /**

@ -69,7 +69,7 @@ import java.util.logging.Logger;
* Setting the parameters can modify the behavior of a * Setting the parameters can modify the behavior of a
* shader. * shader.
* <p/> * <p/>
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public class Material implements CloneableSmartAsset, Cloneable, Savable { public class Material implements CloneableSmartAsset, Cloneable, Savable {
@ -146,7 +146,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* This method sets the name of the material. * This method sets the name of the material.
* The name is not the same as the asset name. * The name is not the same as the asset name.
@ -222,11 +222,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
} }
/** /**
* Compares two materials and returns true if they are equal. * Compares two materials and returns true if they are equal.
* This methods compare definition, parameters, additional render states. * This methods compare definition, parameters, additional render states.
* Since materials are mutable objects, implementing equals() properly is not possible, * Since materials are mutable objects, implementing equals() properly is not possible,
* hence the name contentEquals(). * hence the name contentEquals().
* *
* @param otherObj the material to compare to this material * @param otherObj the material to compare to this material
* @return true if the materials are equal. * @return true if the materials are equal.
*/ */
@ -234,15 +234,15 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
if (!(otherObj instanceof Material)) { if (!(otherObj instanceof Material)) {
return false; return false;
} }
Material other = (Material) otherObj; Material other = (Material) otherObj;
// Early exit if the material are the same object // Early exit if the material are the same object
if (this == other) { if (this == other) {
return true; return true;
} }
// Check material definition // Check material definition
if (this.getMaterialDef() != other.getMaterialDef()) { if (this.getMaterialDef() != other.getMaterialDef()) {
return false; return false;
} }
@ -251,12 +251,12 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
if (this.paramValues.size() != other.paramValues.size()) { if (this.paramValues.size() != other.paramValues.size()) {
return false; return false;
} }
// Checking technique // Checking technique
if (this.technique != null || other.technique != null) { if (this.technique != null || other.technique != null) {
// Techniques are considered equal if their names are the same // Techniques are considered equal if their names are the same
// E.g. if user chose custom technique for one material but // E.g. if user chose custom technique for one material but
// uses default technique for other material, the materials // uses default technique for other material, the materials
// are not equal. // are not equal.
String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default"; String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default";
String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default"; String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default";
@ -290,7 +290,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
return false; return false;
} }
} }
return true; return true;
} }
@ -305,7 +305,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
hash = 29 * hash + (this.additionalState != null ? this.additionalState.contentHashCode() : 0); hash = 29 * hash + (this.additionalState != null ? this.additionalState.contentHashCode() : 0);
return hash; return hash;
} }
/** /**
* Returns the currently active technique. * Returns the currently active technique.
* <p> * <p>
@ -436,7 +436,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
public Collection<MatParam> getParams() { public Collection<MatParam> getParams() {
return paramValues.values(); return paramValues.values();
} }
/** /**
* Returns the ListMap of all parameters set on this material. * Returns the ListMap of all parameters set on this material.
* *
@ -473,7 +473,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
*/ */
public void setParam(String name, VarType type, Object value) { public void setParam(String name, VarType type, Object value) {
checkSetParam(type, name); checkSetParam(type, name);
if (type.isTextureType()) { if (type.isTextureType()) {
setTextureParam(name, type, (Texture)value); setTextureParam(name, type, (Texture)value);
} else { } else {
@ -501,7 +501,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
if (matParam == null) { if (matParam == null) {
return; return;
} }
paramValues.remove(name); paramValues.remove(name);
if (matParam instanceof MatParamTexture) { if (matParam instanceof MatParamTexture) {
int texUnit = ((MatParamTexture) matParam).getUnit(); int texUnit = ((MatParamTexture) matParam).getUnit();
@ -728,7 +728,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
renderer.renderMesh(mesh, lodLevel, 1, null); renderer.renderMesh(mesh, lodLevel, 1, null);
} }
} }
/** /**
* Uploads the lights in the light list as two uniform arrays.<br/><br/> * * Uploads the lights in the light list as two uniform arrays.<br/><br/> *
* <p> * <p>
@ -747,30 +747,30 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
return 0; return 0;
} }
Uniform lightData = shader.getUniform("g_LightData"); Uniform lightData = shader.getUniform("g_LightData");
lightData.setVector4Length(numLights * 3);//8 lights * max 3 lightData.setVector4Length(numLights * 3);//8 lights * max 3
Uniform ambientColor = shader.getUniform("g_AmbientLightColor"); Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
if (startIndex != 0) {
if (startIndex != 0) {
// apply additive blending for 2nd and future passes // apply additive blending for 2nd and future passes
rm.getRenderer().applyRenderState(additiveLight); rm.getRenderer().applyRenderState(additiveLight);
ambientColor.setValue(VarType.Vector4, ColorRGBA.Black); ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
}else{ }else{
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true)); ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true));
} }
int lightDataIndex = 0; int lightDataIndex = 0;
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
Vector4f tmpVec = vars.vect4f1; Vector4f tmpVec = vars.vect4f1;
int curIndex; int curIndex;
int endIndex = numLights + startIndex; int endIndex = numLights + startIndex;
for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) { for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
Light l = lightList.get(curIndex); Light l = lightList.get(curIndex);
if(l.getType() == Light.Type.Ambient){ if(l.getType() == Light.Type.Ambient){
endIndex++; endIndex++;
continue; continue;
} }
ColorRGBA color = l.getColor(); ColorRGBA color = l.getColor();
@ -781,15 +781,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
l.getType().getId(), l.getType().getId(),
lightDataIndex); lightDataIndex);
lightDataIndex++; lightDataIndex++;
switch (l.getType()) { switch (l.getType()) {
case Directional: case Directional:
DirectionalLight dl = (DirectionalLight) l; DirectionalLight dl = (DirectionalLight) l;
Vector3f dir = dl.getDirection(); Vector3f dir = dl.getDirection();
//Data directly sent in view space to avoid a matrix mult for each pixel //Data directly sent in view space to avoid a matrix mult for each pixel
tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f); tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec); transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec);
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
lightDataIndex++; lightDataIndex++;
//PADDING //PADDING
@ -802,14 +801,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
float invRadius = pl.getInvRadius(); float invRadius = pl.getInvRadius();
tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f); tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec); transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec);
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
lightDataIndex++; lightDataIndex++;
//PADDING //PADDING
lightData.setVector4InArray(0,0,0,0, lightDataIndex); lightData.setVector4InArray(0,0,0,0, lightDataIndex);
lightDataIndex++; lightDataIndex++;
break; break;
case Spot: case Spot:
SpotLight sl = (SpotLight) l; SpotLight sl = (SpotLight) l;
Vector3f pos2 = sl.getPosition(); Vector3f pos2 = sl.getPosition();
Vector3f dir2 = sl.getDirection(); Vector3f dir2 = sl.getDirection();
@ -825,17 +824,17 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec); transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpVec);
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
lightDataIndex++; lightDataIndex++;
break; break;
default: default:
throw new UnsupportedOperationException("Unknown type of light: " + l.getType()); throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
} }
} }
vars.release(); vars.release();
//Padding of unsued buffer space //Padding of unsued buffer space
while(lightDataIndex < numLights * 3) { while(lightDataIndex < numLights * 3) {
lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex); lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
lightDataIndex++; lightDataIndex++;
} }
return curIndex; return curIndex;
} }
@ -882,10 +881,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
case Directional: case Directional:
DirectionalLight dl = (DirectionalLight) l; DirectionalLight dl = (DirectionalLight) l;
Vector3f dir = dl.getDirection(); Vector3f dir = dl.getDirection();
//FIXME : there is an inconstency here due to backward //FIXME : there is an inconstency here due to backward
//compatibility of the lighting shader. //compatibility of the lighting shader.
//The directional light direction is passed in the //The directional light direction is passed in the
//LightPosition uniform. The lighting shader needs to be //LightPosition uniform. The lighting shader needs to be
//reworked though in order to fix this. //reworked though in order to fix this.
tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1); tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1);
transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpLightPosition); transposeLightDataToSpace(technique.getDef().getLightSpace(), rm, tmpLightPosition);
@ -996,11 +995,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
for (TechniqueDef techDef : techDefs) { for (TechniqueDef techDef : techDefs) {
if (rendererCaps.containsAll(techDef.getRequiredCaps())) { if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
// use the first one that supports all the caps // use the first one that supports all the caps
tech = new Technique(this, techDef); tech = new Technique(this, techDef);
techniques.put(name, tech); techniques.put(name, tech);
if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() || if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() ||
tech.getDef().getLightMode() == LightMode.Disable){ tech.getDef().getLightMode() == LightMode.Disable){
break; break;
} }
} }
lastTech = techDef; lastTech = techDef;
@ -1087,7 +1086,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
Uniform u = uniforms.getValue(i); Uniform u = uniforms.getValue(i);
if (!u.isSetByCurrentMaterial()) { if (!u.isSetByCurrentMaterial()) {
if (u.getName().charAt(0) != 'g') { if (u.getName().charAt(0) != 'g') {
// Don't reset world globals! // Don't reset world globals!
// The benefits gained from this are very minimal // The benefits gained from this are very minimal
// and cause lots of matrix -> FloatBuffer conversions. // and cause lots of matrix -> FloatBuffer conversions.
u.clearValue(); u.clearValue();
@ -1102,21 +1101,21 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
* <p> * <p>
* The material is rendered as follows: * The material is rendered as follows:
* <ul> * <ul>
* <li>Determine which technique to use to render the material - * <li>Determine which technique to use to render the material -
* either what the user selected via * either what the user selected via
* {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) * {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager)
* Material.selectTechnique()}, * Material.selectTechnique()},
* or the first default technique that the renderer supports * or the first default technique that the renderer supports
* (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})<ul> * (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})<ul>
* <li>If the technique has been changed since the last frame, then it is notified via * <li>If the technique has been changed since the last frame, then it is notified via
* {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet) * {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet)
* Technique.makeCurrent()}. * Technique.makeCurrent()}.
* If the technique wants to use a shader to render the model, it should load it at this part - * If the technique wants to use a shader to render the model, it should load it at this part -
* the shader should have all the proper defines as declared in the technique definition, * the shader should have all the proper defines as declared in the technique definition,
* including those that are bound to material parameters. * including those that are bound to material parameters.
* The technique can re-use the shader from the last frame if * The technique can re-use the shader from the last frame if
* no changes to the defines occurred.</li></ul> * no changes to the defines occurred.</li></ul>
* <li>Set the {@link RenderState} to use for rendering. The render states are * <li>Set the {@link RenderState} to use for rendering. The render states are
* applied in this order (later RenderStates override earlier RenderStates):<ol> * applied in this order (later RenderStates override earlier RenderStates):<ol>
* <li>{@link TechniqueDef#getRenderState() Technique Definition's RenderState} * <li>{@link TechniqueDef#getRenderState() Technique Definition's RenderState}
* - i.e. specific renderstate that is required for the shader.</li> * - i.e. specific renderstate that is required for the shader.</li>
@ -1129,22 +1128,22 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
* <li>Uniforms bound to material parameters are updated based on the current material parameter values.</li> * <li>Uniforms bound to material parameters are updated based on the current material parameter values.</li>
* <li>Uniforms bound to world parameters are updated from the RenderManager. * <li>Uniforms bound to world parameters are updated from the RenderManager.
* Internally {@link UniformBindingManager} is used for this task.</li> * Internally {@link UniformBindingManager} is used for this task.</li>
* <li>Uniforms bound to textures will cause the texture to be uploaded as necessary. * <li>Uniforms bound to textures will cause the texture to be uploaded as necessary.
* The uniform is set to the texture unit where the texture is bound.</li></ul> * The uniform is set to the texture unit where the texture is bound.</li></ul>
* <li>If the technique uses a shader, the model is then rendered according * <li>If the technique uses a shader, the model is then rendered according
* to the lighting mode specified on the technique definition.<ul> * to the lighting mode specified on the technique definition.<ul>
* <li>{@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays * <li>{@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays
* with the first 4 lights and renders the model once.</li> * with the first 4 lights and renders the model once.</li>
* <li>{@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times, * <li>{@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times,
* for the first light it is rendered opaque, on subsequent lights it is * for the first light it is rendered opaque, on subsequent lights it is
* rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.</li> * rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.</li>
* </ul> * </ul>
* <li>For techniques that do not use shaders, * <li>For techniques that do not use shaders,
* fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):<ul> * fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):<ul>
* <li>OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated. </li> * <li>OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated. </li>
* <li>The texture set on the material is uploaded and bound. * <li>The texture set on the material is uploaded and bound.
* Currently only 1 texture is supported for fixed function techniques.</li> * Currently only 1 texture is supported for fixed function techniques.</li>
* <li>If the technique uses lighting, then OpenGL lighting state is updated * <li>If the technique uses lighting, then OpenGL lighting state is updated
* based on the light list on the geometry, otherwise OpenGL lighting is disabled.</li> * based on the light list on the geometry, otherwise OpenGL lighting is disabled.</li>
* <li>The mesh is uploaded and rendered.</li> * <li>The mesh is uploaded and rendered.</li>
* </ul> * </ul>
@ -1156,10 +1155,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
*/ */
public void render(Geometry geom, LightList lights, RenderManager rm) { public void render(Geometry geom, LightList lights, RenderManager rm) {
autoSelectTechnique(rm); autoSelectTechnique(rm);
TechniqueDef techDef = technique.getDef();
Renderer r = rm.getRenderer(); if (techDef.isNoRender()) return;
TechniqueDef techDef = technique.getDef(); Renderer r = rm.getRenderer();
if (rm.getForcedRenderState() != null) { if (rm.getForcedRenderState() != null) {
r.applyRenderState(rm.getForcedRenderState()); r.applyRenderState(rm.getForcedRenderState());
@ -1178,7 +1178,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
// reset unchanged uniform flag // reset unchanged uniform flag
clearUniformsSetByCurrent(technique.getShader()); clearUniformsSetByCurrent(technique.getShader());
rm.updateUniformBindings(technique.getWorldBindUniforms()); rm.updateUniformBindings(technique.getWorldBindUniforms());
// setup textures and uniforms // setup textures and uniforms
for (int i = 0; i < paramValues.size(); i++) { for (int i = 0; i < paramValues.size(); i++) {
@ -1224,24 +1224,24 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
// any unset uniforms will be set to 0 // any unset uniforms will be set to 0
resetUniformsNotSetByCurrent(shader); resetUniformsNotSetByCurrent(shader);
r.setShader(shader); r.setShader(shader);
renderMeshFromGeometry(r, geom); renderMeshFromGeometry(r, geom);
} }
/** /**
* Called by {@link RenderManager} to render the geometry by * Called by {@link RenderManager} to render the geometry by
* using this material. * using this material.
* *
* Note that this version of the render method * Note that this version of the render method
* does not perform light filtering. * does not perform light filtering.
* *
* @param geom The geometry to render * @param geom The geometry to render
* @param rm The render manager requesting the rendering * @param rm The render manager requesting the rendering
*/ */
public void render(Geometry geom, RenderManager rm) { public void render(Geometry geom, RenderManager rm) {
render(geom, geom.getWorldLightList(), rm); render(geom, geom.getWorldLightList(), rm);
} }
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.write(def.getAssetName(), "material_def", null); oc.write(def.getAssetName(), "material_def", null);
@ -1316,14 +1316,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
continue; continue;
} }
} }
if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) { if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) {
// Ancient version of jME3 ... // Ancient version of jME3 ...
param.setName(param.getName().substring(2)); param.setName(param.getName().substring(2));
} }
if (def.getMaterialParam(param.getName()) == null) { if (def.getMaterialParam(param.getName()) == null) {
logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..", logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..",
param.getName()); param.getName());
} else { } else {
checkSetParam(param.getVarType(), param.getName()); checkSetParam(param.getVarType(), param.getName());

@ -40,7 +40,7 @@ import java.util.*;
/** /**
* Describes a technique definition. * Describes a technique definition.
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public class TechniqueDef implements Savable { public class TechniqueDef implements Savable {
@ -49,7 +49,7 @@ public class TechniqueDef implements Savable {
* Version #1: Separate shader language for each shader source. * Version #1: Separate shader language for each shader source.
*/ */
public static final int SAVABLE_VERSION = 1; public static final int SAVABLE_VERSION = 1;
/** /**
* Describes light rendering mode. * Describes light rendering mode.
*/ */
@ -58,15 +58,15 @@ public class TechniqueDef implements Savable {
* Disable light-based rendering * Disable light-based rendering
*/ */
Disable, Disable,
/** /**
* Enable light rendering by using a single pass. * Enable light rendering by using a single pass.
* <p> * <p>
* An array of light positions and light colors is passed to the shader * An array of light positions and light colors is passed to the shader
* containing the world light list for the geometry being rendered. * containing the world light list for the geometry being rendered.
*/ */
SinglePass, SinglePass,
/** /**
* Enable light rendering by using multi-pass rendering. * Enable light rendering by using multi-pass rendering.
* <p> * <p>
@ -77,7 +77,7 @@ public class TechniqueDef implements Savable {
* passes have it set to black. * passes have it set to black.
*/ */
MultiPass, MultiPass,
/** /**
* @deprecated OpenGL1 is not supported anymore * @deprecated OpenGL1 is not supported anymore
*/ */
@ -105,15 +105,16 @@ public class TechniqueDef implements Savable {
private EnumMap<Shader.ShaderType,String> shaderLanguages; private EnumMap<Shader.ShaderType,String> shaderLanguages;
private EnumMap<Shader.ShaderType,String> shaderNames; private EnumMap<Shader.ShaderType,String> shaderNames;
private DefineList presetDefines; private DefineList presetDefines;
private boolean usesNodes = false; private boolean usesNodes = false;
private List<ShaderNode> shaderNodes; private List<ShaderNode> shaderNodes;
private ShaderGenerationInfo shaderGenerationInfo; private ShaderGenerationInfo shaderGenerationInfo;
private boolean noRender = false;
private RenderState renderState; private RenderState renderState;
private RenderState forcedRenderState; private RenderState forcedRenderState;
private LightMode lightMode = LightMode.Disable; private LightMode lightMode = LightMode.Disable;
private ShadowMode shadowMode = ShadowMode.Disable; private ShadowMode shadowMode = ShadowMode.Disable;
@ -126,7 +127,7 @@ public class TechniqueDef implements Savable {
* Creates a new technique definition. * Creates a new technique definition.
* <p> * <p>
* Used internally by the J3M/J3MD loader. * Used internally by the J3M/J3MD loader.
* *
* @param name The name of the technique, should be set to <code>null</code> * @param name The name of the technique, should be set to <code>null</code>
* for default techniques. * for default techniques.
*/ */
@ -146,7 +147,7 @@ public class TechniqueDef implements Savable {
/** /**
* Returns the name of this technique as specified in the J3MD file. * Returns the name of this technique as specified in the J3MD file.
* Default techniques have the name "Default". * Default techniques have the name "Default".
* *
* @return the name of this technique * @return the name of this technique
*/ */
public String getName(){ public String getName(){
@ -164,9 +165,9 @@ public class TechniqueDef implements Savable {
/** /**
* Set the light mode * Set the light mode
* *
* @param lightMode the light mode * @param lightMode the light mode
* *
* @see LightMode * @see LightMode
*/ */
public void setLightMode(LightMode lightMode) { public void setLightMode(LightMode lightMode) {
@ -191,9 +192,9 @@ public class TechniqueDef implements Savable {
/** /**
* Set the shadow mode. * Set the shadow mode.
* *
* @param shadowMode the shadow mode. * @param shadowMode the shadow mode.
* *
* @see ShadowMode * @see ShadowMode
*/ */
public void setShadowMode(ShadowMode shadowMode) { public void setShadowMode(ShadowMode shadowMode) {
@ -203,7 +204,7 @@ public class TechniqueDef implements Savable {
/** /**
* Returns the render state that this technique is using * Returns the render state that this technique is using
* @return the render state that this technique is using * @return the render state that this technique is using
* @see #setRenderState(com.jme3.material.RenderState) * @see #setRenderState(com.jme3.material.RenderState)
*/ */
public RenderState getRenderState() { public RenderState getRenderState() {
return renderState; return renderState;
@ -211,15 +212,37 @@ public class TechniqueDef implements Savable {
/** /**
* Sets the render state that this technique is using. * Sets the render state that this technique is using.
* *
* @param renderState the render state that this technique is using. * @param renderState the render state that this technique is using.
* *
* @see RenderState * @see RenderState
*/ */
public void setRenderState(RenderState renderState) { public void setRenderState(RenderState renderState) {
this.renderState = renderState; this.renderState = renderState;
} }
/**
* Sets if this technique should not be used to render.
*
* @param noRender not render or render ?
*
* @see NoRender
*/
public void setNoRender(boolean noRender) {
this.noRender = noRender;
}
/**
* Returns true if this technique should not be used to render.
* (eg. to not render a material with default technique)
*
* @return true if this technique should not be rendered, false otherwise.
*
*/
public boolean isNoRender(){
return noRender;
}
/** /**
* @deprecated jME3 always requires shaders now * @deprecated jME3 always requires shaders now
*/ */
@ -227,12 +250,12 @@ public class TechniqueDef implements Savable {
public boolean isUsingShaders(){ public boolean isUsingShaders(){
return true; return true;
} }
/** /**
* Returns true if this technique uses Shader Nodes, false otherwise. * Returns true if this technique uses Shader Nodes, false otherwise.
* *
* @return true if this technique uses Shader Nodes, false otherwise. * @return true if this technique uses Shader Nodes, false otherwise.
* *
*/ */
public boolean isUsingShaderNodes(){ public boolean isUsingShaderNodes(){
return usesNodes; return usesNodes;
@ -241,7 +264,7 @@ public class TechniqueDef implements Savable {
/** /**
* Gets the {@link Caps renderer capabilities} that are required * Gets the {@link Caps renderer capabilities} that are required
* by this technique. * by this technique.
* *
* @return the required renderer capabilities * @return the required renderer capabilities
*/ */
public EnumSet<Caps> getRequiredCaps() { public EnumSet<Caps> getRequiredCaps() {
@ -250,7 +273,7 @@ public class TechniqueDef implements Savable {
/** /**
* Sets the shaders that this technique definition will use. * Sets the shaders that this technique definition will use.
* *
* @param vertexShader The name of the vertex shader * @param vertexShader The name of the vertex shader
* @param fragmentShader The name of the fragment shader * @param fragmentShader The name of the fragment shader
* @param vertLanguage The vertex shader language * @param vertLanguage The vertex shader language
@ -261,7 +284,7 @@ public class TechniqueDef implements Savable {
this.shaderNames.put(Shader.ShaderType.Vertex, vertexShader); this.shaderNames.put(Shader.ShaderType.Vertex, vertexShader);
this.shaderLanguages.put(Shader.ShaderType.Fragment, fragLanguage); this.shaderLanguages.put(Shader.ShaderType.Fragment, fragLanguage);
this.shaderNames.put(Shader.ShaderType.Fragment, fragmentShader); this.shaderNames.put(Shader.ShaderType.Fragment, fragmentShader);
requiredCaps.clear(); requiredCaps.clear();
Caps vertCap = Caps.valueOf(vertLanguage); Caps vertCap = Caps.valueOf(vertLanguage);
requiredCaps.add(vertCap); requiredCaps.add(vertCap);
@ -278,17 +301,17 @@ public class TechniqueDef implements Savable {
*/ */
public void setShaderFile(EnumMap<Shader.ShaderType, String> shaderNames, EnumMap<Shader.ShaderType, String> shaderLanguages) { public void setShaderFile(EnumMap<Shader.ShaderType, String> shaderNames, EnumMap<Shader.ShaderType, String> shaderLanguages) {
requiredCaps.clear(); requiredCaps.clear();
for (Shader.ShaderType shaderType : shaderNames.keySet()) { for (Shader.ShaderType shaderType : shaderNames.keySet()) {
String language = shaderLanguages.get(shaderType); String language = shaderLanguages.get(shaderType);
String shaderFile = shaderNames.get(shaderType); String shaderFile = shaderNames.get(shaderType);
this.shaderLanguages.put(shaderType, language); this.shaderLanguages.put(shaderType, language);
this.shaderNames.put(shaderType, shaderFile); this.shaderNames.put(shaderType, shaderFile);
Caps vertCap = Caps.valueOf(language); Caps vertCap = Caps.valueOf(language);
requiredCaps.add(vertCap); requiredCaps.add(vertCap);
if (shaderType.equals(Shader.ShaderType.Geometry)) { if (shaderType.equals(Shader.ShaderType.Geometry)) {
requiredCaps.add(Caps.GeometryShader); requiredCaps.add(Caps.GeometryShader);
} else if (shaderType.equals(Shader.ShaderType.TessellationControl)) { } else if (shaderType.equals(Shader.ShaderType.TessellationControl)) {
@ -299,11 +322,11 @@ public class TechniqueDef implements Savable {
/** /**
* Returns the define name which the given material parameter influences. * Returns the define name which the given material parameter influences.
* *
* @param paramName The parameter name to look up * @param paramName The parameter name to look up
* @return The define name * @return The define name
* *
* @see #addShaderParamDefine(java.lang.String, java.lang.String) * @see #addShaderParamDefine(java.lang.String, java.lang.String)
*/ */
public String getShaderParamDefine(String paramName){ public String getShaderParamDefine(String paramName){
if (defineParams == null) { if (defineParams == null) {
@ -316,11 +339,11 @@ public class TechniqueDef implements Savable {
* Adds a define linked to a material parameter. * Adds a define linked to a material parameter.
* <p> * <p>
* Any time the material parameter on the parent material is altered, * Any time the material parameter on the parent material is altered,
* the appropriate define on the technique will be modified as well. * the appropriate define on the technique will be modified as well.
* See the method * See the method
* {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) }
* on the exact details of how the material parameter changes the define. * on the exact details of how the material parameter changes the define.
* *
* @param paramName The name of the material parameter to link to. * @param paramName The name of the material parameter to link to.
* @param defineName The name of the define parameter, e.g. USE_LIGHTING * @param defineName The name of the define parameter, e.g. USE_LIGHTING
*/ */
@ -333,26 +356,26 @@ public class TechniqueDef implements Savable {
/** /**
* Returns the {@link DefineList} for the preset defines. * Returns the {@link DefineList} for the preset defines.
* *
* @return the {@link DefineList} for the preset defines. * @return the {@link DefineList} for the preset defines.
* *
* @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object) * @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object)
*/ */
public DefineList getShaderPresetDefines() { public DefineList getShaderPresetDefines() {
return presetDefines; return presetDefines;
} }
/** /**
* Adds a preset define. * Adds a preset define.
* <p> * <p>
* Preset defines do not depend upon any parameters to be activated, * Preset defines do not depend upon any parameters to be activated,
* they are always passed to the shader as long as this technique is used. * they are always passed to the shader as long as this technique is used.
* *
* @param defineName The name of the define parameter, e.g. USE_LIGHTING * @param defineName The name of the define parameter, e.g. USE_LIGHTING
* @param type The type of the define. See * @param type The type of the define. See
* {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) }
* to see why it matters. * to see why it matters.
* *
* @param value The value of the define * @param value The value of the define
*/ */
public void addShaderPresetDefine(String defineName, VarType type, Object value){ public void addShaderPresetDefine(String defineName, VarType type, Object value){
@ -365,18 +388,18 @@ public class TechniqueDef implements Savable {
/** /**
* Returns the name of the fragment shader used by the technique, or null * Returns the name of the fragment shader used by the technique, or null
* if no fragment shader is specified. * if no fragment shader is specified.
* *
* @return the name of the fragment shader to be used. * @return the name of the fragment shader to be used.
*/ */
public String getFragmentShaderName() { public String getFragmentShaderName() {
return shaderNames.get(Shader.ShaderType.Fragment); return shaderNames.get(Shader.ShaderType.Fragment);
} }
/** /**
* Returns the name of the vertex shader used by the technique, or null * Returns the name of the vertex shader used by the technique, or null
* if no vertex shader is specified. * if no vertex shader is specified.
* *
* @return the name of the vertex shader to be used. * @return the name of the vertex shader to be used.
*/ */
public String getVertexShaderName() { public String getVertexShaderName() {
@ -389,7 +412,7 @@ public class TechniqueDef implements Savable {
public String getFragmentShaderLanguage() { public String getFragmentShaderLanguage() {
return shaderLanguages.get(Shader.ShaderType.Fragment); return shaderLanguages.get(Shader.ShaderType.Fragment);
} }
/** /**
* Returns the language of the vertex shader used in this technique. * Returns the language of the vertex shader used in this technique.
*/ */
@ -409,10 +432,10 @@ public class TechniqueDef implements Savable {
public String getShaderProgramName(Shader.ShaderType shaderType){ public String getShaderProgramName(Shader.ShaderType shaderType){
return shaderNames.get(shaderType); return shaderNames.get(shaderType);
} }
/** /**
* Adds a new world parameter by the given name. * Adds a new world parameter by the given name.
* *
* @param name The world parameter to add. * @param name The world parameter to add.
* @return True if the world parameter name was found and added * @return True if the world parameter name was found and added
* to the list of world parameters, false otherwise. * to the list of world parameters, false otherwise.
@ -421,7 +444,7 @@ public class TechniqueDef implements Savable {
if (worldBinds == null){ if (worldBinds == null){
worldBinds = new ArrayList<UniformBinding>(); worldBinds = new ArrayList<UniformBinding>();
} }
try { try {
worldBinds.add( UniformBinding.valueOf(name) ); worldBinds.add( UniformBinding.valueOf(name) );
return true; return true;
@ -437,11 +460,11 @@ public class TechniqueDef implements Savable {
public void setForcedRenderState(RenderState forcedRenderState) { public void setForcedRenderState(RenderState forcedRenderState) {
this.forcedRenderState = forcedRenderState; this.forcedRenderState = forcedRenderState;
} }
/** /**
* Returns a list of world parameters that are used by this * Returns a list of world parameters that are used by this
* technique definition. * technique definition.
* *
* @return The list of world parameters * @return The list of world parameters
*/ */
public List<UniformBinding> getWorldBindings() { public List<UniformBinding> getWorldBindings() {
@ -467,10 +490,11 @@ public class TechniqueDef implements Savable {
oc.write(lightMode, "lightMode", LightMode.Disable); oc.write(lightMode, "lightMode", LightMode.Disable);
oc.write(shadowMode, "shadowMode", ShadowMode.Disable); oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
oc.write(renderState, "renderState", null); oc.write(renderState, "renderState", null);
oc.write(noRender, "noRender", false);
oc.write(usesNodes, "usesNodes", false); oc.write(usesNodes, "usesNodes", false);
oc.writeSavableArrayList((ArrayList)shaderNodes,"shaderNodes", null); oc.writeSavableArrayList((ArrayList)shaderNodes,"shaderNodes", null);
oc.write(shaderGenerationInfo, "shaderGenerationInfo", null); oc.write(shaderGenerationInfo, "shaderGenerationInfo", null);
// TODO: Finish this when Map<String, String> export is available // TODO: Finish this when Map<String, String> export is available
// oc.write(defineParams, "defineParams", null); // oc.write(defineParams, "defineParams", null);
// TODO: Finish this when List<Enum> export is available // TODO: Finish this when List<Enum> export is available
@ -489,7 +513,8 @@ public class TechniqueDef implements Savable {
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable); lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable); shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
renderState = (RenderState) ic.readSavable("renderState", null); renderState = (RenderState) ic.readSavable("renderState", null);
noRender = ic.readBoolean("noRender", false);
if (ic.getSavableVersion(TechniqueDef.class) == 0) { if (ic.getSavableVersion(TechniqueDef.class) == 0) {
// Old version // Old version
shaderLanguages.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null)); shaderLanguages.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null));
@ -502,7 +527,7 @@ public class TechniqueDef implements Savable {
shaderLanguages.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlLanguage", null)); shaderLanguages.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlLanguage", null));
shaderLanguages.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalLanguage", null)); shaderLanguages.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalLanguage", null));
} }
usesNodes = ic.readBoolean("usesNodes", false); usesNodes = ic.readBoolean("usesNodes", false);
shaderNodes = ic.readSavableArrayList("shaderNodes", null); shaderNodes = ic.readSavableArrayList("shaderNodes", null);
shaderGenerationInfo = (ShaderGenerationInfo) ic.readSavable("shaderGenerationInfo", null); shaderGenerationInfo = (ShaderGenerationInfo) ic.readSavable("shaderGenerationInfo", null);

@ -119,19 +119,6 @@ public class BatchNode extends GeometryGroupNode {
setNeedsFullRebatch(true); setNeedsFullRebatch(true);
} }
@Override
public void updateGeometricState() {
if (!children.isEmpty()) {
for (Batch batch : batches.getArray()) {
if (batch.needMeshUpdate) {
batch.geometry.updateModelBound();
batch.geometry.updateWorldBound();
batch.needMeshUpdate = false;
}
}
}
super.updateGeometricState();
}
protected Matrix4f getTransformMatrix(Geometry g){ protected Matrix4f getTransformMatrix(Geometry g){
return g.cachedWorldMat; return g.cachedWorldMat;
@ -169,7 +156,7 @@ public class BatchNode extends GeometryGroupNode {
nvb.updateData(normBuf); nvb.updateData(normBuf);
batch.needMeshUpdate = true; batch.geometry.updateModelBound();
} }
} }
@ -234,7 +221,7 @@ public class BatchNode extends GeometryGroupNode {
batch.geometry.setMesh(m); batch.geometry.setMesh(m);
batch.geometry.getMesh().updateCounts(); batch.geometry.getMesh().updateCounts();
batch.geometry.getMesh().updateBound(); batch.geometry.updateModelBound();
batches.add(batch); batches.add(batch);
} }
if (batches.size() > 0) { if (batches.size() > 0) {
@ -747,8 +734,7 @@ public class BatchNode extends GeometryGroupNode {
} }
} }
} }
Geometry geometry; Geometry geometry;
boolean needMeshUpdate = false;
} }
protected void setNeedsFullRebatch(boolean needsFullRebatch) { protected void setNeedsFullRebatch(boolean needsFullRebatch) {

@ -459,7 +459,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
debug = true; debug = true;
} }
abstract void getReceivers(GeometryList lightReceivers); protected abstract void getReceivers(GeometryList lightReceivers);
public void postFrame(FrameBuffer out) { public void postFrame(FrameBuffer out) {
if (skipPostPass) { if (skipPostPass) {

@ -192,7 +192,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer {
} }
@Override @Override
void getReceivers(GeometryList lightReceivers) { protected void getReceivers(GeometryList lightReceivers) {
if (lightReceivers.size()==0) { if (lightReceivers.size()==0) {
for (Spatial scene : viewPort.getScenes()) { for (Spatial scene : viewPort.getScenes()) {
ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers); ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers);

@ -139,7 +139,7 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer {
} }
@Override @Override
void getReceivers(GeometryList lightReceivers) { protected void getReceivers(GeometryList lightReceivers) {
lightReceivers.clear(); lightReceivers.clear();
for (Spatial scene : viewPort.getScenes()) { for (Spatial scene : viewPort.getScenes()) {
ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers);

@ -151,7 +151,7 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer {
} }
@Override @Override
void getReceivers(GeometryList lightReceivers) { protected void getReceivers(GeometryList lightReceivers) {
lightReceivers.clear(); lightReceivers.clear();
Camera[] cameras = new Camera[1]; Camera[] cameras = new Camera[1];
cameras[0] = shadowCam; cameras[0] = shadowCam;

@ -612,9 +612,9 @@ public class TangentBinormalGenerator {
normal.normalizeLocal(); normal.normalizeLocal();
return new TriangleData( return new TriangleData(
tangent, tangent.clone(),
binormal, binormal.clone(),
normal); normal.clone());
} finally { } finally {
tmp.release(); tmp.release();
} }

@ -63,7 +63,7 @@ public class J3MLoader implements AssetLoader {
// private ErrorLogger errors; // private ErrorLogger errors;
private ShaderNodeLoaderDelegate nodesLoaderDelegate; private ShaderNodeLoaderDelegate nodesLoaderDelegate;
boolean isUseNodes = false; boolean isUseNodes = false;
private AssetManager assetManager; private AssetManager assetManager;
private AssetKey key; private AssetKey key;
@ -179,7 +179,7 @@ public class J3MLoader implements AssetLoader {
if (tex != null){ if (tex != null){
if (repeat){ if (repeat){
tex.setWrap(WrapMode.Repeat); tex.setWrap(WrapMode.Repeat);
} }
}else{ }else{
tex = new Texture2D(PlaceholderAssets.getPlaceholderImage(assetManager)); tex = new Texture2D(PlaceholderAssets.getPlaceholderImage(assetManager));
if (repeat){ if (repeat){
@ -187,7 +187,7 @@ public class J3MLoader implements AssetLoader {
} }
tex.setKey(texKey); tex.setKey(texKey);
tex.setName(texKey.getName()); tex.setName(texKey.getName());
} }
return tex; return tex;
}else{ }else{
String[] split = value.trim().split(whitespacePattern); String[] split = value.trim().split(whitespacePattern);
@ -233,15 +233,15 @@ public class J3MLoader implements AssetLoader {
} }
} }
} }
// <TYPE> <NAME> [ "(" <FFBINDING> ")" ] [-LINEAR] [ ":" <DEFAULTVAL> ] // <TYPE> <NAME> [ "(" <FFBINDING> ")" ] [-LINEAR] [ ":" <DEFAULTVAL> ]
private void readParam(String statement) throws IOException{ private void readParam(String statement) throws IOException{
String name; String name;
String defaultVal = null; String defaultVal = null;
ColorSpace colorSpace = null; ColorSpace colorSpace = null;
String[] split = statement.split(":"); String[] split = statement.split(":");
// Parse default val // Parse default val
if (split.length == 1){ if (split.length == 1){
// Doesn't contain default value // Doesn't contain default value
@ -250,14 +250,14 @@ public class J3MLoader implements AssetLoader {
throw new IOException("Parameter statement syntax incorrect"); throw new IOException("Parameter statement syntax incorrect");
} }
statement = split[0].trim(); statement = split[0].trim();
defaultVal = split[1].trim(); defaultVal = split[1].trim();
} }
if (statement.endsWith("-LINEAR")) { if (statement.endsWith("-LINEAR")) {
colorSpace = ColorSpace.Linear; colorSpace = ColorSpace.Linear;
statement = statement.substring(0, statement.length() - "-LINEAR".length()); statement = statement.substring(0, statement.length() - "-LINEAR".length());
} }
// Parse ffbinding // Parse ffbinding
int startParen = statement.indexOf("("); int startParen = statement.indexOf("(");
if (startParen != -1){ if (startParen != -1){
@ -267,32 +267,32 @@ public class J3MLoader implements AssetLoader {
// don't care about bindingStr // don't care about bindingStr
statement = statement.substring(0, startParen); statement = statement.substring(0, startParen);
} }
// Parse type + name // Parse type + name
split = statement.split(whitespacePattern); split = statement.split(whitespacePattern);
if (split.length != 2){ if (split.length != 2){
throw new IOException("Parameter statement syntax incorrect"); throw new IOException("Parameter statement syntax incorrect");
} }
VarType type; VarType type;
if (split[0].equals("Color")){ if (split[0].equals("Color")){
type = VarType.Vector4; type = VarType.Vector4;
}else{ }else{
type = VarType.valueOf(split[0]); type = VarType.valueOf(split[0]);
} }
name = split[1]; name = split[1];
Object defaultValObj = null; Object defaultValObj = null;
if (defaultVal != null){ if (defaultVal != null){
defaultValObj = readValue(type, defaultVal); defaultValObj = readValue(type, defaultVal);
} }
if(type.isTextureType()){ if(type.isTextureType()){
materialDef.addMaterialParamTexture(type, name, colorSpace); materialDef.addMaterialParamTexture(type, name, colorSpace);
}else{ }else{
materialDef.addMaterialParam(type, name, defaultValObj); materialDef.addMaterialParam(type, name, defaultValObj);
} }
} }
private void readValueParam(String statement) throws IOException{ private void readValueParam(String statement) throws IOException{
@ -387,7 +387,7 @@ public class J3MLoader implements AssetLoader {
technique.setRenderState(renderState); technique.setRenderState(renderState);
renderState = null; renderState = null;
} }
private void readForcedRenderState(List<Statement> renderStates) throws IOException{ private void readForcedRenderState(List<Statement> renderStates) throws IOException{
renderState = new RenderState(); renderState = new RenderState();
for (Statement statement : renderStates){ for (Statement statement : renderStates){
@ -396,7 +396,7 @@ public class J3MLoader implements AssetLoader {
technique.setForcedRenderState(renderState); technique.setForcedRenderState(renderState);
renderState = null; renderState = null;
} }
// <DEFINENAME> [ ":" <PARAMNAME> ] // <DEFINENAME> [ ":" <PARAMNAME> ]
private void readDefine(String statement) throws IOException{ private void readDefine(String statement) throws IOException{
String[] split = statement.split(":"); String[] split = statement.split(":");
@ -416,9 +416,9 @@ public class J3MLoader implements AssetLoader {
} }
} }
private void readTechniqueStatement(Statement statement) throws IOException{ private void readTechniqueStatement(Statement statement) throws IOException{
String[] split = statement.getLine().split("[ \\{]"); String[] split = statement.getLine().split("[ \\{]");
if (split[0].equals("VertexShader") || if (split[0].equals("VertexShader") ||
split[0].equals("FragmentShader") || split[0].equals("FragmentShader") ||
split[0].equals("GeometryShader") || split[0].equals("GeometryShader") ||
@ -433,12 +433,12 @@ public class J3MLoader implements AssetLoader {
readShadowMode(statement.getLine()); readShadowMode(statement.getLine());
}else if (split[0].equals("WorldParameters")){ }else if (split[0].equals("WorldParameters")){
readWorldParams(statement.getContents()); readWorldParams(statement.getContents());
}else if (split[0].equals("RenderState")){ }else if (split[0].equals("RenderState")){
readRenderState(statement.getContents()); readRenderState(statement.getContents());
}else if (split[0].equals("ForcedRenderState")){ }else if (split[0].equals("ForcedRenderState")){
readForcedRenderState(statement.getContents()); readForcedRenderState(statement.getContents());
}else if (split[0].equals("Defines")){ }else if (split[0].equals("Defines")){
readDefines(statement.getContents()); readDefines(statement.getContents());
} else if (split[0].equals("ShaderNodesDefinitions")) { } else if (split[0].equals("ShaderNodesDefinitions")) {
initNodesLoader(); initNodesLoader();
if (isUseNodes) { if (isUseNodes) {
@ -451,14 +451,16 @@ public class J3MLoader implements AssetLoader {
} }
} else if (split[0].equals("FragmentShaderNodes")) { } else if (split[0].equals("FragmentShaderNodes")) {
initNodesLoader(); initNodesLoader();
if (isUseNodes) { if (isUseNodes) {
nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents()); nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents());
} }
} else if (split[0].equals("NoRender")) {
technique.setNoRender(true);
} else { } else {
throw new MatParseException(null, split[0], statement); throw new MatParseException(null, split[0], statement);
} }
} }
private void readTransparentStatement(String statement) throws IOException{ private void readTransparentStatement(String statement) throws IOException{
String[] split = statement.split(whitespacePattern); String[] split = statement.split(whitespacePattern);
if (split.length != 2){ if (split.length != 2){
@ -478,11 +480,11 @@ public class J3MLoader implements AssetLoader {
} else { } else {
throw new IOException("Technique statement syntax incorrect"); throw new IOException("Technique statement syntax incorrect");
} }
for (Statement statement : techStat.getContents()){ for (Statement statement : techStat.getContents()){
readTechniqueStatement(statement); readTechniqueStatement(statement);
} }
if(isUseNodes){ if(isUseNodes){
nodesLoaderDelegate.computeConditions(); nodesLoaderDelegate.computeConditions();
//used for caching later, the shader here is not a file. //used for caching later, the shader here is not a file.
@ -492,14 +494,14 @@ public class J3MLoader implements AssetLoader {
if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) { if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) {
technique.setShaderFile(shaderName, shaderLanguage); technique.setShaderFile(shaderName, shaderLanguage);
} }
materialDef.addTechniqueDef(technique); materialDef.addTechniqueDef(technique);
technique = null; technique = null;
shaderLanguage.clear(); shaderLanguage.clear();
shaderName.clear(); shaderName.clear();
} }
private void loadFromRoot(List<Statement> roots) throws IOException{ private void loadFromRoot(List<Statement> roots) throws IOException{
if (roots.size() == 2){ if (roots.size() == 2){
Statement exception = roots.get(0); Statement exception = roots.get(0);
String line = exception.getLine(); String line = exception.getLine();
@ -511,7 +513,7 @@ public class J3MLoader implements AssetLoader {
}else if (roots.size() != 1){ }else if (roots.size() != 1){
throw new IOException("Too many roots in J3M/J3MD file"); throw new IOException("Too many roots in J3M/J3MD file");
} }
boolean extending = false; boolean extending = false;
Statement materialStat = roots.get(0); Statement materialStat = roots.get(0);
String materialName = materialStat.getLine(); String materialName = materialStat.getLine();
@ -524,16 +526,16 @@ public class J3MLoader implements AssetLoader {
}else{ }else{
throw new IOException("Specified file is not a Material file"); throw new IOException("Specified file is not a Material file");
} }
String[] split = materialName.split(":", 2); String[] split = materialName.split(":", 2);
if (materialName.equals("")){ if (materialName.equals("")){
throw new MatParseException("Material name cannot be empty", materialStat); throw new MatParseException("Material name cannot be empty", materialStat);
} }
if (split.length == 2){ if (split.length == 2){
if (!extending){ if (!extending){
throw new MatParseException("Must use 'Material' when extending.", materialStat); throw new MatParseException("Must use 'Material' when extending.", materialStat);
} }
String extendedMat = split[1].trim(); String extendedMat = split[1].trim();
@ -548,15 +550,15 @@ public class J3MLoader implements AssetLoader {
// material.setAssetName(fileName); // material.setAssetName(fileName);
}else if (split.length == 1){ }else if (split.length == 1){
if (extending){ if (extending){
throw new MatParseException("Expected ':', got '{'", materialStat); throw new MatParseException("Expected ':', got '{'", materialStat);
} }
materialDef = new MaterialDef(assetManager, materialName); materialDef = new MaterialDef(assetManager, materialName);
// NOTE: pass file name for defs so they can be loaded later // NOTE: pass file name for defs so they can be loaded later
materialDef.setAssetName(key.getName()); materialDef.setAssetName(key.getName());
}else{ }else{
throw new MatParseException("Cannot use colon in material name/path", materialStat); throw new MatParseException("Cannot use colon in material name/path", materialStat);
} }
for (Statement statement : materialStat.getContents()){ for (Statement statement : materialStat.getContents()){
split = statement.getLine().split("[ \\{]"); split = statement.getLine().split("[ \\{]");
String statType = split[0]; String statType = split[0];
@ -574,16 +576,16 @@ public class J3MLoader implements AssetLoader {
}else if (statType.equals("MaterialParameters")){ }else if (statType.equals("MaterialParameters")){
readMaterialParams(statement.getContents()); readMaterialParams(statement.getContents());
}else{ }else{
throw new MatParseException("Expected material statement, got '"+statType+"'", statement); throw new MatParseException("Expected material statement, got '"+statType+"'", statement);
} }
} }
} }
} }
public Object load(AssetInfo info) throws IOException { public Object load(AssetInfo info) throws IOException {
this.assetManager = info.getManager(); this.assetManager = info.getManager();
InputStream in = info.openStream(); InputStream in = info.openStream();
try { try {
key = info.getKey(); key = info.getKey();
if (key.getExtension().equals("j3m") && !(key instanceof MaterialKey)) { if (key.getExtension().equals("j3m") && !(key instanceof MaterialKey)) {
@ -597,7 +599,7 @@ public class J3MLoader implements AssetLoader {
in.close(); in.close();
} }
} }
if (material != null){ if (material != null){
// material implementation // material implementation
return material; return material;
@ -606,7 +608,7 @@ public class J3MLoader implements AssetLoader {
return materialDef; return materialDef;
} }
} }
public MaterialDef loadMaterialDef(List<Statement> roots, AssetManager manager, AssetKey key) throws IOException { public MaterialDef loadMaterialDef(List<Statement> roots, AssetManager manager, AssetKey key) throws IOException {
this.key = key; this.key = key;
this.assetManager = manager; this.assetManager = manager;
@ -628,6 +630,6 @@ public class J3MLoader implements AssetLoader {
nodesLoaderDelegate.setAssetManager(assetManager); nodesLoaderDelegate.setAssetManager(assetManager);
} }
} }
} }
} }

Loading…
Cancel
Save