2014-03-21 02:32:11 +01:00

357 lines
13 KiB
Java

/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.terrain;
import com.jme3.app.SimpleApplication;
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.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Sphere;
import com.jme3.terrain.ProgressMonitor;
import com.jme3.terrain.Terrain;
import com.jme3.terrain.geomipmap.MultiTerrainLodControl;
import com.jme3.terrain.geomipmap.NeighbourFinder;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import java.util.List;
/**
* Demonstrates the NeighbourFinder interface for TerrainQuads,
* allowing you to tile terrains together without having to use
* TerrainGrid. It also introduces the MultiTerrainLodControl that
* will seam the edges of all the terrains supplied.
*
* @author sploreg
*/
public class TerrainTestTile extends SimpleApplication {
private TiledTerrain terrain;
Material matTerrain;
Material matWire;
boolean wireframe = true;
boolean triPlanar = false;
boolean wardiso = false;
boolean minnaert = false;
protected BitmapText hintText;
private float grassScale = 256;
public static void main(String[] args) {
TerrainTestTile app = new TerrainTestTile();
app.start();
}
@Override
public void simpleInitApp() {
loadHintText();
setupKeys();
// WIREFRAME material
matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
matWire.getAdditionalRenderState().setWireframe(true);
matWire.setColor("Color", ColorRGBA.Green);
terrain = new TiledTerrain();
rootNode.attachChild(terrain);
DirectionalLight light = new DirectionalLight();
light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
rootNode.addLight(light);
AmbientLight ambLight = new AmbientLight();
ambLight.setColor(new ColorRGBA(1f, 1f, 0.8f, 0.2f));
rootNode.addLight(ambLight);
cam.setLocation(new Vector3f(0, 256, 0));
cam.lookAtDirection(new Vector3f(0, -1, -1).normalizeLocal(), Vector3f.UNIT_Y);
Sphere s = new Sphere(12, 12, 3);
Geometry g = new Geometry("marker");
g.setMesh(s);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Red);
g.setMaterial(mat);
g.setLocalTranslation(0, -100, 0);
rootNode.attachChild(g);
Geometry g2 = new Geometry("marker");
g2.setMesh(s);
mat.setColor("Color", ColorRGBA.Red);
g2.setMaterial(mat);
g2.setLocalTranslation(10, -100, 0);
rootNode.attachChild(g2);
Geometry g3 = new Geometry("marker");
g3.setMesh(s);
mat.setColor("Color", ColorRGBA.Red);
g3.setMaterial(mat);
g3.setLocalTranslation(0, -100, 10);
rootNode.attachChild(g3);
}
public void loadHintText() {
hintText = new BitmapText(guiFont, false);
hintText.setLocalTranslation(0, getCamera().getHeight(), 0);
hintText.setText("Hit 'T' to toggle wireframe");
guiNode.attachChild(hintText);
}
private void setupKeys() {
flyCam.setMoveSpeed(100);
inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(actionListener, "wireframe");
}
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean pressed, float tpf) {
if (name.equals("wireframe") && !pressed) {
wireframe = !wireframe;
if (!wireframe) {
terrain.setMaterial(matWire);
} else {
terrain.setMaterial(matTerrain);
}
}
}
};
/**
* A sample class (node in this case) that demonstrates
* the use of NeighbourFinder.
* It just links up the left,right,top,bottom TerrainQuads
* so LOD can work.
* It does not implement many of the Terrain interface's methods,
* you will want to do that for your own implementations.
*/
private class TiledTerrain extends Node implements Terrain, NeighbourFinder {
private TerrainQuad terrain1;
private TerrainQuad terrain2;
private TerrainQuad terrain3;
private TerrainQuad terrain4;
TiledTerrain() {
// TERRAIN TEXTURE material
matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
matTerrain.setBoolean("useTriPlanarMapping", false);
matTerrain.setBoolean("WardIso", true);
matTerrain.setFloat("Shininess", 0);
// GRASS texture
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
matTerrain.setTexture("DiffuseMap", grass);
matTerrain.setFloat("DiffuseMap_0_scale", grassScale);
// CREATE THE TERRAIN
terrain1 = new TerrainQuad("terrain 1", 65, 513, null);
terrain1.setMaterial(matTerrain);
terrain1.setLocalTranslation(-256, -100, -256);
terrain1.setLocalScale(1f, 1f, 1f);
this.attachChild(terrain1);
terrain2 = new TerrainQuad("terrain 2", 65, 513, null);
terrain2.setMaterial(matTerrain);
terrain2.setLocalTranslation(-256, -100, 256);
terrain2.setLocalScale(1f, 1f, 1f);
this.attachChild(terrain2);
terrain3 = new TerrainQuad("terrain 3", 65, 513, null);
terrain3.setMaterial(matTerrain);
terrain3.setLocalTranslation(256, -100, -256);
terrain3.setLocalScale(1f, 1f, 1f);
this.attachChild(terrain3);
terrain4 = new TerrainQuad("terrain 4", 65, 513, null);
terrain4.setMaterial(matTerrain);
terrain4.setLocalTranslation(256, -100, 256);
terrain4.setLocalScale(1f, 1f, 1f);
this.attachChild(terrain4);
terrain1.setNeighbourFinder(this);
terrain2.setNeighbourFinder(this);
terrain3.setNeighbourFinder(this);
terrain4.setNeighbourFinder(this);
MultiTerrainLodControl lodControl = new MultiTerrainLodControl(getCamera());
lodControl.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
lodControl.addTerrain(terrain1);
lodControl.addTerrain(terrain2);
lodControl.addTerrain(terrain3);// order of these seems to matter
lodControl.addTerrain(terrain4);
this.addControl(lodControl);
}
/**
* 1 3
* 2 4
*/
public TerrainQuad getRightQuad(TerrainQuad center) {
//System.out.println("lookup neighbour");
if (center == terrain1)
return terrain3;
if (center == terrain2)
return terrain4;
return null;
}
/**
* 1 3
* 2 4
*/
public TerrainQuad getLeftQuad(TerrainQuad center) {
//System.out.println("lookup neighbour");
if (center == terrain3)
return terrain1;
if (center == terrain4)
return terrain2;
return null;
}
/**
* 1 3
* 2 4
*/
public TerrainQuad getTopQuad(TerrainQuad center) {
//System.out.println("lookup neighbour");
if (center == terrain2)
return terrain1;
if (center == terrain4)
return terrain3;
return null;
}
/**
* 1 3
* 2 4
*/
public TerrainQuad getDownQuad(TerrainQuad center) {
//System.out.println("lookup neighbour");
if (center == terrain1)
return terrain2;
if (center == terrain3)
return terrain4;
return null;
}
public float getHeight(Vector2f xz) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public Vector3f getNormal(Vector2f xz) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public float getHeightmapHeight(Vector2f xz) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public void setHeight(Vector2f xzCoordinate, float height) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public void setHeight(List<Vector2f> xz, List<Float> height) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public void adjustHeight(Vector2f xzCoordinate, float delta) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public void adjustHeight(List<Vector2f> xz, List<Float> height) {
// you will have to offset the coordinate for each terrain, to center on it
throw new UnsupportedOperationException("Not supported yet.");
}
public float[] getHeightMap() {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getMaxLod() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void setLocked(boolean locked) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void generateEntropy(ProgressMonitor monitor) {
throw new UnsupportedOperationException("Not supported yet.");
}
public Material getMaterial() {
throw new UnsupportedOperationException("Not supported yet.");
}
public Material getMaterial(Vector3f worldLocation) {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getTerrainSize() {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getNumMajorSubdivisions() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}