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