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