2
0
Эх сурвалжийг харах

* Moved MatParamTexture out of the Material class (might break loading of old j3o models ..)
* Renamed BinaryClassLoader to SavableClassFinder and put it into core
* SavableClassFinder now can remap class names, it is used to load old J3O files with particles in them by remapping the old shape names to the new names.
* Moved the particle emitter control into an inner class so nobody fools around with it
* Loading of old particle emitters now works
* Fixed issue with input not responding
* Fixed some small javadoc mistakes in RenderState
* Javadocs for com.jme3.material (not done)
* AbstractControl will now throw exception when an already-attached control is added to another spatial
* All tests should now use non-deprecated ParticleEmitter.setGravity method

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7589 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

sha..rd 14 жил өмнө
parent
commit
80900a8d64
33 өөрчлөгдсөн 503 нэмэгдсэн , 218 устгасан
  1. 1 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java
  2. 0 118
      engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java
  3. 2 1
      engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java
  4. 19 0
      engine/src/core/com/jme3/effect/ParticleEmitter.java
  5. 134 0
      engine/src/core/com/jme3/export/SavableClassFinder.java
  6. 4 27
      engine/src/core/com/jme3/input/InputManager.java
  7. 4 0
      engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java
  8. 4 0
      engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java
  9. 4 0
      engine/src/core/com/jme3/input/controls/KeyTrigger.java
  10. 4 0
      engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java
  11. 1 2
      engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java
  12. 5 6
      engine/src/core/com/jme3/input/controls/TouchTrigger.java
  13. 7 0
      engine/src/core/com/jme3/input/controls/Trigger.java
  14. 33 0
      engine/src/core/com/jme3/material/FixedFuncBinding.java
  15. 58 12
      engine/src/core/com/jme3/material/MatParam.java
  16. 72 0
      engine/src/core/com/jme3/material/MaterialDef.java
  17. 6 0
      engine/src/core/com/jme3/material/MaterialList.java
  18. 7 5
      engine/src/core/com/jme3/material/RenderState.java
  19. 55 24
      engine/src/core/com/jme3/material/Technique.java
  20. 58 0
      engine/src/core/com/jme3/material/package.html
  21. 1 1
      engine/src/core/com/jme3/scene/Spatial.java
  22. 3 0
      engine/src/core/com/jme3/scene/control/AbstractControl.java
  23. 1 1
      engine/src/test/jme3test/bullet/BombControl.java
  24. 1 1
      engine/src/test/jme3test/bullet/TestWalkingChar.java
  25. 7 7
      engine/src/test/jme3test/effect/TestExplosionEffect.java
  26. 1 1
      engine/src/test/jme3test/effect/TestMovingParticle.java
  27. 1 1
      engine/src/test/jme3test/effect/TestParticleEmitter.java
  28. 1 1
      engine/src/test/jme3test/effect/TestPointSprite.java
  29. 2 2
      engine/src/test/jme3test/helloworld/HelloEffects.java
  30. 3 3
      engine/src/test/jme3test/helloworld/HelloInput.java
  31. 1 1
      engine/src/test/jme3test/light/TestTransparentShadow.java
  32. 1 1
      engine/src/test/jme3test/water/TestPostWater.java
  33. 2 2
      engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java

+ 1 - 1
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;

+ 0 - 118
engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java

@@ -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<ClassLoader> loaders) throws InstantiationException, 
-        IllegalAccessException, ClassNotFoundException, IOException {
-        if(loaders == null){
-            return fromName(className, inputCapsule);
-        }
-        for (Iterator<ClassLoader> 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;
-        }
-    }
-}

+ 2 - 1
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);

+ 19 - 0
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);
+        }
     }
 }

+ 134 - 0
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;
+
+/**
+ * <code>SavableClassFinder</code> 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<String, String> classRemappings = new HashMap<String, String>();
+
+    private static void addRemapping(String oldClass, Class<? extends Savable> 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<ClassLoader> 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);
+    }
+}

+ 4 - 27
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<Mapping> names = bindings.get(hash);
             if (names == null) {
                 names = new ArrayList<Mapping>();
@@ -617,7 +595,7 @@ public class InputManager implements RawInputListener {
             throw new IllegalArgumentException("Cannot find mapping: " + mappingName);
         }
 
-        ArrayList<Mapping> maps = bindings.get(trigger.hashCode());
+        ArrayList<Mapping> 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<Mapping> maps = bindings.get(TouchTrigger.getHash());
+        ArrayList<Mapping> 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) {

+ 4 - 0
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);
+    }
     
 }

+ 4 - 0
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);
+    }
+
 }

+ 4 - 0
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);
+    }
+
 }

+ 4 - 0
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);
+    }
 }

+ 1 - 2
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);
     }
 

+ 5 - 6
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();
+    }
 }

+ 7 - 0
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();
 }

+ 33 - 0
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.
+     * <p>
+     * Used only for non-lit materials.
+     */
     Color,
+    
+    /**
+     * Specifies the material shininess value.
+     * 
+     * Same as GL_SHININESS for OpenGL.
+     */
+    Shininess
 }

+ 58 - 12
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.
+     * <p>
+     * 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.
+     * <p>
+     * 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.<br/>
@@ -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());
-        }
-    }
 }
 

+ 72 - 0
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<String, TechniqueDef> techniques;
     private Map<String, MatParam> 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.
+     * <p>
+     * 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<TechniqueDef> 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);
     }

+ 6 - 0
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<String, Material> {
 }

+ 7 - 5
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. 
      * 
      * <p>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 
      * <code>gl_PointCoord</code> 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.
      * 
      * <p>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.
      * 
-     * <p>When blending is enabled, (<code>blendMode</code> is not BlendMode.Off)
+     * <p>When blending is enabled, (<code>blendMode</code> 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}

+ 55 - 24
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.
+     * <p>
+     * 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<Uniform> 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();
+    }
 }

+ 58 - 0
engine/src/core/com/jme3/material/package.html

@@ -0,0 +1,58 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body>
+
+The <code>com.jme3.material</code> 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.
+<p>
+Materials (also known as material instances) are extended from
+material definitions.
+
+<h3>Material definitions</h3>
+<p>
+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.
+
+<h3>Techniques</h3>
+<p>
+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
+
+<h3>Render states</h3>
+<p>
+See {@link com.jme3.material.RenderState}.
+
+<h3>Example Usage</h3>
+<p>
+Creating a textured material
+<code>
+// 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);
+</code>
+
+
+
+</body>
+</html>

+ 1 - 1
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<String, Savable>) ic.readStringSavableMap("user_data", null);
     }
 

+ 3 - 0
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;
     }
 

+ 1 - 1
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));

+ 1 - 1
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));

+ 7 - 7
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));

+ 1 - 1
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);

+ 1 - 1
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));

+ 1 - 1
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));

+ 2 - 2
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();

+ 3 - 3
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.");

+ 1 - 1
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);

+ 1 - 1
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);

+ 2 - 2
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);