diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java index 8197a62a8..c2882b954 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java @@ -41,8 +41,8 @@ import java.util.logging.Logger; import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.material.MatParam; +import com.jme3.material.MatParamTexture; import com.jme3.material.Material; -import com.jme3.material.Material.MatParamTexture; import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.FaceCullMode; import com.jme3.math.ColorRGBA; diff --git a/engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java b/engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java deleted file mode 100644 index a1b370c43..000000000 --- a/engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2009-2010 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.jme3.export.binary; - -import java.io.IOException; -import java.util.logging.Logger; - -import com.jme3.export.InputCapsule; -import com.jme3.export.Savable; -import java.util.Iterator; -import java.util.List; - -/** - * This class is mis-named and is located in an inappropriate package: - * It is not binary-specific (it is in fact used for XML format too), and it - * is not a java.lang.ClassLoader, which is what "class loader" is for Java - * developers. - * - * @author mpowell - */ -public class BinaryClassLoader { - - /** - * fromName creates a new Savable from the provided class name. First registered modules - * are checked to handle special cases, if the modules do not handle the class name, the - * class is instantiated directly. - * @param className the class name to create. - * @param inputCapsule the InputCapsule that will be used for loading the Savable (to look up ctor parameters) - * @return the Savable instance of the class. - * @throws InstantiationException thrown if the class does not have an empty constructor. - * @throws IllegalAccessException thrown if the class is not accessable. - * @throws ClassNotFoundException thrown if the class name is not in the classpath. - * @throws IOException when loading ctor parameters fails - */ - public static Savable fromName(String className, InputCapsule inputCapsule) throws InstantiationException, - IllegalAccessException, ClassNotFoundException, IOException { - - try { - return (Savable)Class.forName(className).newInstance(); - } - catch (InstantiationException e) { - Logger.getLogger(BinaryClassLoader.class.getName()).severe( - "Could not access constructor of class '" + className + "'! \n" + - "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup."); - throw e; - } - catch (IllegalAccessException e) { - Logger.getLogger(BinaryClassLoader.class.getName()).severe( - e.getMessage() + " \n" + - "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup."); - throw e; - } - } - - public static Savable fromName(String className, InputCapsule inputCapsule, List loaders) throws InstantiationException, - IllegalAccessException, ClassNotFoundException, IOException { - if(loaders == null){ - return fromName(className, inputCapsule); - } - for (Iterator it = loaders.iterator(); it.hasNext();) { - ClassLoader classLoader = it.next(); - try { - return (Savable)classLoader.loadClass(className).newInstance(); - } - catch (InstantiationException e) { - } - catch (IllegalAccessException e) { - } - - } - - try { - return (Savable)Class.forName(className).newInstance(); - } - catch (InstantiationException e) { - Logger.getLogger(BinaryClassLoader.class.getName()).severe( - "Could not access constructor of class '" + className + "'! \n" + - "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup."); - throw e; - } - catch (IllegalAccessException e) { - Logger.getLogger(BinaryClassLoader.class.getName()).severe( - e.getMessage() + " \n" + - "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup."); - throw e; - } - } -} diff --git a/engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java b/engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java index 55a00afd0..153e34fb8 100644 --- a/engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java +++ b/engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java @@ -32,6 +32,7 @@ package com.jme3.export.binary; +import com.jme3.export.SavableClassFinder; import com.jme3.asset.AssetInfo; import com.jme3.asset.AssetManager; import com.jme3.asset.ModelKey; @@ -294,7 +295,7 @@ public final class BinaryImporter implements JmeImporter { BinaryInputCapsule cap = new BinaryInputCapsule(this, bco); cap.setContent(dataArray, loc, loc+dataLength); - Savable out = BinaryClassLoader.fromName(bco.className, cap, loaders); + Savable out = SavableClassFinder.fromName(bco.className, cap, loaders); capsuleTable.put(out, cap); contentTable.put(id, out); diff --git a/engine/src/core/com/jme3/effect/ParticleEmitter.java b/engine/src/core/com/jme3/effect/ParticleEmitter.java index 4d494cd84..1166fffde 100644 --- a/engine/src/core/com/jme3/effect/ParticleEmitter.java +++ b/engine/src/core/com/jme3/effect/ParticleEmitter.java @@ -1119,5 +1119,24 @@ public class ParticleEmitter extends Geometry { particleMesh.initParticleData(this, particles.length); particleInfluencer = (ParticleInfluencer) ic.readSavable("influencer", DEFAULT_INFLUENCER); + + // compatibility before the control inside particle emitter + // was changed: + // find it in the controls and take it out, then add the proper one in + for (int i = 0; i < controls.size(); i++){ + Object obj = controls.get(i); + if (obj instanceof ParticleEmitter){ + controls.remove(i); + // now add the proper one in + controls.add(control); + break; + } + } + + // compatability before gravity was not a vector but a float + if (gravity == null){ + gravity = new Vector3f(); + gravity.y = ic.readFloat("gravity", 0); + } } } diff --git a/engine/src/core/com/jme3/export/SavableClassFinder.java b/engine/src/core/com/jme3/export/SavableClassFinder.java new file mode 100644 index 000000000..3bbe945f8 --- /dev/null +++ b/engine/src/core/com/jme3/export/SavableClassFinder.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009-2010 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.export; + +import com.jme3.effect.shapes.EmitterBoxShape; +import com.jme3.effect.shapes.EmitterMeshConvexHullShape; +import com.jme3.effect.shapes.EmitterMeshFaceShape; +import com.jme3.effect.shapes.EmitterMeshVertexShape; +import com.jme3.effect.shapes.EmitterPointShape; +import com.jme3.effect.shapes.EmitterSphereShape; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.export.InputCapsule; +import com.jme3.export.Savable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +/** + * SavableClassFinder is used to find classes referenced + * by savables. + * Currently it will remap any classes from old paths to new paths + * so that old J3O models can still be loaded. + * + * @author mpowell + * @author Kirill Vainer + */ +public class SavableClassFinder { + + private final static HashMap classRemappings = new HashMap(); + + private static void addRemapping(String oldClass, Class newClass){ + classRemappings.put(oldClass, newClass.getName()); + } + + static { + addRemapping("com.jme3.effect.EmitterSphereShape", EmitterSphereShape.class); + addRemapping("com.jme3.effect.EmitterBoxShape", EmitterBoxShape.class); + addRemapping("com.jme3.effect.EmitterMeshConvexHullShape", EmitterMeshConvexHullShape.class); + addRemapping("com.jme3.effect.EmitterMeshFaceShape", EmitterMeshFaceShape.class); + addRemapping("com.jme3.effect.EmitterMeshVertexShape", EmitterMeshVertexShape.class); + addRemapping("com.jme3.effect.EmitterPointShape", EmitterPointShape.class); + } + + private static String remapClass(String className) throws ClassNotFoundException { + String result = classRemappings.get(className); + if (result == null) { + return className; + } else { + return result; + } + } + + /** + * fromName creates a new Savable from the provided class name. First registered modules + * are checked to handle special cases, if the modules do not handle the class name, the + * class is instantiated directly. + * @param className the class name to create. + * @param inputCapsule the InputCapsule that will be used for loading the Savable (to look up ctor parameters) + * @return the Savable instance of the class. + * @throws InstantiationException thrown if the class does not have an empty constructor. + * @throws IllegalAccessException thrown if the class is not accessable. + * @throws ClassNotFoundException thrown if the class name is not in the classpath. + * @throws IOException when loading ctor parameters fails + */ + public static Savable fromName(String className, InputCapsule inputCapsule) throws InstantiationException, + IllegalAccessException, ClassNotFoundException, IOException { + + className = remapClass(className); + try { + return (Savable) Class.forName(className).newInstance(); + } catch (InstantiationException e) { + Logger.getLogger(SavableClassFinder.class.getName()).log( + Level.SEVERE, "Could not access constructor of class ''{0}" + "''! \n" + + "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup.", className); + throw e; + } catch (IllegalAccessException e) { + Logger.getLogger(SavableClassFinder.class.getName()).log( + Level.SEVERE, "{0} \n" + + "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup.", e.getMessage()); + throw e; + } + } + + public static Savable fromName(String className, InputCapsule inputCapsule, List loaders) throws InstantiationException, + IllegalAccessException, ClassNotFoundException, IOException { + if (loaders == null) { + return fromName(className, inputCapsule); + } + + String newClassName = remapClass(className); + for (ClassLoader classLoader : loaders){ + try { + return (Savable) classLoader.loadClass(newClassName).newInstance(); + } catch (InstantiationException e) { + } catch (IllegalAccessException e) { + } + + } + + return fromName(className, inputCapsule); + } +} diff --git a/engine/src/core/com/jme3/input/InputManager.java b/engine/src/core/com/jme3/input/InputManager.java index 5e437ec21..7df18a99e 100644 --- a/engine/src/core/com/jme3/input/InputManager.java +++ b/engine/src/core/com/jme3/input/InputManager.java @@ -446,28 +446,6 @@ public class InputManager implements RawInputListener { inputQueue.add(evt); } - - private void onTouchEventQueued(TouchEvent evt) { - for (Mapping mapping : mappings.values()) { - for (InputListener listener : mapping.listeners) { - if (listener instanceof TouchListener) { - ((TouchListener) listener).onTouch(mapping.name, evt, frameTPF); - } - } - } - } - - /** - * Callback from RawInputListener. Do not use. - */ - @Override - public void onTouchEvent(TouchEvent evt) { - if (!eventsPermitted) { - throw new UnsupportedOperationException("TouchInput has raised an event at an illegal time."); - } - - inputQueue.add(evt); - } /** * Set the deadzone for joystick axes. @@ -560,7 +538,7 @@ public class InputManager implements RawInputListener { } for (Trigger trigger : triggers) { - int hash = trigger.hashCode(); + int hash = trigger.triggerHashCode(); ArrayList names = bindings.get(hash); if (names == null) { names = new ArrayList(); @@ -617,7 +595,7 @@ public class InputManager implements RawInputListener { throw new IllegalArgumentException("Cannot find mapping: " + mappingName); } - ArrayList maps = bindings.get(trigger.hashCode()); + ArrayList maps = bindings.get(trigger.triggerHashCode()); maps.remove(mapping); } @@ -868,7 +846,7 @@ public class InputManager implements RawInputListener { * @param evt The touch event to be dispatched to all onTouch listeners */ public void onTouchEventQueued(TouchEvent evt) { - ArrayList maps = bindings.get(TouchTrigger.getHash()); + ArrayList maps = bindings.get(TouchTrigger.touchHash()); if (maps == null) { return; } @@ -888,8 +866,7 @@ public class InputManager implements RawInputListener { } /** - * Receives the touch events from the touch hardware via the input interface - * @param evt The touch Event received + * Callback from RawInputListener. Do not use. */ @Override public void onTouchEvent(TouchEvent evt) { diff --git a/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java b/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java index d67de680e..539d83e0e 100644 --- a/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java +++ b/engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java @@ -69,5 +69,9 @@ public class JoyAxisTrigger implements Trigger { public String getName() { return "JoyAxis[joyId="+joyId+", axisId="+axisId+", neg="+negative+"]"; } + + public int triggerHashCode() { + return joyAxisHash(joyId, axisId, negative); + } } diff --git a/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java b/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java index d6b8b4328..5e2cfd618 100644 --- a/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java +++ b/engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java @@ -66,4 +66,8 @@ public class JoyButtonTrigger implements Trigger { return "JoyButton[joyId="+joyId+", axisId="+buttonId+"]"; } + public int triggerHashCode() { + return joyButtonHash(joyId, buttonId); + } + } diff --git a/engine/src/core/com/jme3/input/controls/KeyTrigger.java b/engine/src/core/com/jme3/input/controls/KeyTrigger.java index 03f6d3244..993b4e7f8 100644 --- a/engine/src/core/com/jme3/input/controls/KeyTrigger.java +++ b/engine/src/core/com/jme3/input/controls/KeyTrigger.java @@ -65,4 +65,8 @@ public class KeyTrigger implements Trigger { return keyCode & 0xff; } + public int triggerHashCode() { + return keyHash(keyCode); + } + } diff --git a/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java b/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java index f13d0a37f..49de745a1 100644 --- a/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java +++ b/engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java @@ -83,4 +83,8 @@ public class MouseAxisTrigger implements Trigger { assert mouseAxis >= 0 && mouseAxis <= 255; return (negative ? 768 : 512) | (mouseAxis & 0xff); } + + public int triggerHashCode() { + return mouseAxisHash(mouseAxis, negative); + } } diff --git a/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java b/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java index fb9483660..303a54e03 100644 --- a/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java +++ b/engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java @@ -70,8 +70,7 @@ public class MouseButtonTrigger implements Trigger { return 256 | (mouseButton & 0xff); } - @Override - public int hashCode(){ + public int triggerHashCode() { return mouseButtonHash(mouseButton); } diff --git a/engine/src/core/com/jme3/input/controls/TouchTrigger.java b/engine/src/core/com/jme3/input/controls/TouchTrigger.java index 21ebf0ac2..a68299289 100644 --- a/engine/src/core/com/jme3/input/controls/TouchTrigger.java +++ b/engine/src/core/com/jme3/input/controls/TouchTrigger.java @@ -38,17 +38,16 @@ public class TouchTrigger implements Trigger { super(); } - @Override - public int hashCode(){ - return getHash(); - } - @Override public String getName() { return "TouchInput"; } - public static int getHash() { + public static int touchHash(){ return 0xfedcba98; } + + public int triggerHashCode() { + return touchHash(); + } } diff --git a/engine/src/core/com/jme3/input/controls/Trigger.java b/engine/src/core/com/jme3/input/controls/Trigger.java index 0eea7835b..9f059e890 100644 --- a/engine/src/core/com/jme3/input/controls/Trigger.java +++ b/engine/src/core/com/jme3/input/controls/Trigger.java @@ -42,4 +42,11 @@ public interface Trigger { * @return A user friendly name for the trigger. */ public String getName(); + + /** + * Returns the hash code for the trigger. + * + * @return the hash code for the trigger. + */ + public int triggerHashCode(); } diff --git a/engine/src/core/com/jme3/material/FixedFuncBinding.java b/engine/src/core/com/jme3/material/FixedFuncBinding.java index c1c13865a..d13f74c26 100644 --- a/engine/src/core/com/jme3/material/FixedFuncBinding.java +++ b/engine/src/core/com/jme3/material/FixedFuncBinding.java @@ -32,9 +32,42 @@ package com.jme3.material; +/** + * Fixed function binding is used to specify a binding for a {@link MatParam} + * in case that shaders are not supported on the system. + * + * @author Kirill Vainer + */ public enum FixedFuncBinding { + /** + * Specifies the material ambient color. + * Same as GL_AMBIENT for OpenGL. + */ MaterialAmbient, + + /** + * Specifies the material diffuse color. + * Same as GL_DIFFUSE for OpenGL. + */ MaterialDiffuse, + + /** + * Specifies the material specular color. + * Same as GL_SPECULAR for OpenGL + */ MaterialSpecular, + + /** + * Specifies the color of the object. + *

+ * Used only for non-lit materials. + */ Color, + + /** + * Specifies the material shininess value. + * + * Same as GL_SHININESS for OpenGL. + */ + Shininess } diff --git a/engine/src/core/com/jme3/material/MatParam.java b/engine/src/core/com/jme3/material/MatParam.java index 7129c5486..46cc0a293 100644 --- a/engine/src/core/com/jme3/material/MatParam.java +++ b/engine/src/core/com/jme3/material/MatParam.java @@ -50,6 +50,12 @@ import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; import java.io.IOException; +/** + * Describes a material parameter. This is used for both defining a name and type + * as well as a material parameter value. + * + * @author Kirill Vainer + */ public class MatParam implements Savable, Cloneable { protected VarType type; @@ -57,6 +63,9 @@ public class MatParam implements Savable, Cloneable { protected Object value; protected FixedFuncBinding ffBinding; + /** + * Create a new material parameter. For internal use only. + */ public MatParam(VarType type, String name, Object value, FixedFuncBinding ffBinding){ this.type = type; this.name = name; @@ -64,33 +73,80 @@ public class MatParam implements Savable, Cloneable { this.ffBinding = ffBinding; } + /** + * Serialization only. Do not use. + */ public MatParam(){ } + /** + * Returns the fixed function binding. + * + * @return the fixed function binding. + */ public FixedFuncBinding getFixedFuncBinding() { return ffBinding; } + /** + * Returns the material parameter type. + * + * @return the material parameter type. + */ public VarType getVarType() { return type; } + /** + * Returns the name of the material parameter. + * @return the name of the material parameter. + */ public String getName(){ return name; } - public void setName(String name){ - this.name=name; + /** + * Used internally + * @param name + */ + void setName(String name) { + this.name = name; } + /** + * Returns the value of this material parameter. + *

+ * Material parameters that are used for material definitions + * will not have a value. + * + * @return the value of this material parameter. + */ public Object getValue(){ return value; } + /** + * Sets the value of this material parameter. + *

+ * It is assumed the value is of the same {@link MatParam#getVarType() type} + * as this material parameter. + * + * @param value the value of this material parameter. + */ public void setValue(Object value){ this.value = value; } + void apply(Renderer r, Technique technique) { + TechniqueDef techDef = technique.getDef(); + if (techDef.isUsingShaders()) { + technique.updateUniformParam(getName(), getVarType(), getValue(), true); + } + if (ffBinding != null && r instanceof GL1Renderer){ + ((GL1Renderer)r).setFixedFuncBinding(ffBinding, getValue()); + } + } + /** * Returns the material parameter value as it would appear in a J3M * file. E.g.
@@ -225,15 +281,5 @@ public class MatParam implements Savable, Cloneable { public String toString(){ return type.name() + " " + name + " : " + getValueAsString(); } - - public void apply(Renderer r, Technique technique) { - TechniqueDef techDef = technique.getDef(); - if (techDef.isUsingShaders()) { - technique.updateUniformParam(getName(), getVarType(), getValue(), true); - } - if (ffBinding != null && r instanceof GL1Renderer){ - ((GL1Renderer)r).setFixedFuncBinding(ffBinding, getValue()); - } - } } diff --git a/engine/src/core/com/jme3/material/MaterialDef.java b/engine/src/core/com/jme3/material/MaterialDef.java index 6f9c99afb..c13236480 100644 --- a/engine/src/core/com/jme3/material/MaterialDef.java +++ b/engine/src/core/com/jme3/material/MaterialDef.java @@ -41,6 +41,11 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +/** + * Describes a J3MD (Material definition). + * + * @author Kirill Vainer + */ public class MaterialDef { private static final Logger logger = Logger.getLogger(MaterialDef.class.getName()); @@ -53,9 +58,18 @@ public class MaterialDef { private Map techniques; private Map matParams; + /** + * Serialization only. Do not use. + */ public MaterialDef(){ } + /** + * Creates a new material definition with the given name. + * + * @param assetManager The asset manager to use to load shaders + * @param name The debug name of the material definition + */ public MaterialDef(AssetManager assetManager, String name){ this.assetManager = assetManager; this.name = name; @@ -65,30 +79,74 @@ public class MaterialDef { logger.log(Level.INFO, "Loaded material definition: {0}", name); } + /** + * Returns the asset key name of the asset from which this material + * definition was loaded. + * + * @return Asset key name of the j3md file + */ public String getAssetName() { return assetName; } + /** + * Set the asset key name. + * + * @param assetName the asset key name + */ public void setAssetName(String assetName) { this.assetName = assetName; } + /** + * Returns the AssetManager passed in the constructor. + * + * @return the AssetManager passed in the constructor. + */ public AssetManager getAssetManager(){ return assetManager; } + /** + * The debug name of the material definition. + * + * @return debug name of the material definition. + */ public String getName(){ return name; } + /** + * Adds a new material parameter. + * + * @param type Type of the parameter + * @param name Name of the parameter + * @param value Default value of the parameter + * @param ffBinding Fixed function binding for the parameter + */ public void addMaterialParam(VarType type, String name, Object value, FixedFuncBinding ffBinding) { matParams.put(name, new MatParam(type, name, value, ffBinding)); } + /** + * Returns the material parameter with the given name. + * + * @param name The name of the parameter to retrieve + * + * @return The material parameter, or null if it does not exist. + */ public MatParam getMaterialParam(String name){ return matParams.get(name); } + /** + * Adds a new technique definition to this material definition. + *

+ * If the technique name is "Default", it will be added + * to the list of {@link MaterialDef#getDefaultTechniques() default techniques}. + * + * @param technique The technique definition to add. + */ public void addTechniqueDef(TechniqueDef technique){ if (technique.getName().equals("Default")){ defaultTechs.add(technique); @@ -97,10 +155,24 @@ public class MaterialDef { } } + /** + * Returns a list of all default techniques. + * + * @return a list of all default techniques. + */ public List getDefaultTechniques(){ return defaultTechs; } + /** + * Returns a technique definition with the given name. + * This does not include default techniques which can be + * retrieved via {@link MaterialDef#getDefaultTechniques() }. + * + * @param name The name of the technique definition to find + * + * @return The technique definition, or null if cannot be found. + */ public TechniqueDef getTechniqueDef(String name) { return techniques.get(name); } diff --git a/engine/src/core/com/jme3/material/MaterialList.java b/engine/src/core/com/jme3/material/MaterialList.java index e40bd29c6..9f2a512c8 100644 --- a/engine/src/core/com/jme3/material/MaterialList.java +++ b/engine/src/core/com/jme3/material/MaterialList.java @@ -34,5 +34,11 @@ package com.jme3.material; import java.util.HashMap; +/** + * A map from material name to a material. Used by loaders to locate + * materials for meshes inside a model. + * + * @author Kirill Vainer + */ public class MaterialList extends HashMap { } diff --git a/engine/src/core/com/jme3/material/RenderState.java b/engine/src/core/com/jme3/material/RenderState.java index 15eff49f5..512e946d9 100644 --- a/engine/src/core/com/jme3/material/RenderState.java +++ b/engine/src/core/com/jme3/material/RenderState.java @@ -37,6 +37,7 @@ import com.jme3.export.InputCapsule; import com.jme3.export.OutputCapsule; import com.jme3.export.Savable; import com.jme3.scene.Mesh; +import com.jme3.scene.Mesh.Mode; import java.io.IOException; /** @@ -392,7 +393,7 @@ public class RenderState implements Cloneable, Savable { * Enables point sprite mode. * *

When point sprite is enabled, any meshes - * with the type of {@link Mesh#Mode#Points} will be rendered as 2D quads + * with the type of {@link Mode#Points} will be rendered as 2D quads * with texturing enabled. Fragment shaders can write to the * gl_PointCoord variable to manipulate the texture coordinate * for each pixel. The size of the 2D quad can be controlled by writing @@ -413,7 +414,7 @@ public class RenderState implements Cloneable, Savable { * the pixel will be discarded. * * @param alphaFallOff The alpha of all rendered pixels must be higher - * than this value to be rendered. + * than this value to be rendered. This value should be between 0 and 1. * * @see RenderState#setAlphaTest(boolean) */ @@ -426,8 +427,9 @@ public class RenderState implements Cloneable, Savable { * Enable alpha testing. * *

When alpha testing is enabled, all input pixels' alpha are compared - * to the constant alpha falloff. If the input alpha is greater than - * the falloff, the pixel will be rendered, otherwise it will be discarded. + * to the {@link RenderState#setAlphaFallOff(float) constant alpha falloff}. + * If the input alpha is greater than the falloff, the pixel will be rendered, + * otherwise it will be discarded. * * @param alphaTest Set to true to enable alpha testing. * @@ -472,7 +474,7 @@ public class RenderState implements Cloneable, Savable { /** * Set the blending mode. * - *

When blending is enabled, (blendMode is not BlendMode.Off) + *

When blending is enabled, (blendMode is not {@link BlendMode#Off}) * the input pixel will be blended with the pixel * already in the color buffer. The blending operation is determined * by the {@link BlendMode}. For example, the {@link BlendMode#Additive} diff --git a/engine/src/core/com/jme3/material/Technique.java b/engine/src/core/com/jme3/material/Technique.java index 628497600..51ea4ca56 100644 --- a/engine/src/core/com/jme3/material/Technique.java +++ b/engine/src/core/com/jme3/material/Technique.java @@ -62,6 +62,13 @@ public class Technique implements Savable { private Shader shader; private boolean needReload = true; + /** + * Creates a new technique instance that implements the given + * technique definition. + * + * @param owner The material that will own this technique + * @param def The technique definition being implemented. + */ public Technique(Material owner, TechniqueDef def) { this.owner = owner; this.def = def; @@ -71,45 +78,49 @@ public class Technique implements Savable { } } + /** + * Serialization only. Do not use. + */ public Technique() { } - public void write(JmeExporter ex) throws IOException { - OutputCapsule oc = ex.getCapsule(this); - oc.write(def, "def", null); - // TODO: - // oc.write(owner, "owner", null); - oc.writeSavableArrayList(worldBindUniforms, "worldBindUniforms", null); - oc.write(defines, "defines", null); - oc.write(shader, "shader", null); - } - - public void read(JmeImporter im) throws IOException { - InputCapsule ic = im.getCapsule(this); - def = (TechniqueDef) ic.readSavable("def", null); - worldBindUniforms = ic.readSavableArrayList("worldBindUniforms", null); - defines = (DefineList) ic.readSavable("defines", null); - shader = (Shader) ic.readSavable("shader", null); - //if (shader != null) - // owner.updateUniformLinks(); - } - + /** + * Returns the technique definition that is implemented by this technique + * instance. + * + * @return the technique definition that is implemented by this technique + * instance. + */ public TechniqueDef getDef() { return def; } + /** + * Returns the shader currently used by this technique instance. + *

+ * Shaders are typically loaded dynamically when the technique is first + * used, therefore, this variable will most likely be null most of the time. + * + * @return the shader currently used by this technique instance. + */ public Shader getShader() { return shader; } + /** + * Returns a list of uniforms that implements the world parameters + * that were requested by the material definition. + * + * @return a list of uniforms implementing the world parameters. + */ public List getWorldBindUniforms() { return worldBindUniforms; } /** - * @param paramName + * Called by the material to tell the technique a parameter was modified */ - public void notifySetParam(String paramName, VarType type, Object value) { + void notifySetParam(String paramName, VarType type, Object value) { String defineName = def.getShaderParamDefine(paramName); if (defineName != null) { defines.set(defineName, type, value); @@ -121,9 +132,9 @@ public class Technique implements Savable { } /** - * @param paramName + * Called by the material to tell the technique a parameter was cleared */ - public void notifyClearParam(String paramName) { + void notifyClearParam(String paramName) { String defineName = def.getShaderParamDefine(paramName); if (defineName != null) { defines.remove(defineName); @@ -229,4 +240,24 @@ public class Technique implements Savable { needReload = false; } + + public void write(JmeExporter ex) throws IOException { + OutputCapsule oc = ex.getCapsule(this); + oc.write(def, "def", null); + // TODO: + // oc.write(owner, "owner", null); + oc.writeSavableArrayList(worldBindUniforms, "worldBindUniforms", null); + oc.write(defines, "defines", null); + oc.write(shader, "shader", null); + } + + public void read(JmeImporter im) throws IOException { + InputCapsule ic = im.getCapsule(this); + def = (TechniqueDef) ic.readSavable("def", null); + worldBindUniforms = ic.readSavableArrayList("worldBindUniforms", null); + defines = (DefineList) ic.readSavable("defines", null); + shader = (Shader) ic.readSavable("shader", null); + //if (shader != null) + // owner.updateUniformLinks(); + } } diff --git a/engine/src/core/com/jme3/material/package.html b/engine/src/core/com/jme3/material/package.html new file mode 100644 index 000000000..adfb66a33 --- /dev/null +++ b/engine/src/core/com/jme3/material/package.html @@ -0,0 +1,58 @@ + + + + + + + + + +The com.jme3.material package contains classes for manipulating +jMonkeyEngine materials. +Materials are applied to {@link com.jme3.scene.Geoemtry geometries} in the +scene. +Each geometry has a single material which is used to render that +geometry. +

+Materials (also known as material instances) are extended from +material definitions. + +

Material definitions

+

+Material definitions provide the "logic" for the material. Usually a shader that +will handle drawing the object, and corresponding parameters that allow +configuration of the shader. +Material definitions can be created through J3MD files. +The J3MD file abstracts the shader and its configuration away from the user, allowing a +simple interface where one can simply set a few parameters on the material to change its +appearance and the way its handled. + +

Techniques

+

+Techniques specify a specific way of rendering a material. Typically +a technique is used to implement the same material for each configuration +of the system. For GPUs that do not support shaders, a "fixed function pipeline" +technique could exist to take care of rendering for that configuration + +

Render states

+

+See {@link com.jme3.material.RenderState}. + +

Example Usage

+

+Creating a textured material + +// Create a material instance +Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + +// Load the texture. +Texture tex = assetManager.loadTexture("Textures/Test/Test.jpg"); + +// Set the parameters +mat.setTexture("ColorMap", tex); + + + + + + diff --git a/engine/src/core/com/jme3/scene/Spatial.java b/engine/src/core/com/jme3/scene/Spatial.java index 2c3b122cf..75189ef06 100644 --- a/engine/src/core/com/jme3/scene/Spatial.java +++ b/engine/src/core/com/jme3/scene/Spatial.java @@ -1247,7 +1247,7 @@ public abstract class Spatial implements Savable, Cloneable, Collidable { //When backward compatibility won't be needed anymore this can be replaced by : //controls = ic.readSavableArrayList("controlsList", null)); controls.addAll(0, ic.readSavableArrayList("controlsList", null)); - + userData = (HashMap) ic.readStringSavableMap("user_data", null); } diff --git a/engine/src/core/com/jme3/scene/control/AbstractControl.java b/engine/src/core/com/jme3/scene/control/AbstractControl.java index 25865a5cc..0eade13b2 100644 --- a/engine/src/core/com/jme3/scene/control/AbstractControl.java +++ b/engine/src/core/com/jme3/scene/control/AbstractControl.java @@ -55,6 +55,9 @@ public abstract class AbstractControl implements Control { } public void setSpatial(Spatial spatial) { + if (this.spatial != null && spatial != null) { + throw new IllegalStateException("This control has already been added to a Spatial"); + } this.spatial = spatial; } diff --git a/engine/src/test/jme3test/bullet/BombControl.java b/engine/src/test/jme3test/bullet/BombControl.java index 4bad9f03a..4438382b4 100644 --- a/engine/src/test/jme3test/bullet/BombControl.java +++ b/engine/src/test/jme3test/bullet/BombControl.java @@ -72,7 +72,7 @@ public class BombControl extends RigidBodyControl implements PhysicsCollisionLis effect.setEndSize(2f); effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); effect.setParticlesPerSec(0); - effect.setGravity(-5f); + effect.setGravity(0, -5f, 0); effect.setLowLife(.4f); effect.setHighLife(.5f); effect.setInitialVelocity(new Vector3f(0, 7, 0)); diff --git a/engine/src/test/jme3test/bullet/TestWalkingChar.java b/engine/src/test/jme3test/bullet/TestWalkingChar.java index af1a554d0..94d370ec7 100644 --- a/engine/src/test/jme3test/bullet/TestWalkingChar.java +++ b/engine/src/test/jme3test/bullet/TestWalkingChar.java @@ -219,7 +219,7 @@ public class TestWalkingChar extends SimpleApplication implements ActionListener effect.setEndSize(2f); effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); effect.setParticlesPerSec(0); - effect.setGravity(-5f); + effect.setGravity(0, -5, 0); effect.setLowLife(.4f); effect.setHighLife(.5f); effect.setInitialVelocity(new Vector3f(0, 7, 0)); diff --git a/engine/src/test/jme3test/effect/TestExplosionEffect.java b/engine/src/test/jme3test/effect/TestExplosionEffect.java index 31c8c0907..e9aae6c7d 100644 --- a/engine/src/test/jme3test/effect/TestExplosionEffect.java +++ b/engine/src/test/jme3test/effect/TestExplosionEffect.java @@ -72,7 +72,7 @@ public class TestExplosionEffect extends SimpleApplication { flame.setEndSize(2f); flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); flame.setParticlesPerSec(0); - flame.setGravity(-5f); + flame.setGravity(0, -5, 0); flame.setLowLife(.4f); flame.setHighLife(.5f); flame.setInitialVelocity(new Vector3f(0, 7, 0)); @@ -95,7 +95,7 @@ public class TestExplosionEffect extends SimpleApplication { flash.setEndSize(3.0f); flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); flash.setParticlesPerSec(0); - flash.setGravity(0); + flash.setGravity(0, 0, 0); flash.setLowLife(.2f); flash.setHighLife(.2f); flash.setInitialVelocity(new Vector3f(0, 5f, 0)); @@ -117,7 +117,7 @@ public class TestExplosionEffect extends SimpleApplication { roundspark.setEndSize(1.8f); roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f)); roundspark.setParticlesPerSec(0); - roundspark.setGravity(-.5f); + roundspark.setGravity(0, -.5f, 0); roundspark.setLowLife(1.8f); roundspark.setHighLife(2f); roundspark.setInitialVelocity(new Vector3f(0, 3, 0)); @@ -141,7 +141,7 @@ public class TestExplosionEffect extends SimpleApplication { // spark.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); spark.setFacingVelocity(true); spark.setParticlesPerSec(0); - spark.setGravity(5); + spark.setGravity(0, 5, 0); spark.setLowLife(1.1f); spark.setHighLife(1.5f); spark.setInitialVelocity(new Vector3f(0, 20, 0)); @@ -164,7 +164,7 @@ public class TestExplosionEffect extends SimpleApplication { // smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); smoketrail.setFacingVelocity(true); smoketrail.setParticlesPerSec(0); - smoketrail.setGravity(1); + smoketrail.setGravity(0, 1, 0); smoketrail.setLowLife(.4f); smoketrail.setHighLife(.5f); smoketrail.setInitialVelocity(new Vector3f(0, 12, 0)); @@ -189,7 +189,7 @@ public class TestExplosionEffect extends SimpleApplication { // debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); debris.setParticlesPerSec(0); - debris.setGravity(12f); + debris.setGravity(0, 12f, 0); debris.setLowLife(1.4f); debris.setHighLife(1.5f); debris.setInitialVelocity(new Vector3f(0, 15, 0)); @@ -213,7 +213,7 @@ public class TestExplosionEffect extends SimpleApplication { shockwave.setEndSize(7f); shockwave.setParticlesPerSec(0); - shockwave.setGravity(0); + shockwave.setGravity(0, 0, 0); shockwave.setLowLife(0.5f); shockwave.setHighLife(0.5f); shockwave.setInitialVelocity(new Vector3f(0, 0, 0)); diff --git a/engine/src/test/jme3test/effect/TestMovingParticle.java b/engine/src/test/jme3test/effect/TestMovingParticle.java index 27a4334ed..dba56e086 100644 --- a/engine/src/test/jme3test/effect/TestMovingParticle.java +++ b/engine/src/test/jme3test/effect/TestMovingParticle.java @@ -58,7 +58,7 @@ public class TestMovingParticle extends SimpleApplication { @Override public void simpleInitApp() { emit = new ParticleEmitter("Emitter", Type.Triangle, 200); - emit.setGravity(0); + emit.setGravity(0, 0, 0); emit.setVelocityVariation(1); emit.setLowLife(1); emit.setHighLife(1); diff --git a/engine/src/test/jme3test/effect/TestParticleEmitter.java b/engine/src/test/jme3test/effect/TestParticleEmitter.java index 226417efe..6cc2f2c3d 100644 --- a/engine/src/test/jme3test/effect/TestParticleEmitter.java +++ b/engine/src/test/jme3test/effect/TestParticleEmitter.java @@ -50,7 +50,7 @@ public class TestParticleEmitter extends SimpleApplication { public void simpleInitApp() { ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Triangle, 200); emit.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); - emit.setGravity(0); + emit.setGravity(0, 0, 0); emit.setLowLife(5); emit.setHighLife(10); emit.setInitialVelocity(new Vector3f(0, 0, 0)); diff --git a/engine/src/test/jme3test/effect/TestPointSprite.java b/engine/src/test/jme3test/effect/TestPointSprite.java index 4577fb9f9..5d6f4ab33 100644 --- a/engine/src/test/jme3test/effect/TestPointSprite.java +++ b/engine/src/test/jme3test/effect/TestPointSprite.java @@ -52,7 +52,7 @@ public class TestPointSprite extends SimpleApplication { ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Point, 10000); emit.setShape(new EmitterBoxShape(new Vector3f(-1.8f, -1.8f, -1.8f), new Vector3f(1.8f, 1.8f, 1.8f))); - emit.setGravity(0); + emit.setGravity(0, 0, 0); emit.setLowLife(60); emit.setHighLife(60); emit.setInitialVelocity(new Vector3f(0, 0, 0)); diff --git a/engine/src/test/jme3test/helloworld/HelloEffects.java b/engine/src/test/jme3test/helloworld/HelloEffects.java index 2539af32c..a7f033830 100644 --- a/engine/src/test/jme3test/helloworld/HelloEffects.java +++ b/engine/src/test/jme3test/helloworld/HelloEffects.java @@ -60,7 +60,7 @@ public class HelloEffects extends SimpleApplication { fire.setInitialVelocity(new Vector3f(0, 2, 0)); fire.setStartSize(1.5f); fire.setEndSize(0.1f); - fire.setGravity(0); + fire.setGravity(0, 0, 0); fire.setLowLife(1f); fire.setHighLife(3f); fire.setVelocityVariation(0.3f); @@ -75,7 +75,7 @@ public class HelloEffects extends SimpleApplication { debris.setSelectRandomImage(true); debris.setInitialVelocity(new Vector3f(0, 4, 0)); debris.setStartColor(ColorRGBA.White); - debris.setGravity(6f); + debris.setGravity(0, 6, 0); debris.setVelocityVariation(.60f); rootNode.attachChild(debris); debris.emitAllParticles(); diff --git a/engine/src/test/jme3test/helloworld/HelloInput.java b/engine/src/test/jme3test/helloworld/HelloInput.java index eb6d1e8a5..c610af0aa 100644 --- a/engine/src/test/jme3test/helloworld/HelloInput.java +++ b/engine/src/test/jme3test/helloworld/HelloInput.java @@ -93,13 +93,13 @@ public class HelloInput extends SimpleApplication { public void onAnalog(String name, float value, float tpf) { if (isRunning) { if (name.equals("Rotate")) { - player.rotate(0, value*speed, 0); + player.rotate(0, value, 0); } if (name.equals("Right")) { - player.move((new Vector3f(value*speed, 0,0)) ); + player.move((new Vector3f(value, 0,0)) ); } if (name.equals("Left")) { - player.move(new Vector3f(-value*speed, 0,0)); + player.move(new Vector3f(-value, 0,0)); } } else { System.out.println("Press P to unpause."); diff --git a/engine/src/test/jme3test/light/TestTransparentShadow.java b/engine/src/test/jme3test/light/TestTransparentShadow.java index 9deed1df8..60678ab2c 100644 --- a/engine/src/test/jme3test/light/TestTransparentShadow.java +++ b/engine/src/test/jme3test/light/TestTransparentShadow.java @@ -122,7 +122,7 @@ public class TestTransparentShadow extends SimpleApplication { fire.setInitialVelocity(new Vector3f(0, 2, 0)); fire.setStartSize(0.6f); fire.setEndSize(0.1f); - fire.setGravity(0); + fire.setGravity(0, 0, 0); fire.setLowLife(0.5f); fire.setHighLife(1.5f); fire.setVelocityVariation(0.3f); diff --git a/engine/src/test/jme3test/water/TestPostWater.java b/engine/src/test/jme3test/water/TestPostWater.java index cdbb2790f..a39d60598 100644 --- a/engine/src/test/jme3test/water/TestPostWater.java +++ b/engine/src/test/jme3test/water/TestPostWater.java @@ -186,7 +186,7 @@ public class TestPostWater extends SimpleApplication { fire.setInitialVelocity(new Vector3f(0, 2, 0)); fire.setStartSize(10f); fire.setEndSize(1f); - fire.setGravity(0); + fire.setGravity(0, 0, 0); fire.setLowLife(0.5f); fire.setHighLife(1.5f); fire.setVelocityVariation(0.3f); diff --git a/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java b/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java index 9860555e5..2238668b2 100644 --- a/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java +++ b/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java @@ -34,7 +34,7 @@ package com.jme3.export.xml; import com.jme3.export.InputCapsule; import com.jme3.export.Savable; -import com.jme3.export.binary.BinaryClassLoader; +import com.jme3.export.SavableClassFinder; import com.jme3.util.BufferUtils; import com.jme3.util.IntMap; import java.io.IOException; @@ -973,7 +973,7 @@ public class DOMInputCapsule implements InputCapsule { } else if (currentElem.hasAttribute("class")) { className = currentElem.getAttribute("class"); } - tmp = BinaryClassLoader.fromName(className, null); + tmp = SavableClassFinder.fromName(className, null); String refID = currentElem.getAttribute("reference_ID"); if (refID.length() < 1) refID = currentElem.getAttribute("id"); if (refID.length() > 0) referencedSavables.put(refID, tmp);