A sum of sine waves, in 2D directions, will control the terrain height in the 3rd dimension, here.
The variable heightmap is a float array of size 512 by 512. The for loops are used to initialize it.
// *** 1. Start (variables) final int IMG_SIZE = 512; float[] heightmap = new float[IMG_SIZE*IMG_SIZE]; int i,j; // x,y final int NX = 400; // periods in x final int NY = 300; // and y float valx,valy; // x,y contributions // *** 1. End
First, we can find valx, which is the first sine contribution.
// *** 2. Start (valx) for (i = 0; i<IMG_SIZE; i++) { valx = 127.5f*FastMath.sin(2*PI*i/NX)+127.5f; // *** 2. End
In the inner for loop, we find valy, which is the second sine contribution.
// *** 3. Start (valy) for (j = 0; j<IMG_SIZE; j++) { valy = 127.5f*FastMath.sin(2*PI*j/NY)+127.5f; // *** 3. End
For the heightmap initialization, the 2 dimensions are mapped to 1 dimension, and a linear combination of valx and valy is used.
// *** 4. Start (heightmap) heightmap[i+j*IMG_SIZE] = (0.25f*valx + 0.75f*valy); // *** 4. End
// JMonkey49.java package mygame; import com.jme3.app.SimpleApplication; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Vector3f; import com.jme3.renderer.RenderManager; import com.jme3.terrain.geomipmap.TerrainQuad; import com.jme3.texture.Texture; public class JMonkey49 extends SimpleApplication { public static void main(String[] args) { JMonkey49 app = new JMonkey49(); app.start(); } private TerrainQuad terrain; Material materialTerrain; final float PI = FastMath.PI; @Override public void simpleInitApp() { viewPort.setBackgroundColor(ColorRGBA.LightGray); setDisplayFps(false); setDisplayStatView(false); flyCam.setMoveSpeed(50); // fast camera // Terrain materialTerrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); materialTerrain.setTexture("Alpha", assetManager. loadTexture("Textures/Ex49/redgreenblue.png")); Texture burlwood = assetManager.loadTexture( "Textures/Ex49/burlwood.png"); burlwood.setWrap(Texture.WrapMode.Repeat); materialTerrain.setTexture("Tex1", burlwood); materialTerrain.setFloat("Tex1Scale", 64); Texture craters = assetManager.loadTexture( "Textures/Ex49/craters.png"); craters.setWrap(Texture.WrapMode.Repeat); materialTerrain.setTexture("Tex2", craters); materialTerrain.setFloat("Tex2Scale", 64); Texture road = assetManager.loadTexture( "Textures/Ex49/road.png"); road.setWrap(Texture.WrapMode.Repeat); materialTerrain.setTexture("Tex3", road); materialTerrain.setFloat("Tex3Scale", 64); // *** 1. Start (variables) final int IMG_SIZE = 512; float[] heightmap = new float[IMG_SIZE*IMG_SIZE]; int i,j; // x,y final int NX = 400; // periods in x final int NY = 300; // and y float valx,valy; // x,y contributions // *** 1. End // *** 2. Start (valx) for (i = 0; i<IMG_SIZE; i++) { valx = 127.5f*FastMath.sin(2*PI*i/NX)+127.5f; // *** 2. End // *** 3. Start (valy) for (j = 0; j<IMG_SIZE; j++) { valy = 127.5f*FastMath.sin(2*PI*j/NY)+127.5f; // *** 3. End // *** 4. Start (heightmap) heightmap[i+j*IMG_SIZE] = (0.25f*valx + 0.75f*valy); // *** 4. End } } terrain = new TerrainQuad("terrain", 129, 513, // patch + 1, height size + 1 heightmap); // float array terrain.setMaterial(materialTerrain); terrain.setLocalScale(.1f, .1f, .1f); float ang = 35*FastMath.DEG_TO_RAD; terrain.rotate(2*ang, 0, ang); rootNode.attachChild(terrain); cam.setLocation(new Vector3f(0,0,150)); // far away } @Override public void simpleUpdate(float tpf) { } @Override public void simpleRender(RenderManager rm) { } }
Output:
No comments:
Post a Comment