Sep 11, 2014

49. Sine terrain

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