Updated jme3test.helloworld: Used best practices, simplified, removed deprecations, added javadoc, added TerrainCollision.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8301 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
roo..li 13 years ago
parent 0da67bdfd6
commit 7967cc1c33
  1. 1
      engine/src/test/jme3test/helloworld/HelloAssets.java
  2. 19
      engine/src/test/jme3test/helloworld/HelloAudio.java
  3. 73
      engine/src/test/jme3test/helloworld/HelloCollision.java
  4. 61
      engine/src/test/jme3test/helloworld/HelloEffects.java
  5. 9
      engine/src/test/jme3test/helloworld/HelloJME3.java
  6. 3
      engine/src/test/jme3test/helloworld/HelloLoop.java
  7. 8
      engine/src/test/jme3test/helloworld/HelloNode.java
  8. 43
      engine/src/test/jme3test/helloworld/HelloPhysics.java
  9. 1
      engine/src/test/jme3test/helloworld/HelloPicking.java
  10. 28
      engine/src/test/jme3test/helloworld/HelloTerrain.java
  11. 226
      engine/src/test/jme3test/helloworld/HelloTerrainCollision.java

@ -87,6 +87,5 @@ public class HelloAssets extends SimpleApplication {
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal());
rootNode.addLight(sun);
}
}

@ -29,7 +29,8 @@ public class HelloAudio extends SimpleApplication {
/** just a blue box floating in space */
Box box1 = new Box(Vector3f.ZERO, 1, 1, 1);
player = new Geometry("Player", box1);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat1 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
player.setMaterial(mat1);
rootNode.attachChild(player);
@ -42,22 +43,22 @@ public class HelloAudio extends SimpleApplication {
/** We create two audio nodes. */
private void initAudio() {
/* gun shot sound is to be triggered by a mouse click. */
audio_gun = new AudioNode(audioRenderer, assetManager, "Sound/Effects/Gun.wav", false);
audio_gun = new AudioNode(assetManager, "Sound/Effects/Gun.wav", false);
audio_gun.setLooping(false);
audio_gun.setVolume(2);
rootNode.attachChild(audio_gun);
/* nature sound - keeps playing in a loop. */
audio_nature = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Nature.ogg", false);
audio_nature.setLooping(true);
audio_nature = new AudioNode(assetManager, "Sound/Environment/Nature.ogg", true);
audio_nature.setLooping(true); // activate continuous playing
audio_nature.setPositional(true);
audio_nature.setLocalTranslation(Vector3f.ZERO.clone());
audio_nature.setVolume(3);
audio_nature.updateGeometricState();
audioRenderer.playSource(audio_nature); // play continuously!
rootNode.attachChild(audio_nature);
audio_nature.play(); // play continuously!
}
/** Declaring the "Shoot" action, and
* mapping it to a trigger (mouse click). */
/** Declaring "Shoot" action, mapping it to a trigger (mouse click). */
private void initKeys() {
inputManager.addMapping("Shoot", new MouseButtonTrigger(0));
inputManager.addListener(actionListener, "Shoot");
@ -68,7 +69,7 @@ public class HelloAudio extends SimpleApplication {
@Override
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("Shoot") && !keyPressed) {
audioRenderer.playSource(audio_gun); // play once!
audio_gun.playInstance(); // play each instance once!
}
}
};

@ -52,11 +52,11 @@ import com.jme3.scene.Spatial;
/**
* Example 9 - How to make walls and floors solid.
* This version uses Physics and a custom Action Listener.
* This collision code uses Physics and a custom Action Listener.
* @author normen, with edits by Zathras
*/
public class HelloCollision extends SimpleApplication
implements ActionListener {
implements ActionListener {
private Spatial sceneModel;
private BulletAppState bulletAppState;
@ -74,9 +74,10 @@ public class HelloCollision extends SimpleApplication
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
// We re-use the flyby camera for rotation, while positioning is handled by physics
viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
flyCam.setMoveSpeed(100);
setUpKeys();
setUpLight();
@ -87,15 +88,15 @@ public class HelloCollision extends SimpleApplication
sceneModel.setLocalScale(2f);
// We set up collision detection for the scene by creating a
// compound collision shape and a static physics node with mass zero.
// compound collision shape and a static RigidBodyControl with mass zero.
CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape((Node) sceneModel);
CollisionShapeFactory.createMeshShape((Node) sceneModel);
landscape = new RigidBodyControl(sceneShape, 0);
sceneModel.addControl(landscape);
// We set up collision detection for the player by creating
// a capsule collision shape and a physics character node.
// The physics character node offers extra settings for
// a capsule collision shape and a CharacterControl.
// The CharacterControl offers extra settings for
// size, stepheight, jumping, falling, and gravity.
// We also put the player in its starting position.
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
@ -112,45 +113,45 @@ public class HelloCollision extends SimpleApplication
bulletAppState.getPhysicsSpace().add(player);
}
private void setUpLight() {
// We add light so we see the scene
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(al);
private void setUpLight() {
// We add light so we see the scene
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(al);
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White);
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
rootNode.addLight(dl);
}
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White);
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
rootNode.addLight(dl);
}
/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */
private void setUpKeys() {
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "Lefts");
inputManager.addListener(this, "Rights");
inputManager.addListener(this, "Ups");
inputManager.addListener(this, "Downs");
inputManager.addListener(this, "Jumps");
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "Left");
inputManager.addListener(this, "Right");
inputManager.addListener(this, "Up");
inputManager.addListener(this, "Down");
inputManager.addListener(this, "Jump");
}
/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if (value) { left = true; } else { left = false; }
} else if (binding.equals("Rights")) {
if (binding.equals("Left")) {
if (value) { left = true; } else { left = false; }
} else if (binding.equals("Right")) {
if (value) { right = true; } else { right = false; }
} else if (binding.equals("Ups")) {
if (value) { up = true; } else { up = false; }
} else if (binding.equals("Downs")) {
if (value) { down = true; } else { down = false; }
} else if (binding.equals("Jumps")) {
} else if (binding.equals("Up")) {
if (value) { up = true; } else { up = false; }
} else if (binding.equals("Down")) {
if (value) { down = true; } else { down = false; }
} else if (binding.equals("Jump")) {
player.jump();
}
}

@ -49,52 +49,63 @@ public class HelloEffects extends SimpleApplication {
@Override
public void simpleInitApp() {
ParticleEmitter fire = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
Material mat_red = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat_red.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
ParticleEmitter fire =
new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
Material mat_red = new Material(assetManager,
"Common/MatDefs/Misc/Particle.j3md");
mat_red.setTexture("Texture", assetManager.loadTexture(
"Effects/Explosion/flame.png"));
fire.setMaterial(mat_red);
fire.setImagesX(2); fire.setImagesY(2); // 2x2 texture animation
fire.setImagesX(2);
fire.setImagesY(2); // 2x2 texture animation
fire.setEndColor( new ColorRGBA(1f, 0f, 0f, 1f)); // red
fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
fire.setInitialVelocity(new Vector3f(0, 2, 0));
fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0));
fire.setStartSize(1.5f);
fire.setEndSize(0.1f);
fire.setGravity(0, 0, 0);
fire.setLowLife(1f);
fire.setHighLife(3f);
fire.setVelocityVariation(0.3f);
fire.getParticleInfluencer().setVelocityVariation(0.3f);
rootNode.attachChild(fire);
ParticleEmitter debris = new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
Material debris_mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
debris_mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/Debris.png"));
ParticleEmitter debris =
new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
Material debris_mat = new Material(assetManager,
"Common/MatDefs/Misc/Particle.j3md");
debris_mat.setTexture("Texture", assetManager.loadTexture(
"Effects/Explosion/Debris.png"));
debris.setMaterial(debris_mat);
debris.setImagesX(3); debris.setImagesY(3); // 3x3 texture animation
debris.setRotateSpeed(4);
debris.setImagesX(3);
debris.setImagesY(3); // 3x3 texture animation
debris.setSelectRandomImage(true);
debris.setInitialVelocity(new Vector3f(0, 4, 0));
debris.setRotateSpeed(4);
debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 4, 0));
debris.setStartColor(ColorRGBA.White);
debris.setGravity(0, 6, 0);
debris.setVelocityVariation(.60f);
debris.getParticleInfluencer().setVelocityVariation(.60f);
rootNode.attachChild(debris);
debris.emitAllParticles();
// ParticleEmitter water = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
// Material mat_blue = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
// mat_blue.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
// ParticleEmitter water =
// new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 20);
// Material mat_blue = new Material(assetManager,
// "Common/MatDefs/Misc/Particle.j3md");
// mat_blue.setTexture("Texture", assetManager.loadTexture(
// "Effects/Explosion/flame.png"));
// water.setMaterial(mat_blue);
// water.setImagesX(2); water.setImagesY(2); // 2x2 texture animation
// water.setStartColor(new ColorRGBA(0f, 0f, 1f, 1f)); // blue
// water.setEndColor( new ColorRGBA(0f, 1f, 1f, 1f)); // turquois
// water.setInitialVelocity(new Vector3f(0, -2, 0));
// water.setImagesX(2);
// water.setImagesY(2); // 2x2 texture animation
// water.setStartColor( ColorRGBA.Blue);
// water.setEndColor( ColorRGBA.Cyan);
// water.getParticleInfluencer().setInitialVelocity(new Vector3f(0, -4, 0));
// water.setStartSize(1f);
// water.setEndSize(1.5f);
// water.setGravity(1);
// water.setGravity(0,1,0);
// water.setLowLife(1f);
// water.setHighLife(3f);
// water.setVelocityVariation(0.3f);
// water.setLocalTranslation(0, 5, 0);
// water.setHighLife(1f);
// water.getParticleInfluencer().setVelocityVariation(0.1f);
// water.setLocalTranslation(0, 6, 0);
// rootNode.attachChild(water);
}

@ -33,7 +33,6 @@
package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.input.FlyByCamera;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
@ -47,16 +46,16 @@ public class HelloJME3 extends SimpleApplication {
public static void main(String[] args){
HelloJME3 app = new HelloJME3();
app.start(); // start JME3
app.start(); // start the game
}
@Override
public void simpleInitApp() {
Box b = new Box(Vector3f.ZERO, 1, 1, 1); // create cube shape
Box b = new Box(Vector3f.ZERO, 1, 1, 1); // create cube shape at the origin
Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
}

@ -40,7 +40,8 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
/** Sample 4 - how to trigger repeating actions from the main event loop.
* In this example, we make the player character rotate. */
* In this example, you use the loop to make the player character
* rotate continuously. */
public class HelloLoop extends SimpleApplication {
public static void main(String[] args){

@ -56,14 +56,16 @@ public class HelloNode extends SimpleApplication {
/** create a blue box at coordinates (1,-1,1) */
Box box1 = new Box( new Vector3f(1,-1,1), 1,1,1);
Geometry blue = new Geometry("Box", box1);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat1 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
blue.setMaterial(mat1);
/** create a red box straight above the blue one at (1,3,1) */
Box box2 = new Box( new Vector3f(1,3,1), 1,1,1);
Geometry red = new Geometry("Box", box2);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat2 = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.Red);
red.setMaterial(mat2);
@ -76,8 +78,6 @@ public class HelloNode extends SimpleApplication {
pivot.attachChild(red);
/** Rotate the pivot node: Note that both boxes have rotated! */
pivot.rotate(.4f,.4f,0f);
}
}

@ -43,12 +43,10 @@ import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.shadow.BasicShadowRenderer;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
@ -66,9 +64,6 @@ public class HelloPhysics extends SimpleApplication {
/** Prepare the Physics Application State (jBullet) */
private BulletAppState bulletAppState;
/** Activate custom rendering of shadows */
BasicShadowRenderer bsr;
/** Prepare Materials */
Material wall_mat;
Material stone_mat;
@ -104,19 +99,23 @@ public class HelloPhysics extends SimpleApplication {
/** Set up Physics Game */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
/** Configure cam to look at scene */
cam.setLocation(new Vector3f(0, 6f, 6f));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(15);
/** Add InputManager action: Left click triggers shooting. */
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
/** Initialize the scene, materials, and physics space */
cam.setLocation(new Vector3f(0, 4f, 6f));
cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y);
/** Initialize the scene, materials, inputs, and physics space */
initInputs();
initMaterials();
initWall();
initFloor();
initCrossHairs();
initShadows();
}
/** Add InputManager action: Left click triggers shooting. */
private void initInputs() {
inputManager.addMapping("shoot",
new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
}
/**
@ -157,7 +156,6 @@ public class HelloPhysics extends SimpleApplication {
public void initFloor() {
Geometry floor_geo = new Geometry("Floor", floor);
floor_geo.setMaterial(floor_mat);
floor_geo.setShadowMode(ShadowMode.Receive);
floor_geo.setLocalTranslation(0, -0.1f, 0);
this.rootNode.attachChild(floor_geo);
/* Make the floor physical with mass 0.0f! */
@ -171,7 +169,7 @@ public class HelloPhysics extends SimpleApplication {
float startpt = brickLength / 4;
float height = 0;
for (int j = 0; j < 15; j++) {
for (int i = 0; i < 4; i++) {
for (int i = 0; i < 6; i++) {
Vector3f vt =
new Vector3f(i * brickLength * 2 + startpt, brickHeight + height, 0);
makeBrick(vt);
@ -181,24 +179,14 @@ public class HelloPhysics extends SimpleApplication {
}
}
/** Activate shadow casting and light direction */
private void initShadows() {
bsr = new BasicShadowRenderer(assetManager, 256);
bsr.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
viewPort.addProcessor(bsr);
// Default mode is Off -- Every node declares own shadow mode!
rootNode.setShadowMode(ShadowMode.Off);
}
/** This method creates one individual physical brick. */
public void makeBrick(Vector3f loc) {
/** Create a brick geometry and attach to scene graph. */
Geometry brick_geo = new Geometry("brick", box);
brick_geo.setMaterial(wall_mat);
rootNode.attachChild(brick_geo);
/** Position the brick geometry and activate shadows */
/** Position the brick geometry */
brick_geo.setLocalTranslation(loc);
brick_geo.setShadowMode(ShadowMode.CastAndReceive);
/** Make brick physical with a mass > 0.0f. */
brick_phy = new RigidBodyControl(2f);
/** Add physical brick to physics space. */
@ -214,9 +202,8 @@ public class HelloPhysics extends SimpleApplication {
Geometry ball_geo = new Geometry("cannon ball", sphere);
ball_geo.setMaterial(stone_mat);
rootNode.attachChild(ball_geo);
/** Position the cannon ball and activate shadows */
/** Position the cannon ball */
ball_geo.setLocalTranslation(cam.getLocation());
ball_geo.setShadowMode(ShadowMode.CastAndReceive);
/** Make the ball physcial with a mass > 0.0f */
ball_phy = new RigidBodyControl(1f);
/** Add physical ball to physics space. */

@ -33,7 +33,6 @@
package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapText;

@ -38,7 +38,7 @@ import com.jme3.renderer.Camera;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.HillHeightMap;
import com.jme3.terrain.heightmap.HillHeightMap; // for exercise 2
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
@ -61,42 +61,49 @@ public class HelloTerrain extends SimpleApplication {
flyCam.setMoveSpeed(50);
/** 1. Create terrain material and load four textures into it. */
mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
mat_terrain = new Material(assetManager,
"Common/MatDefs/Terrain/Terrain.j3md");
/** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
mat_terrain.setTexture("Alpha", assetManager.loadTexture(
"Textures/Terrain/splat/alphamap.png"));
/** 1.2) Add GRASS texture into the red layer (Tex1). */
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
Texture grass = assetManager.loadTexture(
"Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex1", grass);
mat_terrain.setFloat("Tex1Scale", 64f);
/** 1.3) Add DIRT texture into the green layer (Tex2) */
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
Texture dirt = assetManager.loadTexture(
"Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex2", dirt);
mat_terrain.setFloat("Tex2Scale", 32f);
/** 1.4) Add ROAD texture into the blue layer (Tex3) */
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
Texture rock = assetManager.loadTexture(
"Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex3", rock);
mat_terrain.setFloat("Tex3Scale", 128f);
/** 2. Create the height map */
AbstractHeightMap heightmap = null;
Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
Texture heightMapImage = assetManager.loadTexture(
"Textures/Terrain/splat/mountains512.png");
heightmap = new ImageBasedHeightMap(
ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));
heightmap.load();
/** 3. We have prepared material and heightmap. Now we create the actual terrain:
* 3.1) We create a TerrainQuad and name it "my terrain".
/** 3. We have prepared material and heightmap.
* Now we create the actual terrain:
* 3.1) Create a TerrainQuad and name it "my terrain".
* 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
* 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
* 3.4) As LOD step scale we supply Vector3f(1,1,1).
* 3.5) At last, we supply the prepared heightmap itself.
* 3.5) We supply the prepared heightmap itself.
*/
terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());
@ -111,6 +118,5 @@ public class HelloTerrain extends SimpleApplication {
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);
}
}

@ -0,0 +1,226 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import java.util.ArrayList;
import java.util.List;
import jme3tools.converters.ImageToAwt;
/**
* This demo shows a terrain with collision detection,
* that you can walk around in with a first-person perspective.
* This code combines HelloCollision and HelloTerrain.
*/
public class HelloTerrainCollision extends SimpleApplication
implements ActionListener {
private BulletAppState bulletAppState;
private RigidBodyControl landscape;
private CharacterControl player;
private Vector3f walkDirection = new Vector3f();
private boolean left = false, right = false, up = false, down = false;
private TerrainQuad terrain;
private Material mat_terrain;
public static void main(String[] args) {
HelloTerrainCollision app = new HelloTerrainCollision();
app.start();
}
@Override
public void simpleInitApp() {
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
flyCam.setMoveSpeed(100);
setUpKeys();
/** 1. Create terrain material and load four textures into it. */
mat_terrain = new Material(assetManager,
"Common/MatDefs/Terrain/Terrain.j3md");
/** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
mat_terrain.setTexture("Alpha", assetManager.loadTexture(
"Textures/Terrain/splat/alphamap.png"));
/** 1.2) Add GRASS texture into the red layer (Tex1). */
Texture grass = assetManager.loadTexture(
"Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex1", grass);
mat_terrain.setFloat("Tex1Scale", 64f);
/** 1.3) Add DIRT texture into the green layer (Tex2) */
Texture dirt = assetManager.loadTexture(
"Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex2", dirt);
mat_terrain.setFloat("Tex2Scale", 32f);
/** 1.4) Add ROAD texture into the blue layer (Tex3) */
Texture rock = assetManager.loadTexture(
"Textures/Terrain/splat/road.jpg");
rock.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex3", rock);
mat_terrain.setFloat("Tex3Scale", 128f);
/** 2. Create the height map */
AbstractHeightMap heightmap = null;
Texture heightMapImage = assetManager.loadTexture(
"Textures/Terrain/splat/mountains512.png");
heightmap = new ImageBasedHeightMap(
ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));
heightmap.load();
/** 3. We have prepared material and heightmap.
* Now we create the actual terrain:
* 3.1) Create a TerrainQuad and name it "my terrain".
* 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
* 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
* 3.4) As LOD step scale we supply Vector3f(1,1,1).
* 3.5) We supply the prepared heightmap itself.
*/
terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());
/** 4. We give the terrain its material, position & scale it, and attach it. */
terrain.setMaterial(mat_terrain);
terrain.setLocalTranslation(0, -100, 0);
terrain.setLocalScale(2f, 1f, 2f);
rootNode.attachChild(terrain);
/** 5. The LOD (level of detail) depends on were the camera is: */
List<Camera> cameras = new ArrayList<Camera>();
cameras.add(getCamera());
TerrainLodControl control = new TerrainLodControl(terrain, cameras);
terrain.addControl(control);
/** 6. Add physics: */
// We set up collision detection for the scene by creating a
// compound collision shape and a static RigidBodyControl with mass zero.*/
CollisionShape terrainShape =
CollisionShapeFactory.createMeshShape((Node) terrain);
landscape = new RigidBodyControl(terrainShape, 0);
terrain.addControl(landscape);
// We set up collision detection for the player by creating
// a capsule collision shape and a CharacterControl.
// The CharacterControl offers extra settings for
// size, stepheight, jumping, falling, and gravity.
// We also put the player in its starting position.
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
player.setPhysicsLocation(new Vector3f(0, 10, 0));
// We attach the scene and the player to the rootnode and the physics space,
// to make them appear in the game world.
bulletAppState.getPhysicsSpace().add(terrain);
bulletAppState.getPhysicsSpace().add(player);
}
/** We over-write some navigational key mappings here, so we can
* add physics-controlled walking and jumping: */
private void setUpKeys() {
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, "Left");
inputManager.addListener(this, "Right");
inputManager.addListener(this, "Up");
inputManager.addListener(this, "Down");
inputManager.addListener(this, "Jump");
}
/** These are our custom actions triggered by key presses.
* We do not walk yet, we just keep track of the direction the user pressed. */
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Left")) {
if (value) { left = true; } else { left = false; }
} else if (binding.equals("Right")) {
if (value) { right = true; } else { right = false; }
} else if (binding.equals("Up")) {
if (value) { up = true; } else { up = false; }
} else if (binding.equals("Down")) {
if (value) { down = true; } else { down = false; }
} else if (binding.equals("Jump")) {
player.jump();
}
}
/**
* This is the main event loop--walking happens here.
* We check in which direction the player is walking by interpreting
* the camera direction forward (camDir) and to the side (camLeft).
* The setWalkDirection() command is what lets a physics-controlled player walk.
* We also make sure here that the camera moves with player.
*/
@Override
public void simpleUpdate(float tpf) {
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
walkDirection.set(0, 0, 0);
if (left) { walkDirection.addLocal(camLeft); }
if (right) { walkDirection.addLocal(camLeft.negate()); }
if (up) { walkDirection.addLocal(camDir); }
if (down) { walkDirection.addLocal(camDir.negate()); }
player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
}
}
Loading…
Cancel
Save