package net.anzix.fsz.proceduralterrain;
import net.anzix.fsz.sceneComponents.Water;
import net.anzix.fsz.sceneComponents.Sky;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.util.ReadOnlyTimer;
/**
*
* @author elcsiga
*/
public class ProceduralTerrain {
private final float farPlane = 8000.0f;
private Terrain terrain;
private Water water;
private Sky sky;
private boolean aboveWater = true;
private FogState fogState;
public void update(final ReadOnlyTimer timer, Camera camera) {
updateTerrain(timer,camera );
sky.update(timer,camera);
water.update(timer, camera);
}
protected void updateTerrain(final ReadOnlyTimer timer, Camera camera ) {
if (aboveWater && camera.getLocation().getY() < water.getWaterHeight()) {
fogState.setStart(-1000f);
fogState.setEnd(farPlane / 10f);
fogState.setColor(new ColorRGBA(0.0f, 0.0f, 0.1f, 1.0f));
aboveWater = false;
} else if (!aboveWater && camera.getLocation().getY() >= water.getWaterHeight()) {
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
aboveWater = true;
}
}
private final Vector3 heightCalc = new Vector3();
private float getHeightAt(final double x, final double z) {
heightCalc.set(x, 0, z);
terrain.worldToLocal(heightCalc, heightCalc);
return terrain.getClipmaps().get(0).getCache().getSubHeight(heightCalc.getXf(), heightCalc.getZf());
}
private NominalHeightGenerator heightGenerator = new NominalHeightGenerator();
private Vector3 getTerrainSurfacePoint(final double x, final double z) {
return new Vector3(x,heightGenerator.getHeight(x, z),z);
}
protected void initCamera(Camera camera) {
camera.setLocation(new Vector3(0, 1, 0));
camera.lookAt(new Vector3(1, 1, 1), Vector3.UNIT_Y);
camera.setFrustumPerspective(70.0, (float) camera.getWidth() / camera.getHeight(), 1.0f, farPlane);
}
protected void initFog( Node root) {
fogState = new FogState();
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
fogState.setDensityFunction(DensityFunction.Linear);
root.setRenderState(fogState);
}
public void init(Camera camera, Node root) {
initCamera(camera);
initFog(root);
try {
//terrain = new TerrainBuilder(new ProceduralTerrainDataProvider(), camera).build();
/*WireframeState wireframeState = new WireframeState();
wireframeState.setEnabled(true);
terrain.setRenderState(wireframeState);*/
// terrain.setVertexShader(java.net.URL("shaders/fsTerrain.vert"));
//terrain.setPixelShader(java.net.URL("shaders/fsTerrain.frag"));
//terrain.setVertexShader(ResourceLocatorTool.getClassPathResource(Terrain.class,
// "shaders/fsTerrain.vert"));
//terrain.setPixelShader(ResourceLocatorTool.getClassPathResource(Terrain.class,
// "shaders/fsTerrain.frag"));
//terrain.setVertexShader( new UrlInputSupplier(ResourceLocatorTool.getClassPathResource(Terrain.class,
// "shaders/fsTerrain.vert")));
//terrain.setPixelShader( new UrlInputSupplier(ResourceLocatorTool.getClassPathResource(Terrain.class,
// "shaders/fsTerrain.frag")));
root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(terrain);
sky = new Sky(0.0f);
reflectedNode.attachChild(sky);
//water = new Water(camera, reflectedNode, sky, farPlane,0);
root.attachChild(reflectedNode);
root.attachChild(water);
//TEST BILBOARD FOREST
Forest forest = new Forest();
int counter = 0;
while (counter < 1000) {
double x = Math.random() * 200.0 - 100.0;
double y = Math.random() * 200.0 - 100.0;
double width = Math.random() * 5.0 + 2.0;
double height = Math.random() * 10.0 + 2.0;
Vector3 v = getTerrainSurfacePoint(x,y);
if (v.getY() > 0.0) {
forest.attachChild(new BillboardTree(v,width,height));
counter ++;
}
}
root.attachChild(forest);
root.attachChild (new ObjTree());
}
}