1 package jme3test.water;
2 
3 import com.jme3.app.SimpleApplication;
4 import com.jme3.audio.AudioNode;
5 import com.jme3.audio.LowPassFilter;
6 import com.jme3.effect.ParticleEmitter;
7 import com.jme3.effect.ParticleMesh;
8 import com.jme3.input.controls.ActionListener;
9 import com.jme3.input.controls.KeyTrigger;
10 import com.jme3.light.DirectionalLight;
11 import com.jme3.material.Material;
12 import com.jme3.material.RenderState.BlendMode;
13 import com.jme3.math.ColorRGBA;
14 import com.jme3.math.FastMath;
15 import com.jme3.math.Quaternion;
16 import com.jme3.math.Vector3f;
17 import com.jme3.post.FilterPostProcessor;
18 import com.jme3.post.filters.BloomFilter;
19 import com.jme3.post.filters.DepthOfFieldFilter;
20 import com.jme3.post.filters.LightScatteringFilter;
21 import com.jme3.renderer.Camera;
22 import com.jme3.renderer.queue.RenderQueue.Bucket;
23 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
24 import com.jme3.scene.Geometry;
25 import com.jme3.scene.Node;
26 import com.jme3.scene.Spatial;
27 import com.jme3.scene.shape.Box;
28 import com.jme3.terrain.geomipmap.TerrainQuad;
29 import com.jme3.terrain.heightmap.AbstractHeightMap;
30 import com.jme3.terrain.heightmap.ImageBasedHeightMap;
31 import com.jme3.texture.Texture;
32 import com.jme3.texture.Texture.WrapMode;
33 import com.jme3.texture.Texture2D;
34 import com.jme3.util.SkyFactory;
35 import com.jme3.water.WaterFilter;
36 import java.util.ArrayList;
37 import java.util.List;
38 
39 /**
40  * test
41  * @author normenhansen
42  */
43 public class TestPostWater extends SimpleApplication {
44 
45     private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
46     private WaterFilter water;
47     TerrainQuad terrain;
48     Material matRock;
49     AudioNode waves;
50     LowPassFilter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f);
51     LowPassFilter underWaterReverbFilter = new LowPassFilter(0.5f, 0.1f);
52     LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1);
53 
main(String[] args)54     public static void main(String[] args) {
55         TestPostWater app = new TestPostWater();
56         app.start();
57     }
58 
59     @Override
simpleInitApp()60     public void simpleInitApp() {
61 
62       setDisplayFps(false);
63       setDisplayStatView(false);
64 
65         Node mainScene = new Node("Main Scene");
66         rootNode.attachChild(mainScene);
67 
68         createTerrain(mainScene);
69         DirectionalLight sun = new DirectionalLight();
70         sun.setDirection(lightDir);
71         sun.setColor(ColorRGBA.White.clone().multLocal(1.7f));
72         mainScene.addLight(sun);
73 
74         DirectionalLight l = new DirectionalLight();
75         l.setDirection(Vector3f.UNIT_Y.mult(-1));
76         l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
77 //        mainScene.addLight(l);
78 
79         flyCam.setMoveSpeed(50);
80 
81         //cam.setLocation(new Vector3f(-700, 100, 300));
82          //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z));
83         cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f));
84         cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f));
85 
86 
87         cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));
88 
89 
90         Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
91         sky.setLocalScale(350);
92 
93         mainScene.attachChild(sky);
94         cam.setFrustumFar(4000);
95         //cam.setFrustumNear(100);
96 
97 
98 
99         //private FilterPostProcessor fpp;
100 
101 
102         water = new WaterFilter(rootNode, lightDir);
103 
104         FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
105 
106         fpp.addFilter(water);
107         BloomFilter bloom=new BloomFilter();
108         //bloom.getE
109         bloom.setExposurePower(55);
110         bloom.setBloomIntensity(1.0f);
111         fpp.addFilter(bloom);
112         LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300));
113         lsf.setLightDensity(1.0f);
114         fpp.addFilter(lsf);
115         DepthOfFieldFilter dof=new DepthOfFieldFilter();
116         dof.setFocusDistance(0);
117         dof.setFocusRange(100);
118         fpp.addFilter(dof);
119 //
120 
121      //   fpp.addFilter(new TranslucentBucketFilter());
122  //
123 
124          // fpp.setNumSamples(4);
125 
126 
127         water.setWaveScale(0.003f);
128         water.setMaxAmplitude(2f);
129         water.setFoamExistence(new Vector3f(1f, 4, 0.5f));
130         water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
131         //water.setNormalScale(0.5f);
132 
133         //water.setRefractionConstant(0.25f);
134         water.setRefractionStrength(0.2f);
135         //water.setFoamHardness(0.6f);
136 
137         water.setWaterHeight(initialWaterHeight);
138       uw=cam.getLocation().y<waterHeight;
139 
140         waves = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Ocean Waves.ogg", false);
141         waves.setLooping(true);
142         waves.setReverbEnabled(true);
143         if(uw){
144             waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));
145         }else{
146             waves.setDryFilter(aboveWaterAudioFilter);
147         }
148         audioRenderer.playSource(waves);
149         //
150         viewPort.addProcessor(fpp);
151 
152         inputManager.addListener(new ActionListener() {
153 
154             public void onAction(String name, boolean isPressed, float tpf) {
155                 if (isPressed) {
156                     if (name.equals("foam1")) {
157                         water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));
158                     }
159                     if (name.equals("foam2")) {
160                         water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
161                     }
162                     if (name.equals("foam3")) {
163                         water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));
164                     }
165                 }
166             }
167         }, "foam1", "foam2", "foam3");
168         inputManager.addMapping("foam1", new KeyTrigger(keyInput.KEY_1));
169         inputManager.addMapping("foam2", new KeyTrigger(keyInput.KEY_2));
170         inputManager.addMapping("foam3", new KeyTrigger(keyInput.KEY_3));
171 //        createBox();
172       //  createFire();
173     }
174     Geometry box;
175 
176     private void createBox() {
177         //creating a transluscent box
178         box = new Geometry("box", new Box(new Vector3f(0, 0, 0), 50, 50, 50));
179         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
180         mat.setColor("Color", new ColorRGBA(1.0f, 0, 0, 0.3f));
181         mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
182         //mat.getAdditionalRenderState().setDepthWrite(false);
183         //mat.getAdditionalRenderState().setDepthTest(false);
184         box.setMaterial(mat);
185         box.setQueueBucket(Bucket.Translucent);
186 
187 
188         //creating a post view port
189 //        ViewPort post=renderManager.createPostView("transpPost", cam);
190 //        post.setClearFlags(false, true, true);
191 
192 
193         box.setLocalTranslation(-600, 0, 300);
194 
195         //attaching the box to the post viewport
196         //Don't forget to updateGeometricState() the box in the simpleUpdate
197         //  post.attachScene(box);
198 
199         rootNode.attachChild(box);
200     }
201 
202     private void createFire() {
203         /** Uses Texture from jme3-test-data library! */
204         ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
205         Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
206         mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
207 
208         fire.setMaterial(mat_red);
209         fire.setImagesX(2);
210         fire.setImagesY(2); // 2x2 texture animation
211         fire.setEndColor(new ColorRGBA(1f, 0f, 0f, 1f));   // red
212         fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
213         fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0));
214         fire.setStartSize(10f);
215         fire.setEndSize(1f);
216         fire.setGravity(0, 0, 0);
217         fire.setLowLife(0.5f);
218         fire.setHighLife(1.5f);
219         fire.getParticleInfluencer().setVelocityVariation(0.3f);
220         fire.setLocalTranslation(-350, 40, 430);
221 
222         fire.setQueueBucket(Bucket.Transparent);
223         rootNode.attachChild(fire);
224     }
225 
226     private void createTerrain(Node rootNode) {
227         matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
228         matRock.setBoolean("useTriPlanarMapping", false);
229         matRock.setBoolean("WardIso", true);
230         matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
231         Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
232         Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
233         grass.setWrap(WrapMode.Repeat);
234         matRock.setTexture("DiffuseMap", grass);
235         matRock.setFloat("DiffuseMap_0_scale", 64);
236         Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
237         dirt.setWrap(WrapMode.Repeat);
238         matRock.setTexture("DiffuseMap_1", dirt);
239         matRock.setFloat("DiffuseMap_1_scale", 16);
240         Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
241         rock.setWrap(WrapMode.Repeat);
242         matRock.setTexture("DiffuseMap_2", rock);
243         matRock.setFloat("DiffuseMap_2_scale", 128);
244         Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
245         normalMap0.setWrap(WrapMode.Repeat);
246         Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
247         normalMap1.setWrap(WrapMode.Repeat);
248         Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png");
249         normalMap2.setWrap(WrapMode.Repeat);
250         matRock.setTexture("NormalMap", normalMap0);
251         matRock.setTexture("NormalMap_1", normalMap2);
252         matRock.setTexture("NormalMap_2", normalMap2);
253 
254         AbstractHeightMap heightmap = null;
255         try {
256             heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
257             heightmap.load();
258         } catch (Exception e) {
259             e.printStackTrace();
260         }
261         terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
262         List<Camera> cameras = new ArrayList<Camera>();
263         cameras.add(getCamera());
264         terrain.setMaterial(matRock);
265         terrain.setLocalScale(new Vector3f(5, 5, 5));
266         terrain.setLocalTranslation(new Vector3f(0, -30, 0));
267         terrain.setLocked(false); // unlock it so we can edit the height
268 
269         terrain.setShadowMode(ShadowMode.Receive);
270         rootNode.attachChild(terrain);
271 
272     }
273     //This part is to emulate tides, slightly varrying the height of the water plane
274     private float time = 0.0f;
275     private float waterHeight = 0.0f;
276     private float initialWaterHeight = 0.8f;
277 private boolean uw=false;
278     @Override
279     public void simpleUpdate(float tpf) {
280         super.simpleUpdate(tpf);
281         //     box.updateGeometricState();
282         time += tpf;
283         waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
284         water.setWaterHeight(initialWaterHeight + waterHeight);
285         if(water.isUnderWater() && !uw){
286 
287             waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));
288             uw=true;
289         }
290         if(!water.isUnderWater() && uw){
291             uw=false;
292              //waves.setReverbEnabled(false);
293              waves.setDryFilter(new LowPassFilter(1, 1f));
294              //waves.setDryFilter(new LowPassFilter(1,1f));
295 
296         }
297     }
298 }
299