* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
_canvas.setTitle("Terrain Example");
final Camera cam = _canvas.getCanvasRenderer().getCamera();
cam.setLocation(new Vector3(440, 215, 275));
cam.lookAt(new Vector3(450, 140, 360), Vector3.UNIT_Y);
cam.setFrustumPerspective(70.0, (float) cam.getWidth() / cam.getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
terrainCamera = new Camera(cam);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
terrain.setPixelShader(new UrlInputSupplier(ResourceLocatorTool
.getClassPathResource(ShadowedTerrainExample.class,
"com/ardor3d/extension/terrain/shadowedGeometryClipmapShaderPCF.frag")));
terrain.reloadShader();
_root.attachChild(terrain);
} catch (final Exception e) {
logger.log(Level.SEVERE, "Problem setting up terrain...", e);
System.exit(1);
}
// Initialize PSSM shadows
_pssmPass = new ParallelSplitShadowMapPass(light, 1024, 4);
_pssmPass.setFiltering(Filter.Pcf);
_pssmPass.setRenderShadowedScene(false);
_pssmPass.setKeepMainShader(true);
_pssmPass.setMaxShadowDistance(750); // XXX: Tune this
// _pssmPass.setMinimumLightDistance(500); // XXX: Tune this
_pssmPass.setUseSceneTexturing(false);
_pssmPass.setUseObjectCullFace(false);
// _pssmPass.setDrawDebug(true);
final Node occluders = setupOccluders();
_root.attachChild(occluders);
// TODO: could we use the shadow variable in scenehints here??
// Add objects that will get shadowed through overlay render
_pssmPass.add(occluders);
// Add terrain in as bounds receiver as well, since it's not in the overlay list
_pssmPass.addBoundsReceiver(terrain);
// Add our occluders that will produce shadows
_pssmPass.addOccluder(occluders);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.C), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUpdateMainCamera(!_pssmPass.isUpdateMainCamera());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
System.out.println("camera location: " + cam.getLocation());
System.out.println("camera direction: " + cam.getDirection());
}
}));
}