* 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
3.0
sha..rd 14 years ago
parent 4079aeab5e
commit 80900a8d64
  1. 2
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java
  2. 118
      engine/src/core-plugins/com/jme3/export/binary/BinaryClassLoader.java
  3. 3
      engine/src/core-plugins/com/jme3/export/binary/BinaryImporter.java
  4. 19
      engine/src/core/com/jme3/effect/ParticleEmitter.java
  5. 134
      engine/src/core/com/jme3/export/SavableClassFinder.java
  6. 31
      engine/src/core/com/jme3/input/InputManager.java
  7. 4
      engine/src/core/com/jme3/input/controls/JoyAxisTrigger.java
  8. 4
      engine/src/core/com/jme3/input/controls/JoyButtonTrigger.java
  9. 4
      engine/src/core/com/jme3/input/controls/KeyTrigger.java
  10. 4
      engine/src/core/com/jme3/input/controls/MouseAxisTrigger.java
  11. 3
      engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java
  12. 11
      engine/src/core/com/jme3/input/controls/TouchTrigger.java
  13. 7
      engine/src/core/com/jme3/input/controls/Trigger.java
  14. 33
      engine/src/core/com/jme3/material/FixedFuncBinding.java
  15. 70
      engine/src/core/com/jme3/material/MatParam.java
  16. 72
      engine/src/core/com/jme3/material/MaterialDef.java
  17. 6
      engine/src/core/com/jme3/material/MaterialList.java
  18. 12
      engine/src/core/com/jme3/material/RenderState.java
  19. 79
      engine/src/core/com/jme3/material/Technique.java
  20. 58
      engine/src/core/com/jme3/material/package.html
  21. 2
      engine/src/core/com/jme3/scene/Spatial.java
  22. 3
      engine/src/core/com/jme3/scene/control/AbstractControl.java
  23. 2
      engine/src/test/jme3test/bullet/BombControl.java
  24. 2
      engine/src/test/jme3test/bullet/TestWalkingChar.java
  25. 14
      engine/src/test/jme3test/effect/TestExplosionEffect.java
  26. 2
      engine/src/test/jme3test/effect/TestMovingParticle.java
  27. 2
      engine/src/test/jme3test/effect/TestParticleEmitter.java
  28. 2
      engine/src/test/jme3test/effect/TestPointSprite.java
  29. 4
      engine/src/test/jme3test/helloworld/HelloEffects.java
  30. 6
      engine/src/test/jme3test/helloworld/HelloInput.java
  31. 2
      engine/src/test/jme3test/light/TestTransparentShadow.java
  32. 2
      engine/src/test/jme3test/water/TestPostWater.java
  33. 4
      engine/src/xml/com/jme3/export/xml/DOMInputCapsule.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;

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

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

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

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

@ -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) {

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

@ -66,4 +66,8 @@ public class JoyButtonTrigger implements Trigger {
return "JoyButton[joyId="+joyId+", axisId="+buttonId+"]";
}
public int triggerHashCode() {
return joyButtonHash(joyId, buttonId);
}
}

@ -65,4 +65,8 @@ public class KeyTrigger implements Trigger {
return keyCode & 0xff;
}
public int triggerHashCode() {
return keyHash(keyCode);
}
}

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

@ -70,8 +70,7 @@ public class MouseButtonTrigger implements Trigger {
return 256 | (mouseButton & 0xff);
}
@Override
public int hashCode(){
public int triggerHashCode() {
return mouseButtonHash(mouseButton);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save