diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowFilter.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowFilter.java index 0d839be29..aa80fa0c6 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowFilter.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowFilter.java @@ -45,6 +45,8 @@ import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; import com.jme3.renderer.queue.RenderQueue; import com.jme3.texture.FrameBuffer; +import com.jme3.util.clone.Cloner; +import com.jme3.util.clone.JmeCloneable; import java.io.IOException; @@ -55,7 +57,7 @@ import java.io.IOException; * * @author Rémy Bouquet aka Nehon */ -public abstract class AbstractShadowFilter extends Filter { +public abstract class AbstractShadowFilter extends Filter implements Cloneable, JmeCloneable { protected T shadowRenderer; protected ViewPort viewPort; @@ -303,17 +305,31 @@ public abstract class AbstractShadowFilter ext return shadowRenderer.getEdgeFilteringMode(); } + @Override + public AbstractShadowFilter jmeClone() { + try { + return (AbstractShadowFilter) super.clone(); + } catch (final CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + @Override + public void cloneFields(final Cloner cloner, final Object original) { + material = cloner.clone(material); + shadowRenderer = cloner.clone(shadowRenderer); + shadowRenderer.setPostShadowMaterial(material); + } + @Override public void write(JmeExporter ex) throws IOException { super.write(ex); OutputCapsule oc = ex.getCapsule(this); - } @Override public void read(JmeImporter im) throws IOException { super.read(im); InputCapsule ic = im.getCapsule(this); - } } diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 2857eef88..44ed63778 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -62,10 +62,13 @@ import com.jme3.texture.Texture.MinFilter; import com.jme3.texture.Texture.ShadowCompareMode; import com.jme3.texture.Texture2D; import com.jme3.ui.Picture; +import com.jme3.util.clone.Cloner; +import com.jme3.util.clone.JmeCloneable; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; /** * abstract shadow renderer that holds commons feature to have for a shadow @@ -73,7 +76,9 @@ import java.util.List; * * @author Rémy Bouquet aka Nehon */ -public abstract class AbstractShadowRenderer implements SceneProcessor, Savable { +public abstract class AbstractShadowRenderer implements SceneProcessor, Savable, JmeCloneable, Cloneable { + + protected static final Logger logger = Logger.getLogger(AbstractShadowRenderer.class.getName()); protected int nbShadowMaps = 1; protected float shadowMapSize; @@ -147,7 +152,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable } - protected void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize) { + private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize) { this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md"); shadowFB = new FrameBuffer[nbShadowMaps]; shadowMaps = new Texture2D[nbShadowMaps]; @@ -677,8 +682,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable } /** - * returns true if the light source bounding box is in the view frustum - * @return + * @return true if the light source bounding box is in the view frustum */ protected abstract boolean checkCulling(Camera viewCam); @@ -747,7 +751,6 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable @Deprecated public void setFlushQueues(boolean flushQueues) {} - /** * returns the pre shadows pass render state. * use it to adjust the RenderState parameters of the pre shadow pass. @@ -789,13 +792,28 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable return renderBackFacesShadows != null?renderBackFacesShadows:false; } + @Override + public Object jmeClone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + @Override + public void cloneFields(final Cloner cloner, final Object original) { + forcedRenderState = cloner.clone(forcedRenderState); + init(assetManager, nbShadowMaps, (int) shadowMapSize); + } + /** * De-serialize this instance, for example when loading from a J3O file. * * @param im importer (not null) */ public void read(JmeImporter im) throws IOException { - InputCapsule ic = (InputCapsule) im.getCapsule(this); + InputCapsule ic = im.getCapsule(this); assetManager = im.getAssetManager(); nbShadowMaps = ic.readInt("nbShadowMaps", 1); shadowMapSize = ic.readFloat("shadowMapSize", 0f); @@ -814,7 +832,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable * @param ex exporter (not null) */ public void write(JmeExporter ex) throws IOException { - OutputCapsule oc = (OutputCapsule) ex.getCapsule(this); + OutputCapsule oc = ex.getCapsule(this); oc.write(nbShadowMaps, "nbShadowMaps", 1); oc.write(shadowMapSize, "shadowMapSize", 0); oc.write(shadowIntensity, "shadowIntensity", 0.7f); diff --git a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java index 196bfbe7c..5fb2a6929 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java @@ -46,6 +46,8 @@ import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Node; import com.jme3.scene.Spatial; +import com.jme3.util.clone.Cloner; + import java.io.IOException; /** @@ -112,8 +114,6 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { protected void initFrustumCam() { //nothing to do } - - /** * return the light used to cast shadows @@ -136,6 +136,12 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { @Override protected void updateShadowCams(Camera viewCam) { + // it needs to support for editors + if (light == null) { + logger.warning("The light can't be null for a " + getClass().getName()); + return; + } + float zFar = zFarOverride; if (zFar == 0) { zFar = viewCam.getFrustumFar(); @@ -248,11 +254,9 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { public void setLambda(float lambda) { this.lambda = lambda; } - /** - * retruns true if stabilization is enabled - * @return + * @return true if stabilization is enabled */ public boolean isEnabledStabilization() { return stabilize; @@ -267,11 +271,18 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { public void setEnabledStabilization(boolean stabilize) { this.stabilize = stabilize; } - + + @Override + public void cloneFields(final Cloner cloner, final Object original) { + light = cloner.clone(light); + init(nbShadowMaps, (int) shadowMapSize); + super.cloneFields(cloner, original); + } + @Override public void read(JmeImporter im) throws IOException { super.read(im); - InputCapsule ic = (InputCapsule) im.getCapsule(this); + InputCapsule ic = im.getCapsule(this); lambda = ic.readFloat("lambda", 0.65f); zFarOverride = ic.readInt("zFarOverride", 0); light = (DirectionalLight) ic.readSavable("light", null); @@ -283,7 +294,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { @Override public void write(JmeExporter ex) throws IOException { super.write(ex); - OutputCapsule oc = (OutputCapsule) ex.getCapsule(this); + OutputCapsule oc = ex.getCapsule(this); oc.write(lambda, "lambda", 0.65f); oc.write(zFarOverride, "zFarOverride", 0); oc.write(light, "light", null); diff --git a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java index f4a6455f1..06c4451f1 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java @@ -46,6 +46,8 @@ import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.util.TempVars; +import com.jme3.util.clone.Cloner; + import java.io.IOException; /** @@ -100,7 +102,8 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { protected void updateShadowCams(Camera viewCam) { if (light == null) { - throw new IllegalStateException("The light can't be null for a " + this.getClass().getName()); + logger.warning("The light can't be null for a " + getClass().getName()); + return; } //bottom @@ -197,10 +200,18 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { this.light = light; } + @Override + public void cloneFields(final Cloner cloner, final Object original) { + light = cloner.clone(light); + init((int) shadowMapSize); + frustums = null; + super.cloneFields(cloner, original); + } + @Override public void read(JmeImporter im) throws IOException { super.read(im); - InputCapsule ic = (InputCapsule) im.getCapsule(this); + InputCapsule ic = im.getCapsule(this); light = (PointLight) ic.readSavable("light", null); init((int) shadowMapSize); } @@ -208,7 +219,7 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { @Override public void write(JmeExporter ex) throws IOException { super.write(ex); - OutputCapsule oc = (OutputCapsule) ex.getCapsule(this); + OutputCapsule oc = ex.getCapsule(this); oc.write(light, "light", null); } diff --git a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java index b291e722e..e1d7db05e 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java @@ -47,6 +47,8 @@ import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.util.TempVars; +import com.jme3.util.clone.Cloner; + import java.io.IOException; /** @@ -123,6 +125,11 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { @Override protected void updateShadowCams(Camera viewCam) { + if (light == null) { + logger.warning("The light can't be null for a " + getClass().getName()); + return; + } + float zFar = zFarOverride; if (zFar == 0) { zFar = viewCam.getFrustumFar(); @@ -139,7 +146,6 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { shadowCam.update(); shadowCam.updateViewProjection(); - } @Override @@ -186,11 +192,17 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { material.clearParam("LightDir"); } - + @Override + public void cloneFields(final Cloner cloner, final Object original) { + light = cloner.clone(light); + init((int) shadowMapSize); + super.cloneFields(cloner, original); + } + @Override public void read(JmeImporter im) throws IOException { super.read(im); - InputCapsule ic = (InputCapsule) im.getCapsule(this); + InputCapsule ic = im.getCapsule(this); zFarOverride = ic.readInt("zFarOverride", 0); light = (SpotLight) ic.readSavable("light", null); fadeInfo = (Vector2f) ic.readSavable("fadeInfo", null); @@ -202,7 +214,7 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { @Override public void write(JmeExporter ex) throws IOException { super.write(ex); - OutputCapsule oc = (OutputCapsule) ex.getCapsule(this); + OutputCapsule oc = ex.getCapsule(this); oc.write(zFarOverride, "zFarOverride", 0); oc.write(light, "light", null); oc.write(fadeInfo, "fadeInfo", null);