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 13d8d50e4..dff4da90d 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -45,7 +45,6 @@ import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.post.SceneProcessor; import com.jme3.renderer.Camera; -import com.jme3.renderer.Caps; import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; import com.jme3.renderer.ViewPort; @@ -63,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 @@ -74,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; @@ -678,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); @@ -748,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. @@ -790,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); @@ -815,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..1ac016f15 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,11 @@ public class DirectionalLightShadowRenderer 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(); @@ -215,7 +220,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { @Override protected void setMaterialParameters(Material material) { material.setColor("Splits", splits); - material.setVector3("LightDir", light.getDirection()); + material.setVector3("LightDir", light == null ? new Vector3f() : light.getDirection()); if (fadeInfo != null) { material.setVector2("FadeInfo", fadeInfo); } @@ -248,11 +253,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 +270,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 +293,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..407f72367 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 @@ -171,7 +174,7 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { @Override protected void setMaterialParameters(Material material) { - material.setVector3("LightPos", light.getPosition()); + material.setVector3("LightPos", light == null ? new Vector3f() : light.getPosition()); } @Override @@ -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); } @@ -218,7 +229,12 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { * @return */ @Override - protected boolean checkCulling(Camera viewCam) { + protected boolean checkCulling(Camera viewCam) { + + if (light == null) { + return false; + } + Camera cam = viewCam; if(frustumCam != null){ cam = frustumCam; 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);