159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage jme3test.terrain;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.SimpleApplication;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.state.ScreenshotAppState;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.plugins.HttpZipLocator;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.plugins.ZipLocator;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.BulletAppState;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.control.CharacterControl;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.control.RigidBodyControl;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.KeyInput;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.controls.ActionListener;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.controls.KeyTrigger;
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.light.AmbientLight;
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.light.DirectionalLight;
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.Material;
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.ColorRGBA;
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector2f;
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.Camera;
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Geometry;
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Node;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.debug.Arrow;
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainGrid;
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainGridListener;
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainLodControl;
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainQuad;
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.grid.FractalTileLoader;
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture.WrapMode;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.File;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.ShaderUtils;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.basis.FilteredBasis;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.filter.IterativeFilter;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.filter.OptimizedErode;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.filter.PerturbFilter;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.filter.SmoothFilter;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.fractal.FractalSum;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.noise.modulator.NoiseModulator;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class TerrainGridAlphaMapTest extends SimpleApplication {
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private TerrainGrid terrain;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float grassScale = 64;
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float dirtScale = 16;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float rockScale = 128;
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean usePhysics = false;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static void main(final String[] args) {
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TerrainGridAlphaMapTest app = new TerrainGridAlphaMapTest();
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        app.start();
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private CharacterControl player3;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private FractalSum base;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private PerturbFilter perturb;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private OptimizedErode therm;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private SmoothFilter smooth;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private IterativeFilter iterate;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private Material material;
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private Material matWire;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void simpleInitApp() {
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        DirectionalLight sun = new DirectionalLight();
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sun.setColor(ColorRGBA.White);
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        sun.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        rootNode.addLight(sun);
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AmbientLight al = new AmbientLight();
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        al.setColor(ColorRGBA.White.mult(1.3f));
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        rootNode.addLight(al);
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        File file = new File("TerrainGridTestData.zip");
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (!file.exists()) {
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/TerrainGridTestData.zip", HttpZipLocator.class);
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assetManager.registerLocator("TerrainGridTestData.zip", ZipLocator.class);
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.flyCam.setMoveSpeed(100f);
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ScreenshotAppState state = new ScreenshotAppState();
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.stateManager.attach(state);
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // TERRAIN TEXTURE material
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setBoolean("useTriPlanarMapping", false);
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //material.setBoolean("isTerrainGrid", true);
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setFloat("Shininess", 0.0f);
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // GRASS texture
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        grass.setWrap(WrapMode.Repeat);
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setTexture("DiffuseMap", grass);
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setFloat("DiffuseMap_0_scale", grassScale);
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // DIRT texture
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dirt.setWrap(WrapMode.Repeat);
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setTexture("DiffuseMap_1", dirt);
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setFloat("DiffuseMap_1_scale", dirtScale);
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // ROCK texture
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        rock.setWrap(WrapMode.Repeat);
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setTexture("DiffuseMap_2", rock);
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        material.setFloat("DiffuseMap_2_scale", rockScale);
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // WIREFRAME material
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        matWire.getAdditionalRenderState().setWireframe(true);
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        matWire.setColor("Color", ColorRGBA.Green);
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base = new FractalSum();
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setRoughness(0.7f);
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setFrequency(1.0f);
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setAmplitude(1.0f);
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setLacunarity(2.12f);
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setOctaves(8);
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.setScale(0.02125f);
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.base.addModulator(new NoiseModulator() {
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            @Override
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            public float value(float... in) {
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1);
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        });
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        FilteredBasis ground = new FilteredBasis(this.base);
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.perturb = new PerturbFilter();
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.perturb.setMagnitude(0.119f);
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.therm = new OptimizedErode();
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.therm.setRadius(5);
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.therm.setTalus(0.011f);
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.smooth = new SmoothFilter();
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.smooth.setRadius(1);
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.smooth.setEffect(0.7f);
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.iterate = new IterativeFilter();
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.iterate.addPreFilter(this.perturb);
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.iterate.addPostFilter(this.smooth);
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.iterate.setFilter(this.therm);
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.iterate.setIterations(1);
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        ground.addPreFilter(this.iterate);
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.terrain = new TerrainGrid("terrain", 33, 257, new FractalTileLoader(ground, 256));
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.terrain.setMaterial(this.material);
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.terrain.setLocalTranslation(0, 0, 0);
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.terrain.setLocalScale(2f, 1f, 2f);
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.rootNode.attachChild(this.terrain);
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        List<Camera> cameras = new ArrayList<Camera>();
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        cameras.add(this.getCamera());
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        TerrainLodControl control = new TerrainLodControl(this.terrain, cameras);
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        control.setLodCalculator( new DistanceLodCalculator(33, 2.7f) ); // patch size, and a multiplier
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.terrain.addControl(control);
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        final BulletAppState bulletAppState = new BulletAppState();
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        stateManager.attach(bulletAppState);
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.getCamera().setLocation(new Vector3f(0, 256, 0));
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (usePhysics) {
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            player3 = new CharacterControl(capsuleShape, 0.5f);
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            player3.setJumpSpeed(20);
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            player3.setFallSpeed(10);
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            player3.setGravity(10);
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bulletAppState.getPhysicsSpace().add(player3);
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        terrain.addListener(new TerrainGridListener() {
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            public void gridMoved(Vector3f newCenter) {
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            public void tileAttached(Vector3f cell, TerrainQuad quad) {
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Texture alpha = null;
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                try {
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_" + (int)cell.x+ "_" + (int)cell.z + ".png");
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } catch (Exception e) {
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    alpha = assetManager.loadTexture("TerrainAlphaTest/alpha_default.png");
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                quad.getMaterial().setTexture("AlphaMap", alpha);
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (usePhysics) {
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    bulletAppState.getPhysicsSpace().add(quad);
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                updateMarkerElevations();
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            public void tileDetached(Vector3f cell, TerrainQuad quad) {
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (usePhysics) {
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    bulletAppState.getPhysicsSpace().remove(quad);
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    quad.removeControl(RigidBodyControl.class);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                updateMarkerElevations();
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        });
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.initKeys();
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        markers = new Node();
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        rootNode.attachChild(markers);
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        createMarkerPoints(1);
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    Node markers;
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void createMarkerPoints(float count) {
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Node center = createAxisMarker(10);
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        markers.attachChild(center);
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float xS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2);
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float zS = (count-1)*terrain.getTerrainSize() - (terrain.getTerrainSize()/2);
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float xSi = xS;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float zSi = zS;
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (int x=0; x<count*2; x++) {
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int z=0; z<count*2; z++) {
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Node m = createAxisMarker(5);
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                m.setLocalTranslation(xSi, 0, zSi);
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                markers.attachChild(m);
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                zSi += terrain.getTerrainSize();
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            zSi = zS;
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            xSi += terrain.getTerrainSize();
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void updateMarkerElevations() {
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (Spatial s : markers.getChildren()) {
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float h = terrain.getHeight(new Vector2f(s.getLocalTranslation().x, s.getLocalTranslation().z));
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            s.setLocalTranslation(s.getLocalTranslation().x, h+1, s.getLocalTranslation().z);
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private void initKeys() {
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // You can map one or several inputs to one named action
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE));
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addListener(this.actionListener, "Lefts");
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addListener(this.actionListener, "Rights");
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addListener(this.actionListener, "Ups");
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addListener(this.actionListener, "Downs");
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.inputManager.addListener(this.actionListener, "Jumps");
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean left;
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean right;
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean up;
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean down;
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final ActionListener actionListener = new ActionListener() {
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        @Override
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        public void onAction(final String name, final boolean keyPressed, final float tpf) {
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (name.equals("Lefts")) {
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (keyPressed) {
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.left = true;
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.left = false;
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (name.equals("Rights")) {
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (keyPressed) {
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.right = true;
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.right = false;
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (name.equals("Ups")) {
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (keyPressed) {
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.up = true;
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.up = false;
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (name.equals("Downs")) {
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                if (keyPressed) {
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.down = true;
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                } else {
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    TerrainGridAlphaMapTest.this.down = false;
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                }
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (name.equals("Jumps")) {
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                TerrainGridAlphaMapTest.this.player3.jump();
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    };
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private final Vector3f walkDirection = new Vector3f();
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void simpleUpdate(final float tpf) {
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f);
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f);
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.walkDirection.set(0, 0, 0);
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this.left) {
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.walkDirection.addLocal(camLeft);
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this.right) {
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.walkDirection.addLocal(camLeft.negate());
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this.up) {
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.walkDirection.addLocal(camDir);
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (this.down) {
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.walkDirection.addLocal(camDir.negate());
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (usePhysics) {
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.player3.setWalkDirection(this.walkDirection);
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.cam.setLocation(this.player3.getPhysicsLocation());
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Node createAxisMarker(float arrowSize) {
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Material redMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        redMat.getAdditionalRenderState().setWireframe(true);
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        redMat.setColor("Color", ColorRGBA.Red);
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Material greenMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        greenMat.getAdditionalRenderState().setWireframe(true);
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        greenMat.setColor("Color", ColorRGBA.Green);
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Material blueMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        blueMat.getAdditionalRenderState().setWireframe(true);
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        blueMat.setColor("Color", ColorRGBA.Blue);
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Node axis = new Node();
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // create arrows
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Geometry arrowX = new Geometry("arrowX", new Arrow(new Vector3f(arrowSize, 0, 0)));
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        arrowX.setMaterial(redMat);
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Geometry arrowY = new Geometry("arrowY", new Arrow(new Vector3f(0, arrowSize, 0)));
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        arrowY.setMaterial(greenMat);
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Geometry arrowZ = new Geometry("arrowZ", new Arrow(new Vector3f(0, 0, arrowSize)));
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        arrowZ.setMaterial(blueMat);
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        axis.attachChild(arrowX);
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        axis.attachChild(arrowY);
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        axis.attachChild(arrowZ);
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //axis.setModelBound(new BoundingBox());
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return axis;
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
360