Home | History | Annotate | Download | only in water
      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 
     54     public static void main(String[] args) {
     55         TestPostWater app = new TestPostWater();
     56         app.start();
     57     }
     58 
     59     @Override
     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