Update the water filter (#693)

WaterFilter now serializes the different textures textures, and can optionally serialize the reflection scene
fix-456
Alexandr Brui 7 years ago committed by Rémy Bouquet
parent 3058c218c5
commit 6e5e85f7ac
  1. 231
      jme3-effects/src/main/java/com/jme3/water/WaterFilter.java

@ -31,7 +31,9 @@
*/
package com.jme3.water;
import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
@ -41,7 +43,6 @@ import com.jme3.light.Light;
import com.jme3.material.Material;
import com.jme3.math.*;
import com.jme3.post.Filter;
import com.jme3.post.Filter.Pass;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer;
@ -51,7 +52,9 @@ import com.jme3.scene.Spatial;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.texture.Texture2D;
import com.jme3.util.TempVars;
import com.jme3.util.clone.Cloner;
import com.jme3.util.clone.JmeCloneable;
import java.io.IOException;
/**
@ -62,17 +65,22 @@ import java.io.IOException;
*
* @author Rémy Bouquet aka Nehon
*/
public class WaterFilter extends Filter {
public class WaterFilter extends Filter implements JmeCloneable, Cloneable {
public static final String DEFAULT_NORMAL_MAP = "Common/MatDefs/Water/Textures/water_normalmap.dds";
public static final String DEFAULT_FOAM = "Common/MatDefs/Water/Textures/foam.jpg";
public static final String DEFAULT_CAUSTICS = "Common/MatDefs/Water/Textures/caustics.jpg";
public static final String DEFAULT_HEIGHT_MAP = "Common/MatDefs/Water/Textures/heightmap.jpg";
private Pass reflectionPass;
protected Spatial reflectionScene;
protected Spatial rootScene;
protected ViewPort reflectionView;
private Texture2D normalTexture;
private Texture2D foamTexture;
private Texture2D causticsTexture;
private Texture2D heightTexture;
private Camera reflectionCam;
protected Ray ray = new Ray();
private Vector3f targetLocation = new Vector3f();
private ReflectionProcessor reflectionProcessor;
private Matrix4f biasMatrix = new Matrix4f(0.5f, 0.0f, 0.0f, 0.5f,
@ -121,6 +129,8 @@ public class WaterFilter extends Filter {
private float radius;
private AreaShape shapeType = AreaShape.Circular;
private boolean needSaveReflectionScene;
public enum AreaShape{
Circular,
Square
@ -201,16 +211,23 @@ public class WaterFilter extends Filter {
return null;
}
/**
* @return true if need to try to use direction light from a scene.
*/
protected boolean useDirectionLightFromScene() {
return true;
}
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
rootScene = vp.getScenes().get(0);
if (reflectionScene == null) {
reflectionScene = vp.getScenes().get(0);
DirectionalLight l = findLight((Node) reflectionScene);
if (l != null) {
lightDirection = l.getDirection();
reflectionScene = rootScene;
DirectionalLight directionalLight = findLight((Node) reflectionScene);
if (directionalLight != null && useDirectionLightFromScene()) {
lightDirection = directionalLight.getDirection();
}
}
this.renderManager = renderManager;
@ -227,19 +244,25 @@ public class WaterFilter extends Filter {
reflectionProcessor.setReflectionClipPlane(plane);
reflectionView.addProcessor(reflectionProcessor);
normalTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/water_normalmap.dds");
if (normalTexture == null) {
normalTexture = (Texture2D) manager.loadTexture(DEFAULT_NORMAL_MAP);
normalTexture.setWrap(WrapMode.Repeat);
}
if (foamTexture == null) {
foamTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg");
foamTexture = (Texture2D) manager.loadTexture(DEFAULT_FOAM);
foamTexture.setWrap(WrapMode.Repeat);
}
if (causticsTexture == null) {
causticsTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/caustics.jpg");
causticsTexture = (Texture2D) manager.loadTexture(DEFAULT_CAUSTICS);
causticsTexture.setWrap(WrapMode.Repeat);
}
heightTexture = (Texture2D) manager.loadTexture("Common/MatDefs/Water/Textures/heightmap.jpg");
normalTexture.setWrap(WrapMode.Repeat);
foamTexture.setWrap(WrapMode.Repeat);
causticsTexture.setWrap(WrapMode.Repeat);
heightTexture.setWrap(WrapMode.Repeat);
if (heightTexture == null) {
heightTexture = (Texture2D) manager.loadTexture(DEFAULT_HEIGHT_MAP);
heightTexture.setWrap(WrapMode.Repeat);
}
material = new Material(manager, "Common/MatDefs/Water/Water.j3md");
material.setTexture("HeightMap", heightTexture);
@ -278,10 +301,9 @@ public class WaterFilter extends Filter {
if (center != null) {
material.setVector3("Center", center);
material.setFloat("Radius", radius * radius);
material.setBoolean("SquareArea", shapeType==AreaShape.Square);
material.setBoolean("SquareArea", shapeType == AreaShape.Square);
}
material.setFloat("WaterHeight", waterHeight);
}
@Override
@ -292,8 +314,36 @@ public class WaterFilter extends Filter {
@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
final Spatial reflectionScene = getReflectionScene();
final boolean needSaveReflectionScene = isNeedSaveReflectionScene();
final AssetKey causticsTextureKey = causticsTexture.getKey();
final AssetKey heightTextureKey = heightTexture.getKey();
final AssetKey normalTextureKey = normalTexture.getKey();
final AssetKey foamTextureKey = foamTexture.getKey();
if (causticsTextureKey != null && !DEFAULT_CAUSTICS.equals(causticsTextureKey.getName())) {
oc.write(causticsTextureKey, "causticsTexture", null);
}
if (heightTextureKey != null && !DEFAULT_HEIGHT_MAP.equals(heightTextureKey.getName())) {
oc.write(heightTextureKey, "heightTexture", null);
}
if (normalTextureKey != null && !DEFAULT_NORMAL_MAP.equals(normalTextureKey.getName())) {
oc.write(normalTextureKey, "normalTexture", null);
}
if (foamTextureKey != null && !DEFAULT_FOAM.equals(foamTextureKey.getName())) {
oc.write(foamTextureKey, "foamTexture", null);
}
oc.write(needSaveReflectionScene, "needSaveReflectionScene", false);
if (needSaveReflectionScene) {
oc.write(reflectionScene, "reflectionScene", null);
}
oc.write(speed, "speed", 1f);
oc.write(lightDirection, "lightDirection", new Vector3f(0, -1, 0));
oc.write(lightColor, "lightColor", ColorRGBA.White);
@ -382,6 +432,29 @@ public class WaterFilter extends Filter {
useCaustics = ic.readBoolean("useCaustics", true);
final TextureKey causticsTextureKey = (TextureKey) ic.readSavable("causticsTexture", null);
final TextureKey heightTextureKey = (TextureKey) ic.readSavable("heightTexture", null);
final TextureKey normalTextureKey = (TextureKey) ic.readSavable("normalTexture", null);
final TextureKey foamTextureKey = (TextureKey) ic.readSavable("foamTexture", null);
needSaveReflectionScene = ic.readBoolean("needSaveReflectionScene", false);
reflectionScene = (Spatial) ic.readSavable("reflectionScene", null);
final AssetManager assetManager = im.getAssetManager();
if (causticsTextureKey != null) {
setCausticsTexture((Texture2D) assetManager.loadTexture(causticsTextureKey));
}
if (heightTextureKey != null) {
setHeightTexture((Texture2D) assetManager.loadTexture(heightTextureKey));
}
if (normalTextureKey != null) {
setNormalTexture((Texture2D) assetManager.loadTexture(normalTextureKey));
}
if (foamTextureKey != null) {
setFoamTexture((Texture2D) assetManager.loadTexture(foamTextureKey));
}
//positional attributes
center = (Vector3f) ic.readSavable("center", null);
radius = ic.readFloat("radius", 0f);
@ -414,11 +487,32 @@ public class WaterFilter extends Filter {
}
/**
* sets the scene to render in the reflection map
* @param reflectionScene
* Sets the scene to render in the reflection map.
*
* @param reflectionScene the refraction scene.
*/
public void setReflectionScene(Spatial reflectionScene) {
public void setReflectionScene(final Spatial reflectionScene) {
final Spatial currentScene = getReflectionScene();
if (reflectionView != null) {
reflectionView.detachScene(currentScene == null? rootScene : currentScene);
}
this.reflectionScene = reflectionScene;
if (reflectionView != null) {
reflectionView.attachScene(reflectionScene == null? rootScene : reflectionScene);
}
}
/**
* Gets the scene which is used to render in the reflection map.
*
* @return the refraction scene.
*/
public Spatial getReflectionScene() {
return reflectionScene;
}
/**
@ -696,8 +790,9 @@ public class WaterFilter extends Filter {
}
/**
* Sets the foam texture
* @param foamTexture
* Sets the foam texture.
*
* @param foamTexture the foam texture.
*/
public void setFoamTexture(Texture2D foamTexture) {
this.foamTexture = foamTexture;
@ -707,8 +802,18 @@ public class WaterFilter extends Filter {
}
}
/**
* Gets the foam texture.
*
* @return the foam texture.
*/
public Texture2D getFoamTexture() {
return foamTexture;
}
/**
* Sets the height texture
*
* @param heightTexture
*/
public void setHeightTexture(Texture2D heightTexture) {
@ -720,8 +825,18 @@ public class WaterFilter extends Filter {
}
/**
* Sets the normal Texture
* @param normalTexture
* Gets the height texture.
*
* @return the height texture.
*/
public Texture2D getHeightTexture() {
return heightTexture;
}
/**
* Sets the normal texture.
*
* @param normalTexture the normal texture.
*/
public void setNormalTexture(Texture2D normalTexture) {
this.normalTexture = normalTexture;
@ -731,6 +846,15 @@ public class WaterFilter extends Filter {
}
}
/**
* Gets the normal texture.
*
* @return the normal texture.
*/
public Texture2D getNormalTexture() {
return normalTexture;
}
/**
* return the shininess factor of the water
* @return
@ -878,8 +1002,9 @@ public class WaterFilter extends Filter {
}
/**
* sets the texture to use to render caustics on the ground underwater
* @param causticsTexture
* Sets the texture to use to render caustics on the ground underwater.
*
* @param causticsTexture the caustics texture.
*/
public void setCausticsTexture(Texture2D causticsTexture) {
this.causticsTexture = causticsTexture;
@ -888,6 +1013,15 @@ public class WaterFilter extends Filter {
}
}
/**
* Gets the texture which is used to render caustics on the ground underwater.
*
* @return the caustics texture.
*/
public Texture2D getCausticsTexture() {
return causticsTexture;
}
/**
* Whether or not caustics are rendered
* @return true if caustics are rendered
@ -1133,5 +1267,46 @@ public class WaterFilter extends Filter {
}
}
@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) {
this.normalTexture = cloner.clone(normalTexture);
this.foamTexture = cloner.clone(foamTexture);
this.causticsTexture = cloner.clone(causticsTexture);
this.heightTexture = cloner.clone(heightTexture);
this.targetLocation = cloner.clone(targetLocation);
this.biasMatrix = cloner.clone(biasMatrix);
this.textureProjMatrix = cloner.clone(textureProjMatrix);
this.lightDirection = cloner.clone(lightDirection);
this.lightColor = cloner.clone(lightColor);
this.waterColor = cloner.clone(waterColor);
this.deepWaterColor = cloner.clone(deepWaterColor);
this.colorExtinction = cloner.clone(colorExtinction);
this.foamExistence = cloner.clone(foamExistence);
this.windDirection = cloner.clone(windDirection);
}
/**
* Sets the flag.
*
* @param needSaveReflectionScene true if need to save reflection scene.
*/
public void setNeedSaveReflectionScene(final boolean needSaveReflectionScene) {
this.needSaveReflectionScene = needSaveReflectionScene;
}
/**
* @return true if need to save reflection scene.
*/
public boolean isNeedSaveReflectionScene() {
return needSaveReflectionScene;
}
}
Loading…
Cancel
Save