1package jme3test.terrain; 2 3import com.jme3.app.SimpleApplication; 4import com.jme3.app.state.ScreenshotAppState; 5import com.jme3.bullet.control.CharacterControl; 6import com.jme3.material.Material; 7import com.jme3.math.ColorRGBA; 8import com.jme3.math.Vector3f; 9import com.jme3.terrain.geomipmap.TerrainGrid; 10import com.jme3.terrain.geomipmap.TerrainLodControl; 11import com.jme3.terrain.geomipmap.grid.FractalTileLoader; 12import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; 13import com.jme3.terrain.noise.ShaderUtils; 14import com.jme3.terrain.noise.basis.FilteredBasis; 15import com.jme3.terrain.noise.filter.IterativeFilter; 16import com.jme3.terrain.noise.filter.OptimizedErode; 17import com.jme3.terrain.noise.filter.PerturbFilter; 18import com.jme3.terrain.noise.filter.SmoothFilter; 19import com.jme3.terrain.noise.fractal.FractalSum; 20import com.jme3.terrain.noise.modulator.NoiseModulator; 21import com.jme3.texture.Texture; 22import com.jme3.texture.Texture.WrapMode; 23 24public class TerrainFractalGridTest extends SimpleApplication { 25 26 private Material mat_terrain; 27 private TerrainGrid terrain; 28 private float grassScale = 64; 29 private float dirtScale = 16; 30 private float rockScale = 128; 31 32 public static void main(final String[] args) { 33 TerrainFractalGridTest app = new TerrainFractalGridTest(); 34 app.start(); 35 } 36 private CharacterControl player3; 37 private FractalSum base; 38 private PerturbFilter perturb; 39 private OptimizedErode therm; 40 private SmoothFilter smooth; 41 private IterativeFilter iterate; 42 43 @Override 44 public void simpleInitApp() { 45 this.flyCam.setMoveSpeed(100f); 46 ScreenshotAppState state = new ScreenshotAppState(); 47 this.stateManager.attach(state); 48 49 // TERRAIN TEXTURE material 50 this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); 51 52 // Parameters to material: 53 // regionXColorMap: X = 1..4 the texture that should be appliad to state X 54 // regionX: a Vector3f containing the following information: 55 // regionX.x: the start height of the region 56 // regionX.y: the end height of the region 57 // regionX.z: the texture scale for the region 58 // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :) 59 // slopeColorMap: the texture to be used for cliffs, and steep mountain sites 60 // slopeTileFactor: the texture scale for slopes 61 // terrainSize: the total size of the terrain (used for scaling the texture) 62 // GRASS texture 63 Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); 64 grass.setWrap(WrapMode.Repeat); 65 this.mat_terrain.setTexture("region1ColorMap", grass); 66 this.mat_terrain.setVector3("region1", new Vector3f(15, 200, this.grassScale)); 67 68 // DIRT texture 69 Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); 70 dirt.setWrap(WrapMode.Repeat); 71 this.mat_terrain.setTexture("region2ColorMap", dirt); 72 this.mat_terrain.setVector3("region2", new Vector3f(0, 20, this.dirtScale)); 73 74 // ROCK texture 75 Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); 76 rock.setWrap(WrapMode.Repeat); 77 this.mat_terrain.setTexture("region3ColorMap", rock); 78 this.mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale)); 79 80 this.mat_terrain.setTexture("region4ColorMap", rock); 81 this.mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale)); 82 83 this.mat_terrain.setTexture("slopeColorMap", rock); 84 this.mat_terrain.setFloat("slopeTileFactor", 32); 85 86 this.mat_terrain.setFloat("terrainSize", 513); 87 88 this.base = new FractalSum(); 89 this.base.setRoughness(0.7f); 90 this.base.setFrequency(1.0f); 91 this.base.setAmplitude(1.0f); 92 this.base.setLacunarity(2.12f); 93 this.base.setOctaves(8); 94 this.base.setScale(0.02125f); 95 this.base.addModulator(new NoiseModulator() { 96 97 @Override 98 public float value(float... in) { 99 return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); 100 } 101 }); 102 103 FilteredBasis ground = new FilteredBasis(this.base); 104 105 this.perturb = new PerturbFilter(); 106 this.perturb.setMagnitude(0.119f); 107 108 this.therm = new OptimizedErode(); 109 this.therm.setRadius(5); 110 this.therm.setTalus(0.011f); 111 112 this.smooth = new SmoothFilter(); 113 this.smooth.setRadius(1); 114 this.smooth.setEffect(0.7f); 115 116 this.iterate = new IterativeFilter(); 117 this.iterate.addPreFilter(this.perturb); 118 this.iterate.addPostFilter(this.smooth); 119 this.iterate.setFilter(this.therm); 120 this.iterate.setIterations(1); 121 122 ground.addPreFilter(this.iterate); 123 124 this.terrain = new TerrainGrid("terrain", 33, 129, new FractalTileLoader(ground, 256f)); 125 126 this.terrain.setMaterial(this.mat_terrain); 127 this.terrain.setLocalTranslation(0, 0, 0); 128 this.terrain.setLocalScale(2f, 1f, 2f); 129 this.rootNode.attachChild(this.terrain); 130 131 TerrainLodControl control = new TerrainLodControl(this.terrain, this.getCamera()); 132 control.setLodCalculator(new DistanceLodCalculator(33, 2.7f)); // patch size, and a multiplier 133 this.terrain.addControl(control); 134 135 136 137 this.getCamera().setLocation(new Vector3f(0, 300, 0)); 138 139 this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); 140 141 142 } 143 144 @Override 145 public void simpleUpdate(final float tpf) { 146 } 147} 148