Переглянути джерело

Merge pull request #2418 from capdevon/capdevon-TestPostWater

jme3-examples: TestPostWater code cleanup
Ryan McDonough 4 місяців тому
батько
коміт
2fa2101794
1 змінених файлів з 171 додано та 158 видалено
  1. 171 158
      jme3-examples/src/main/java/jme3test/water/TestPostWater.java

+ 171 - 158
jme3-examples/src/main/java/jme3test/water/TestPostWater.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2022 jMonkeyEngine
+ * Copyright (c) 2009-2025 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@ import com.jme3.font.BitmapText;
 import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
+import com.jme3.input.controls.Trigger;
 import com.jme3.light.AmbientLight;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
@@ -55,7 +56,9 @@ import com.jme3.post.filters.LightScatteringFilter;
 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
+import com.jme3.terrain.geomipmap.TerrainLodControl;
 import com.jme3.terrain.geomipmap.TerrainQuad;
+import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
 import com.jme3.terrain.heightmap.AbstractHeightMap;
 import com.jme3.terrain.heightmap.ImageBasedHeightMap;
 import com.jme3.texture.Texture;
@@ -66,18 +69,12 @@ import com.jme3.util.SkyFactory.EnvMapType;
 import com.jme3.water.WaterFilter;
 
 /**
- * test
- *
  * @author normenhansen
  */
 public class TestPostWater extends SimpleApplication {
 
-    final private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
+    private final Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
     private WaterFilter water;
-    private AudioNode waves;
-    final private LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1);
-    final private Filter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f);
-    private boolean useDryFilter = true;
 
     public static void main(String[] args) {
         TestPostWater app = new TestPostWater();
@@ -87,173 +84,154 @@ public class TestPostWater extends SimpleApplication {
     @Override
     public void simpleInitApp() {
 
-        setDisplayFps(false);
-        setDisplayStatView(false);
-        
         Node mainScene = new Node("Main Scene");
         rootNode.attachChild(mainScene);
 
+        configureCamera();
+        createSky(mainScene);
         createTerrain(mainScene);
+        createLights(mainScene);
+        createWaterFilter();
+        setupPostFilters();
+        addAudioClip();
+        setupUI();
+        registerInputMappings();
+    }
+
+    private void configureCamera() {
+        flyCam.setMoveSpeed(50f);
+        cam.setLocation(new Vector3f(-370.31592f, 182.04016f, 196.81192f));
+        cam.setRotation(new Quaternion(0.015302252f, 0.9304095f, -0.039101653f, 0.3641086f));
+        cam.setFrustumFar(2000);
+    }
+
+    private void createLights(Node mainScene) {
         DirectionalLight sun = new DirectionalLight();
         sun.setDirection(lightDir);
-        sun.setColor(ColorRGBA.White.clone().multLocal(1f));
         mainScene.addLight(sun);
-        
+
         AmbientLight al = new AmbientLight();
         al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f));
         mainScene.addLight(al);
-        
-        flyCam.setMoveSpeed(50);
+    }
 
-        //cam.setLocation(new Vector3f(-700, 100, 300));
-        //cam.setRotation(new Quaternion().fromAngleAxis(0.5f, Vector3f.UNIT_Z));
-//        cam.setLocation(new Vector3f(-327.21957f, 61.6459f, 126.884346f));
-//        cam.setRotation(new Quaternion(0.052168474f, 0.9443102f, -0.18395276f, 0.2678024f));
+    private void createSky(Node mainScene) {
+        Spatial sky = SkyFactory.createSky(assetManager,
+                "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap);
+        sky.setShadowMode(ShadowMode.Off);
+        mainScene.attachChild(sky);
+    }
 
+    private void setupUI() {
+        setText(0, 50, "1 - Set Foam Texture to Foam.jpg");
+        setText(0, 80, "2 - Set Foam Texture to Foam2.jpg");
+        setText(0, 110, "3 - Set Foam Texture to Foam3.jpg");
+        setText(0, 140, "4 - Turn Dry Filter under water On/Off");
+        setText(0, 240, "PgUp - Larger Reflection Map");
+        setText(0, 270, "PgDn - Smaller Reflection Map");
+    }
 
-        cam.setLocation(new Vector3f(-370.31592f, 182.04016f, 196.81192f));
-        cam.setRotation(new Quaternion(0.015302252f, 0.9304095f, -0.039101653f, 0.3641086f));
+    private void setText(int x, int y, String text) {
+        BitmapText bmp = new BitmapText(guiFont);
+        bmp.setText(text);
+        bmp.setLocalTranslation(x, cam.getHeight() - y, 0);
+        bmp.setColor(ColorRGBA.Red);
+        guiNode.attachChild(bmp);
+    }
 
+    private void registerInputMappings() {
+        addMapping("foam1", new KeyTrigger(KeyInput.KEY_1));
+        addMapping("foam2", new KeyTrigger(KeyInput.KEY_2));
+        addMapping("foam3", new KeyTrigger(KeyInput.KEY_3));
+        addMapping("dryFilter", new KeyTrigger(KeyInput.KEY_4));
+        addMapping("upRM", new KeyTrigger(KeyInput.KEY_PGUP));
+        addMapping("downRM", new KeyTrigger(KeyInput.KEY_PGDN));
+    }
 
+    private void addMapping(String mappingName, Trigger... triggers) {
+        inputManager.addMapping(mappingName, triggers);
+        inputManager.addListener(actionListener, mappingName);
+    }
 
+    private final ActionListener actionListener = new ActionListener() {
+        @Override
+        public void onAction(String name, boolean isPressed, float tpf) {
+            if (!isPressed) return;
 
-        Spatial sky = SkyFactory.createSky(assetManager, 
-                "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap);
-        sky.setLocalScale(350);
+            if (name.equals("foam1")) {
+                water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));
 
-        mainScene.attachChild(sky);
-        cam.setFrustumFar(4000);
+            } else if (name.equals("foam2")) {
+                water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
 
-        //Water Filter
-        water = new WaterFilter(rootNode, lightDir);
-        water.setWaterColor(new ColorRGBA().setAsSrgb(0.0078f, 0.3176f, 0.5f, 1.0f));
-        water.setDeepWaterColor(new ColorRGBA().setAsSrgb(0.0039f, 0.00196f, 0.145f, 1.0f));
-        water.setUnderWaterFogDistance(80);
-        water.setWaterTransparency(0.12f);
-        water.setFoamIntensity(0.4f);        
-        water.setFoamHardness(0.3f);
-        water.setFoamExistence(new Vector3f(0.8f, 8f, 1f));
-        water.setReflectionDisplace(50);
-        water.setRefractionConstant(0.25f);
-        water.setColorExtinction(new Vector3f(30, 50, 70));
-        water.setCausticsIntensity(0.4f);        
-        water.setWaveScale(0.003f);
-        water.setMaxAmplitude(2f);
-        water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
-        water.setRefractionStrength(0.2f);
-        water.setWaterHeight(initialWaterHeight);
-        
-        //Bloom Filter
-        BloomFilter bloom = new BloomFilter();        
+            } else if (name.equals("foam3")) {
+                water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));
+
+            } else if (name.equals("upRM")) {
+                water.setReflectionMapSize(Math.min(water.getReflectionMapSize() * 2, 4096));
+                System.out.println("Reflection map size : " + water.getReflectionMapSize());
+
+            } else if (name.equals("downRM")) {
+                water.setReflectionMapSize(Math.max(water.getReflectionMapSize() / 2, 32));
+                System.out.println("Reflection map size : " + water.getReflectionMapSize());
+
+            } else if (name.equals("dryFilter")) {
+                useDryFilter = !useDryFilter;
+            }
+        }
+    };
+
+    private void setupPostFilters() {
+        BloomFilter bloom = new BloomFilter();
         bloom.setExposurePower(55);
         bloom.setBloomIntensity(1.0f);
-        
-        //Light Scattering Filter
+
         LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300));
-        lsf.setLightDensity(0.5f);   
-        
-        //Depth of field Filter
+        lsf.setLightDensity(0.5f);
+
         DepthOfFieldFilter dof = new DepthOfFieldFilter();
         dof.setFocusDistance(0);
         dof.setFocusRange(100);
-        
+
         FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
-        
         fpp.addFilter(water);
         fpp.addFilter(bloom);
         fpp.addFilter(dof);
         fpp.addFilter(lsf);
         fpp.addFilter(new FXAAFilter());
-        
-//      fpp.addFilter(new TranslucentBucketFilter());
+
         int numSamples = getContext().getSettings().getSamples();
         if (numSamples > 0) {
             fpp.setNumSamples(numSamples);
         }
-
-        
-        uw = cam.getLocation().y < waterHeight;
-
-        waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg",
-                DataType.Buffer);
-        waves.setLooping(true);
-        updateAudio();
-        audioRenderer.playSource(waves);
-        //  
         viewPort.addProcessor(fpp);
+    }
 
-        setText(0, 50, "1 - Set Foam Texture to Foam.jpg");
-        setText(0, 80, "2 - Set Foam Texture to Foam2.jpg");
-        setText(0, 110, "3 - Set Foam Texture to Foam3.jpg");
-        setText(0, 140, "4 - Turn Dry Filter under water On/Off");
-        setText(0, 240, "PgUp - Larger Reflection Map");
-        setText(0, 270, "PgDn - Smaller Reflection Map");
-
-        inputManager.addListener(new ActionListener() {
-            @Override
-            public void onAction(String name, boolean isPressed, float tpf) {
-                if (isPressed) {
-                    if (name.equals("foam1")) {
-                        water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam.jpg"));
-                    }
-                    if (name.equals("foam2")) {
-                        water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
-                    }
-                    if (name.equals("foam3")) {
-                        water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam3.jpg"));
-                    }
-
-                    if (name.equals("upRM")) {
-                        water.setReflectionMapSize(Math.min(water.getReflectionMapSize() * 2, 4096));
-                        System.out.println("Reflection map size : " + water.getReflectionMapSize());
-                    }
-                    if (name.equals("downRM")) {
-                        water.setReflectionMapSize(Math.max(water.getReflectionMapSize() / 2, 32));
-                        System.out.println("Reflection map size : " + water.getReflectionMapSize());
-                    }
-                    if (name.equals("dryFilter")) {
-                        useDryFilter = !useDryFilter; 
-                    }
-                }
-            }
-        }, "foam1", "foam2", "foam3", "upRM", "downRM", "dryFilter");
-        inputManager.addMapping("foam1", new KeyTrigger(KeyInput.KEY_1));
-        inputManager.addMapping("foam2", new KeyTrigger(KeyInput.KEY_2));
-        inputManager.addMapping("foam3", new KeyTrigger(KeyInput.KEY_3));
-        inputManager.addMapping("dryFilter", new KeyTrigger(KeyInput.KEY_4));
-        inputManager.addMapping("upRM", new KeyTrigger(KeyInput.KEY_PGUP));
-        inputManager.addMapping("downRM", new KeyTrigger(KeyInput.KEY_PGDN));
+    private void createWaterFilter() {
+        //Water Filter
+        water = new WaterFilter(rootNode, lightDir);
+        water.setWaterColor(new ColorRGBA().setAsSrgb(0.0078f, 0.3176f, 0.5f, 1.0f));
+        water.setDeepWaterColor(new ColorRGBA().setAsSrgb(0.0039f, 0.00196f, 0.145f, 1.0f));
+        water.setUnderWaterFogDistance(80);
+        water.setWaterTransparency(0.12f);
+        water.setFoamIntensity(0.4f);
+        water.setFoamHardness(0.3f);
+        water.setFoamExistence(new Vector3f(0.8f, 8f, 1f));
+        water.setReflectionDisplace(50);
+        water.setRefractionConstant(0.25f);
+        water.setColorExtinction(new Vector3f(30, 50, 70));
+        water.setCausticsIntensity(0.4f);
+        water.setWaveScale(0.003f);
+        water.setMaxAmplitude(2f);
+        water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
+        water.setRefractionStrength(0.2f);
+        water.setWaterHeight(initialWaterHeight);
     }
 
-    private void createTerrain(Node rootNode) {
-        Material matRock = new Material(assetManager,
-                "Common/MatDefs/Terrain/TerrainLighting.j3md");
-        matRock.setBoolean("useTriPlanarMapping", false);
-        matRock.setBoolean("WardIso", true);
-        matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
-        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
-        Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
-        grass.setWrap(WrapMode.Repeat);
-        matRock.setTexture("DiffuseMap", grass);
-        matRock.setFloat("DiffuseMap_0_scale", 64);
-        Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
-        dirt.setWrap(WrapMode.Repeat);
-        matRock.setTexture("DiffuseMap_1", dirt);
-        matRock.setFloat("DiffuseMap_1_scale", 16);
-        Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
-        rock.setWrap(WrapMode.Repeat);
-        matRock.setTexture("DiffuseMap_2", rock);
-        matRock.setFloat("DiffuseMap_2_scale", 128);
-        Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
-        normalMap0.setWrap(WrapMode.Repeat);
-        Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
-        normalMap1.setWrap(WrapMode.Repeat);
-        Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png");
-        normalMap2.setWrap(WrapMode.Repeat);
-        matRock.setTexture("NormalMap", normalMap0);
-        matRock.setTexture("NormalMap_1", normalMap1);
-        matRock.setTexture("NormalMap_2", normalMap2);
+    private void createTerrain(Node mainScene) {
+        Material matRock = createTerrainMaterial();
 
+        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
         AbstractHeightMap heightmap = null;
         try {
             heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
@@ -261,51 +239,86 @@ public class TestPostWater extends SimpleApplication {
         } catch (Exception e) {
             e.printStackTrace();
         }
-        TerrainQuad terrain
-                = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
+
+        int patchSize = 64;
+        int totalSize = 512;
+        TerrainQuad terrain = new TerrainQuad("terrain", patchSize + 1, totalSize + 1, heightmap.getHeightMap());
+        TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
+        control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier
+        terrain.addControl(control);
         terrain.setMaterial(matRock);
-        terrain.setLocalScale(new Vector3f(5, 5, 5));
+
         terrain.setLocalTranslation(new Vector3f(0, -30, 0));
-        terrain.setLocked(false); // unlock it so we can edit the height
+        terrain.setLocalScale(new Vector3f(5, 5, 5));
 
         terrain.setShadowMode(ShadowMode.Receive);
-        rootNode.attachChild(terrain);
+        mainScene.attachChild(terrain);
+    }
+
+    private Material createTerrainMaterial() {
+        Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
+        matRock.setBoolean("useTriPlanarMapping", false);
+        matRock.setBoolean("WardIso", true);
+        matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
+
+        setTexture("Textures/Terrain/splat/grass.jpg", matRock, "DiffuseMap");
+        setTexture("Textures/Terrain/splat/dirt.jpg", matRock, "DiffuseMap_1");
+        setTexture("Textures/Terrain/splat/road.jpg", matRock, "DiffuseMap_2");
+        matRock.setFloat("DiffuseMap_0_scale", 64);
+        matRock.setFloat("DiffuseMap_1_scale", 16);
+        matRock.setFloat("DiffuseMap_2_scale", 128);
+
+        setTexture("Textures/Terrain/splat/grass_normal.jpg", matRock, "NormalMap");
+        setTexture("Textures/Terrain/splat/dirt_normal.png", matRock, "NormalMap_1");
+        setTexture("Textures/Terrain/splat/road_normal.png", matRock, "NormalMap_2");
 
+        return matRock;
     }
-    //This part is to emulate tides, slightly varying the height of the water plane
+
+    private void setTexture(String texture, Material mat, String param) {
+        Texture tex = assetManager.loadTexture(texture);
+        tex.setWrap(WrapMode.Repeat);
+        mat.setTexture(param, tex);
+    }
+
+    // This part is to emulate tides, slightly varying the height of the water plane
     private float time = 0.0f;
     private float waterHeight = 0.0f;
-    final private float initialWaterHeight = 90f;//0.8f;
-    private boolean uw = false;
+    private final float initialWaterHeight = 90f;
+    private boolean underWater = false;
+
+    private AudioNode waves;
+    private final LowPassFilter aboveWaterAudioFilter = new LowPassFilter(1, 1);
+    private final LowPassFilter underWaterAudioFilter = new LowPassFilter(0.5f, 0.1f);
+    private boolean useDryFilter = true;
 
     @Override
     public void simpleUpdate(float tpf) {
-        super.simpleUpdate(tpf);
-        //     box.updateGeometricState();
         time += tpf;
         waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;
         water.setWaterHeight(initialWaterHeight + waterHeight);
-        uw = water.isUnderWater();
+        underWater = water.isUnderWater();
         updateAudio();
     }
-    
-    protected void setText(int x, int y, String text) {
-        BitmapText txt2 = new BitmapText(guiFont);
-        txt2.setText(text);
-        txt2.setLocalTranslation(x, cam.getHeight() - y, 0);
-        txt2.setColor(ColorRGBA.Red);
-        guiNode.attachChild(txt2);
+
+    private void addAudioClip() {
+        underWater = cam.getLocation().y < waterHeight;
+
+        waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", DataType.Buffer);
+        waves.setLooping(true);
+        updateAudio();
+        waves.play();
     }
 
     /**
      * Update the audio settings (dry filter and reverb)
-     * based on boolean fields ({@code uw} and {@code useDryFilter}).
+     * based on boolean fields ({@code underWater} and {@code useDryFilter}).
      */
-    protected void updateAudio() {
+    private void updateAudio() {
         Filter newDryFilter;
         if (!useDryFilter) {
             newDryFilter = null;
-        } else if (uw) {
+        } else if (underWater) {
             newDryFilter = underWaterAudioFilter;
         } else {
             newDryFilter = aboveWaterAudioFilter;
@@ -316,11 +329,11 @@ public class TestPostWater extends SimpleApplication {
             waves.setDryFilter(newDryFilter);
         }
 
-        boolean newReverbEnabled = !uw;
+        boolean newReverbEnabled = !underWater;
         boolean oldReverbEnabled = waves.isReverbEnabled();
         if (oldReverbEnabled != newReverbEnabled) {
             System.out.println("reverb enabled : " + newReverbEnabled);
             waves.setReverbEnabled(newReverbEnabled);
         }
     }
-}
+}