Home | History | Annotate | Download | only in terrain
      1 package jme3test.terrain;
      2 
      3 import com.jme3.app.SimpleApplication;
      4 import com.jme3.app.state.ScreenshotAppState;
      5 import com.jme3.asset.plugins.HttpZipLocator;
      6 import com.jme3.asset.plugins.ZipLocator;
      7 import com.jme3.bullet.BulletAppState;
      8 import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
      9 import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
     10 import com.jme3.bullet.control.CharacterControl;
     11 import com.jme3.bullet.control.RigidBodyControl;
     12 import com.jme3.input.KeyInput;
     13 import com.jme3.input.controls.ActionListener;
     14 import com.jme3.input.controls.KeyTrigger;
     15 import com.jme3.material.Material;
     16 import com.jme3.math.ColorRGBA;
     17 import com.jme3.math.Vector3f;
     18 import com.jme3.terrain.geomipmap.TerrainGrid;
     19 import com.jme3.terrain.geomipmap.TerrainGridListener;
     20 import com.jme3.terrain.geomipmap.TerrainLodControl;
     21 import com.jme3.terrain.geomipmap.TerrainQuad;
     22 import com.jme3.terrain.geomipmap.grid.AssetTileLoader;
     23 import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
     24 import com.jme3.texture.Texture;
     25 import com.jme3.texture.Texture.WrapMode;
     26 import java.io.File;
     27 
     28 public class TerrainGridTileLoaderTest extends SimpleApplication {
     29 
     30     private Material mat_terrain;
     31     private TerrainGrid terrain;
     32     private float grassScale = 64;
     33     private float dirtScale = 16;
     34     private float rockScale = 128;
     35     private boolean usePhysics = true;
     36     private boolean physicsAdded = false;
     37 
     38     public static void main(final String[] args) {
     39         TerrainGridTileLoaderTest app = new TerrainGridTileLoaderTest();
     40         app.start();
     41     }
     42     private CharacterControl player3;
     43 
     44     @Override
     45     public void simpleInitApp() {
     46         File file = new File("TerrainGridTestData.zip");
     47         if (!file.exists()) {
     48             assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/TerrainGridTestData.zip", HttpZipLocator.class);
     49         } else {
     50             assetManager.registerLocator("TerrainGridTestData.zip", ZipLocator.class);
     51         }
     52 
     53         this.flyCam.setMoveSpeed(100f);
     54         ScreenshotAppState state = new ScreenshotAppState();
     55         this.stateManager.attach(state);
     56 
     57         // TERRAIN TEXTURE material
     58         this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
     59 
     60         // Parameters to material:
     61         // regionXColorMap: X = 1..4 the texture that should be appliad to state X
     62         // regionX: a Vector3f containing the following information:
     63         //      regionX.x: the start height of the region
     64         //      regionX.y: the end height of the region
     65         //      regionX.z: the texture scale for the region
     66         //  it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
     67         // slopeColorMap: the texture to be used for cliffs, and steep mountain sites
     68         // slopeTileFactor: the texture scale for slopes
     69         // terrainSize: the total size of the terrain (used for scaling the texture)
     70         // GRASS texture
     71         Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
     72         grass.setWrap(WrapMode.Repeat);
     73         this.mat_terrain.setTexture("region1ColorMap", grass);
     74         this.mat_terrain.setVector3("region1", new Vector3f(88, 200, this.grassScale));
     75 
     76         // DIRT texture
     77         Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
     78         dirt.setWrap(WrapMode.Repeat);
     79         this.mat_terrain.setTexture("region2ColorMap", dirt);
     80         this.mat_terrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale));
     81 
     82         // ROCK texture
     83         Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
     84         rock.setWrap(WrapMode.Repeat);
     85         this.mat_terrain.setTexture("region3ColorMap", rock);
     86         this.mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale));
     87 
     88         this.mat_terrain.setTexture("region4ColorMap", rock);
     89         this.mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale));
     90 
     91         this.mat_terrain.setTexture("slopeColorMap", rock);
     92         this.mat_terrain.setFloat("slopeTileFactor", 32);
     93 
     94         this.mat_terrain.setFloat("terrainSize", 129);
     95 //quad.getHeightMap(), terrain.getLocalScale()), 0
     96         AssetTileLoader grid = new AssetTileLoader(assetManager, "testgrid", "TerrainGrid");
     97         this.terrain = new TerrainGrid("terrain", 65, 257, grid);
     98 
     99         this.terrain.setMaterial(this.mat_terrain);
    100         this.terrain.setLocalTranslation(0, 0, 0);
    101         this.terrain.setLocalScale(2f, 1f, 2f);
    102 //        try {
    103 //            BinaryExporter.getInstance().save(terrain, new File("/Users/normenhansen/Documents/Code/jme3/engine/src/test-data/TerrainGrid/"
    104 //                    + "TerrainGrid.j3o"));
    105 //        } catch (IOException ex) {
    106 //            Logger.getLogger(TerrainFractalGridTest.class.getName()).log(Level.SEVERE, null, ex);
    107 //        }
    108 
    109         this.rootNode.attachChild(this.terrain);
    110 
    111         TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera());
    112         control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
    113         this.terrain.addControl(control);
    114 
    115         final BulletAppState bulletAppState = new BulletAppState();
    116         stateManager.attach(bulletAppState);
    117 
    118         this.getCamera().setLocation(new Vector3f(0, 256, 0));
    119 
    120         this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
    121 
    122         if (usePhysics) {
    123             CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
    124             player3 = new CharacterControl(capsuleShape, 0.5f);
    125             player3.setJumpSpeed(20);
    126             player3.setFallSpeed(10);
    127             player3.setGravity(10);
    128 
    129             player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
    130 
    131             bulletAppState.getPhysicsSpace().add(player3);
    132 
    133             terrain.addListener(new TerrainGridListener() {
    134 
    135                 public void gridMoved(Vector3f newCenter) {
    136                 }
    137 
    138                 public Material tileLoaded(Material material, Vector3f cell) {
    139                     return material;
    140                 }
    141 
    142                 public void tileAttached(Vector3f cell, TerrainQuad quad) {
    143                     while(quad.getControl(RigidBodyControl.class)!=null){
    144                         quad.removeControl(RigidBodyControl.class);
    145                     }
    146                     quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
    147                     bulletAppState.getPhysicsSpace().add(quad);
    148                 }
    149 
    150                 public void tileDetached(Vector3f cell, TerrainQuad quad) {
    151                     bulletAppState.getPhysicsSpace().remove(quad);
    152                     quad.removeControl(RigidBodyControl.class);
    153                 }
    154 
    155             });
    156         }
    157 
    158         this.initKeys();
    159     }
    160 
    161     private void initKeys() {
    162         // You can map one or several inputs to one named action
    163         this.inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
    164         this.inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
    165         this.inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
    166         this.inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
    167         this.inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE));
    168         this.inputManager.addListener(this.actionListener, "Lefts");
    169         this.inputManager.addListener(this.actionListener, "Rights");
    170         this.inputManager.addListener(this.actionListener, "Ups");
    171         this.inputManager.addListener(this.actionListener, "Downs");
    172         this.inputManager.addListener(this.actionListener, "Jumps");
    173     }
    174     private boolean left;
    175     private boolean right;
    176     private boolean up;
    177     private boolean down;
    178     private final ActionListener actionListener = new ActionListener() {
    179 
    180         @Override
    181         public void onAction(final String name, final boolean keyPressed, final float tpf) {
    182             if (name.equals("Lefts")) {
    183                 if (keyPressed) {
    184                     TerrainGridTileLoaderTest.this.left = true;
    185                 } else {
    186                     TerrainGridTileLoaderTest.this.left = false;
    187                 }
    188             } else if (name.equals("Rights")) {
    189                 if (keyPressed) {
    190                     TerrainGridTileLoaderTest.this.right = true;
    191                 } else {
    192                     TerrainGridTileLoaderTest.this.right = false;
    193                 }
    194             } else if (name.equals("Ups")) {
    195                 if (keyPressed) {
    196                     TerrainGridTileLoaderTest.this.up = true;
    197                 } else {
    198                     TerrainGridTileLoaderTest.this.up = false;
    199                 }
    200             } else if (name.equals("Downs")) {
    201                 if (keyPressed) {
    202                     TerrainGridTileLoaderTest.this.down = true;
    203                 } else {
    204                     TerrainGridTileLoaderTest.this.down = false;
    205                 }
    206             } else if (name.equals("Jumps")) {
    207                 TerrainGridTileLoaderTest.this.player3.jump();
    208             }
    209         }
    210     };
    211     private final Vector3f walkDirection = new Vector3f();
    212 
    213     @Override
    214     public void simpleUpdate(final float tpf) {
    215         Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f);
    216         Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f);
    217         this.walkDirection.set(0, 0, 0);
    218         if (this.left) {
    219             this.walkDirection.addLocal(camLeft);
    220         }
    221         if (this.right) {
    222             this.walkDirection.addLocal(camLeft.negate());
    223         }
    224         if (this.up) {
    225             this.walkDirection.addLocal(camDir);
    226         }
    227         if (this.down) {
    228             this.walkDirection.addLocal(camDir.negate());
    229         }
    230 
    231         if (usePhysics) {
    232             this.player3.setWalkDirection(this.walkDirection);
    233             this.cam.setLocation(this.player3.getPhysicsLocation());
    234         }
    235     }
    236 }
    237