git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7483 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
@ -0,0 +1,216 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.terrain.geomipmap; |
||||
|
||||
import com.jme3.bullet.PhysicsSpace; |
||||
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; |
||||
import com.jme3.bullet.control.RigidBodyControl; |
||||
import com.jme3.terrain.heightmap.HeightMap; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.logging.Logger; |
||||
|
||||
import com.jme3.material.Material; |
||||
import com.jme3.math.FastMath; |
||||
import com.jme3.math.Vector2f; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory; |
||||
import com.jme3.terrain.geomipmap.lodcalc.LodDistanceCalculatorFactory; |
||||
import com.jme3.terrain.heightmap.HeightMapGrid; |
||||
|
||||
/** |
||||
* @author Anthyon |
||||
*/ |
||||
public class TerrainGrid extends TerrainQuad { |
||||
|
||||
private static Logger log = Logger.getLogger(TerrainGrid.class.getCanonicalName()); |
||||
private Vector3f currentCell; |
||||
private int quarterSize; |
||||
private int quadSize; |
||||
private HeightMapGrid heightMapGrid; |
||||
private Vector3f[] quadOrigins; |
||||
private Vector3f[] quadIndex; |
||||
private Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>(); |
||||
private Material material; |
||||
|
||||
public TerrainGrid(String name, int patchSize, int size, Vector3f stepScale, HeightMapGrid heightMapGrid, int totalSize, |
||||
Vector2f offset, float offsetAmount, LodCalculatorFactory lodCalculatorFactory) { |
||||
this.name = name; |
||||
this.patchSize = patchSize; |
||||
this.size = size; |
||||
this.quarterSize = size >> 2; |
||||
this.quadSize = (size + 1) >> 1; |
||||
this.stepScale = stepScale; |
||||
this.heightMapGrid = heightMapGrid; |
||||
heightMapGrid.setSize(this.quadSize); |
||||
this.totalSize = totalSize; |
||||
this.offset = offset; |
||||
this.offsetAmount = offsetAmount; |
||||
this.lodCalculatorFactory = lodCalculatorFactory; |
||||
if (lodCalculatorFactory == null) { |
||||
lodCalculatorFactory = new LodDistanceCalculatorFactory(); |
||||
} |
||||
this.quadOrigins = new Vector3f[]{new Vector3f(-this.quarterSize, 0, -this.quarterSize).mult(this.stepScale), |
||||
new Vector3f(-this.quarterSize, 0, this.quarterSize).mult(this.stepScale), |
||||
new Vector3f(this.quarterSize, 0, -this.quarterSize).mult(this.stepScale), |
||||
new Vector3f(this.quarterSize, 0, this.quarterSize).mult(this.stepScale)}; |
||||
this.quadIndex = new Vector3f[]{new Vector3f(0, 0, 0), new Vector3f(0, 0, 1), new Vector3f(1, 0, 0), new Vector3f(1, 0, 1)}; |
||||
|
||||
updateChildrens(Vector3f.ZERO); |
||||
} |
||||
|
||||
public TerrainGrid(String name, int patchSize, int size, Vector3f scale, HeightMapGrid heightMapGrid, |
||||
LodCalculatorFactory lodCalculatorFactory) { |
||||
this(name, patchSize, size, scale, heightMapGrid, size, new Vector2f(), 0, lodCalculatorFactory); |
||||
} |
||||
|
||||
public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid, LodCalculatorFactory lodCalculatorFactory) { |
||||
this(name, patchSize, totalSize, Vector3f.UNIT_XYZ, heightMapGrid, lodCalculatorFactory); |
||||
} |
||||
|
||||
public TerrainGrid(String name, int patchSize, int totalSize, HeightMapGrid heightMapGrid) { |
||||
this(name, patchSize, totalSize, heightMapGrid, null); |
||||
} |
||||
|
||||
public TerrainGrid() { |
||||
} |
||||
|
||||
@Override |
||||
public void update(List<Vector3f> locations) { |
||||
// for now, only the first camera is handled.
|
||||
// to accept more, there are two ways:
|
||||
// 1: every camera has an associated grid, then the location is not enough to identify which camera location has changed
|
||||
// 2: grids are associated with locations, and no incremental update is done, we load new grids for new locations, and unload those that are not needed anymore
|
||||
Vector3f cam = locations.get(0); |
||||
Vector3f camCell = this.getCell(cam); |
||||
if (!camCell.equals(this.currentCell)) { |
||||
this.updateChildrens(camCell); |
||||
for (TerrainGridListener l : this.listeners.values()) { |
||||
l.gridMoved(camCell); |
||||
} |
||||
} |
||||
|
||||
super.update(locations); |
||||
} |
||||
|
||||
public Vector3f getCell(Vector3f location) { |
||||
final Vector3f v = location.clone().divideLocal(this.getLocalScale().mult(this.quadSize)).add(0.5f, 0, 0.5f); |
||||
return new Vector3f(FastMath.floor(v.x), FastMath.floor(v.y), FastMath.floor(v.z)); |
||||
} |
||||
|
||||
protected void removeQuad(int idx) { |
||||
this.detachChild(this.getQuad(idx)); |
||||
} |
||||
|
||||
protected void moveQuad(int from, int to) { |
||||
this.removeQuad(to); |
||||
TerrainQuad fq = this.getQuad(from); |
||||
fq.setQuadrant((short) to); |
||||
fq.setLocalTranslation(this.quadOrigins[to - 1]); |
||||
} |
||||
|
||||
protected TerrainQuad createQuadAt(Vector3f location, int quadrant) { |
||||
final HeightMap heightMapAt = this.heightMapGrid.getHeightMapAt(location); |
||||
TerrainQuad q = new TerrainQuad(this.getName() + "Quad" + location, this.patchSize, this.quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap(), this.lodCalculatorFactory); |
||||
q.setLocalTranslation(this.quadOrigins[quadrant - 1]); |
||||
q.setMaterial(this.material); |
||||
q.setQuadrant((short) quadrant); |
||||
return q; |
||||
} |
||||
|
||||
private void updateChildrens(Vector3f cam) { |
||||
RigidBodyControl control = getControl(RigidBodyControl.class); |
||||
PhysicsSpace space = null; |
||||
if (control != null) { |
||||
space = control.getPhysicsSpace(); |
||||
space.remove(this); |
||||
this.removeControl(control); |
||||
} |
||||
int dx = (int) cam.x; |
||||
int dz = (int) cam.z; |
||||
if (this.currentCell != null) { |
||||
dx -= (int) (this.currentCell.x); |
||||
dz -= (int) (this.currentCell.z); |
||||
} |
||||
if (this.currentCell == null || FastMath.abs(dx) > 1 || FastMath.abs(dz) > 1 || (dx != 0 && dz != 0)) { |
||||
if (this.currentCell != null) { |
||||
// in case of teleport, otherwise the FastMath.abs(delta) should
|
||||
// never be greater than 1
|
||||
this.removeQuad(1); |
||||
this.removeQuad(2); |
||||
this.removeQuad(3); |
||||
this.removeQuad(4); |
||||
} |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); |
||||
} else if (dx == 0) { |
||||
if (dz < 0) { |
||||
// move north
|
||||
this.moveQuad(1, 2); |
||||
this.moveQuad(3, 4); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); |
||||
} else { |
||||
// move south
|
||||
this.moveQuad(2, 1); |
||||
this.moveQuad(4, 3); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); |
||||
} |
||||
} else if (dz == 0) { |
||||
if (dx < 0) { |
||||
// move west
|
||||
this.moveQuad(1, 3); |
||||
this.moveQuad(2, 4); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[0]).mult(this.quadSize - 1), 1)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[1]).mult(this.quadSize - 1), 2)); |
||||
} else { |
||||
// move east
|
||||
this.moveQuad(3, 1); |
||||
this.moveQuad(4, 2); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[2]).mult(this.quadSize - 1), 3)); |
||||
this.attachChild(this.createQuadAt(cam.add(this.quadIndex[3]).mult(this.quadSize - 1), 4)); |
||||
} |
||||
} else { |
||||
// rare situation to enter into a diagonally placed cell
|
||||
// could not get into this part while testing, as it is handled by moving first
|
||||
// in either horizontally or vertically than the other way
|
||||
// I handle it in the first IF
|
||||
} |
||||
this.currentCell = cam; |
||||
this.setLocalTranslation(cam.mult(2 * this.quadSize)); |
||||
|
||||
if (control != null) { |
||||
control = new RigidBodyControl(new HeightfieldCollisionShape(getHeightMap(), getLocalScale()), 0); |
||||
this.addControl(control); |
||||
space.add(this); |
||||
} |
||||
} |
||||
|
||||
public void addListener(String id, TerrainGridListener listener) { |
||||
this.listeners.put(id, listener); |
||||
} |
||||
|
||||
public Vector3f getCurrentCell() { |
||||
return this.currentCell; |
||||
} |
||||
|
||||
public void removeListener(String id) { |
||||
this.listeners.remove(id); |
||||
} |
||||
|
||||
@Override |
||||
public void setMaterial(Material mat) { |
||||
this.material = mat; |
||||
super.setMaterial(mat); |
||||
} |
||||
|
||||
public void setQuadSize(int quadSize) { |
||||
this.quadSize = quadSize; |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.terrain.geomipmap; |
||||
|
||||
import com.jme3.math.Vector3f; |
||||
|
||||
/** |
||||
* |
||||
* @author Anthyon |
||||
*/ |
||||
public interface TerrainGridListener { |
||||
|
||||
public void gridMoved(Vector3f newCenter); |
||||
|
||||
} |
@ -0,0 +1,68 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.terrain.heightmap; |
||||
|
||||
import java.awt.image.BufferedImage; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.logging.Level; |
||||
import java.util.logging.Logger; |
||||
import javax.imageio.ImageIO; |
||||
|
||||
/** |
||||
* |
||||
* @author Anthyon |
||||
*/ |
||||
public class Grayscale16BitHeightMap extends AbstractHeightMap { |
||||
|
||||
private BufferedImage image; |
||||
|
||||
public Grayscale16BitHeightMap() { |
||||
} |
||||
|
||||
public Grayscale16BitHeightMap(BufferedImage image) { |
||||
this.image = image; |
||||
} |
||||
|
||||
public Grayscale16BitHeightMap(String filename) { |
||||
this(new File(filename)); |
||||
} |
||||
|
||||
public Grayscale16BitHeightMap(File file) { |
||||
try { |
||||
this.image = ImageIO.read(file); |
||||
} catch (IOException ex) { |
||||
Logger.getLogger(Grayscale16BitHeightMap.class.getName()).log(Level.SEVERE, null, ex); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean load() { |
||||
return load(false, false); |
||||
} |
||||
|
||||
public boolean load(boolean flipX, boolean flipY) { |
||||
int imageWidth = image.getWidth(); |
||||
int imageHeight = image.getHeight(); |
||||
|
||||
if (imageWidth != imageHeight) { |
||||
throw new RuntimeException("imageWidth: " + imageWidth |
||||
+ " != imageHeight: " + imageHeight); |
||||
} |
||||
|
||||
Object out = new short[imageWidth * imageHeight]; |
||||
out = image.getData().getDataElements(0, 0, imageWidth, imageHeight, out); |
||||
short[] values = (short[]) out; |
||||
heightData = new float[imageWidth * imageHeight]; |
||||
int i = 0; |
||||
for (int y = 0; y < imageHeight; y++) { |
||||
for (int x = 0; x < imageWidth; x++, i++) { |
||||
heightData[i] = heightScale * (values[i] & 0x0000FFFF) / 65536f; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,19 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.terrain.heightmap; |
||||
|
||||
import com.jme3.math.Vector3f; |
||||
|
||||
/** |
||||
* |
||||
* @author Anthyon |
||||
*/ |
||||
public interface HeightMapGrid { |
||||
|
||||
public HeightMap getHeightMapAt(Vector3f location); |
||||
|
||||
public void setSize(int size); |
||||
|
||||
} |
@ -0,0 +1,61 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package com.jme3.terrain.heightmap; |
||||
|
||||
import com.jme3.asset.AssetManager; |
||||
import com.jme3.asset.AssetNotFoundException; |
||||
import com.jme3.math.FastMath; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.texture.Texture; |
||||
import java.awt.image.BufferedImage; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import javax.imageio.ImageIO; |
||||
import jme3tools.converters.ImageToAwt; |
||||
|
||||
/** |
||||
* |
||||
* @author Anthyon |
||||
*/ |
||||
public class ImageBasedHeightMapGrid implements HeightMapGrid { |
||||
|
||||
private final String textureBase; |
||||
private final String textureExt; |
||||
private final AssetManager assetManager; |
||||
private int size; |
||||
|
||||
public ImageBasedHeightMapGrid(String textureBase, String textureExt, AssetManager assetManager) { |
||||
this.textureBase = textureBase; |
||||
this.textureExt = textureExt; |
||||
this.assetManager = assetManager; |
||||
} |
||||
|
||||
public HeightMap getHeightMapAt(Vector3f location) { |
||||
// HEIGHTMAP image (for the terrain heightmap)
|
||||
int x = (int) (FastMath.floor(location.x / this.size) * this.size); |
||||
int z = (int) (FastMath.floor(location.z / this.size) * this.size); |
||||
AbstractHeightMap heightmap = null; |
||||
try { |
||||
final InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(textureBase + "_" + x + "_" + z + "." + textureExt); |
||||
BufferedImage im = null; |
||||
if (stream != null) { |
||||
im = ImageIO.read(stream); |
||||
} else { |
||||
im = new BufferedImage(size, size, BufferedImage.TYPE_USHORT_GRAY); |
||||
} |
||||
// CREATE HEIGHTMAP
|
||||
heightmap = new Grayscale16BitHeightMap(im); |
||||
heightmap.setHeightScale(256); |
||||
heightmap.load(); |
||||
} catch (IOException e) { |
||||
} catch (AssetNotFoundException e) { |
||||
} |
||||
return heightmap; |
||||
} |
||||
|
||||
public void setSize(int size) { |
||||
this.size = size - 1; |
||||
} |
||||
} |
After Width: | Height: | Size: 444 KiB |
After Width: | Height: | Size: 437 KiB |
After Width: | Height: | Size: 424 KiB |
After Width: | Height: | Size: 358 KiB |
After Width: | Height: | Size: 370 KiB |
After Width: | Height: | Size: 415 KiB |
After Width: | Height: | Size: 438 KiB |
After Width: | Height: | Size: 430 KiB |
After Width: | Height: | Size: 420 KiB |
After Width: | Height: | Size: 445 KiB |
After Width: | Height: | Size: 395 KiB |
After Width: | Height: | Size: 410 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 420 KiB |
After Width: | Height: | Size: 442 KiB |
After Width: | Height: | Size: 336 KiB |
After Width: | Height: | Size: 444 KiB |
After Width: | Height: | Size: 428 KiB |
After Width: | Height: | Size: 374 KiB |
After Width: | Height: | Size: 428 KiB |
After Width: | Height: | Size: 420 KiB |
After Width: | Height: | Size: 436 KiB |
After Width: | Height: | Size: 450 KiB |
After Width: | Height: | Size: 446 KiB |
After Width: | Height: | Size: 436 KiB |
After Width: | Height: | Size: 429 KiB |
After Width: | Height: | Size: 416 KiB |
After Width: | Height: | Size: 430 KiB |
After Width: | Height: | Size: 432 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 424 KiB |
After Width: | Height: | Size: 439 KiB |
After Width: | Height: | Size: 426 KiB |
After Width: | Height: | Size: 432 KiB |
After Width: | Height: | Size: 338 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 422 KiB |
After Width: | Height: | Size: 425 KiB |
After Width: | Height: | Size: 424 KiB |
After Width: | Height: | Size: 381 KiB |
@ -0,0 +1,184 @@ |
||||
package jme3test.terrain; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import com.jme3.app.SimpleApplication; |
||||
import com.jme3.app.state.ScreenshotAppState; |
||||
import com.jme3.bullet.BulletAppState; |
||||
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape; |
||||
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; |
||||
import com.jme3.bullet.control.CharacterControl; |
||||
import com.jme3.bullet.control.RigidBodyControl; |
||||
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.ColorRGBA; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.renderer.Camera; |
||||
import com.jme3.terrain.geomipmap.TerrainGrid; |
||||
import com.jme3.terrain.geomipmap.TerrainLodControl; |
||||
import com.jme3.terrain.geomipmap.TerrainQuad; |
||||
import com.jme3.terrain.heightmap.ImageBasedHeightMapGrid; |
||||
import com.jme3.texture.Texture; |
||||
import com.jme3.texture.Texture.WrapMode; |
||||
|
||||
public class TerrainGridTest extends SimpleApplication { |
||||
|
||||
private Material mat_terrain; |
||||
private TerrainQuad terrain; |
||||
private float grassScale = 64; |
||||
private float dirtScale = 16; |
||||
private float rockScale = 128; |
||||
|
||||
public static void main(final String[] args) { |
||||
TerrainGridTest app = new TerrainGridTest(); |
||||
app.start(); |
||||
} |
||||
private CharacterControl player3; |
||||
|
||||
@Override |
||||
public void simpleInitApp() { |
||||
this.flyCam.setMoveSpeed(100f); |
||||
ScreenshotAppState state = new ScreenshotAppState(); |
||||
this.stateManager.attach(state); |
||||
|
||||
// TERRAIN TEXTURE material
|
||||
mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); |
||||
mat_terrain.setBoolean("useTriPlanarMapping", false); |
||||
|
||||
// ALPHA map (for splat textures)
|
||||
mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); |
||||
|
||||
// GRASS texture
|
||||
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); |
||||
grass.setWrap(WrapMode.Repeat); |
||||
mat_terrain.setTexture("Tex1", grass); |
||||
mat_terrain.setFloat("Tex1Scale", grassScale); |
||||
|
||||
// DIRT texture
|
||||
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); |
||||
dirt.setWrap(WrapMode.Repeat); |
||||
mat_terrain.setTexture("Tex2", dirt); |
||||
mat_terrain.setFloat("Tex2Scale", dirtScale); |
||||
|
||||
// ROCK texture
|
||||
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); |
||||
rock.setWrap(WrapMode.Repeat); |
||||
mat_terrain.setTexture("Tex3", rock); |
||||
mat_terrain.setFloat("Tex3Scale", rockScale); |
||||
|
||||
this.terrain = new TerrainGrid("terrain", 65, 1025, new ImageBasedHeightMapGrid("Textures/Terrain/grid/mountains", "png", |
||||
this.assetManager)); |
||||
|
||||
this.terrain.setMaterial(this.mat_terrain); |
||||
this.terrain.setLocalTranslation(0, 0, 0); |
||||
this.terrain.setLocalScale(2f, 1f, 2f); |
||||
this.rootNode.attachChild(this.terrain); |
||||
|
||||
List<Camera> cameras = new ArrayList<Camera>(); |
||||
cameras.add(this.getCamera()); |
||||
TerrainLodControl control = new TerrainLodControl(this.terrain, cameras); |
||||
this.terrain.addControl(control); |
||||
|
||||
BulletAppState bulletAppState = new BulletAppState(); |
||||
stateManager.attach(bulletAppState); |
||||
|
||||
RigidBodyControl body = new RigidBodyControl(new HeightfieldCollisionShape(terrain.getHeightMap(), terrain.getLocalScale()), 0); |
||||
terrain.addControl(body); |
||||
bulletAppState.getPhysicsSpace().add(terrain); |
||||
|
||||
this.getCamera().setLocation(new Vector3f(0, 256, 0)); |
||||
|
||||
this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f)); |
||||
|
||||
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1); |
||||
this.player3 = new CharacterControl(capsuleShape, 0.5f); |
||||
this.player3.setJumpSpeed(20); |
||||
this.player3.setFallSpeed(30); |
||||
this.player3.setGravity(30); |
||||
|
||||
this.player3.setPhysicsLocation(new Vector3f(0, 256, 0)); |
||||
|
||||
bulletAppState.getPhysicsSpace().add(this.player3); |
||||
|
||||
this.initKeys(); |
||||
} |
||||
|
||||
private void initKeys() { |
||||
// You can map one or several inputs to one named action
|
||||
this.inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A)); |
||||
this.inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D)); |
||||
this.inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W)); |
||||
this.inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S)); |
||||
this.inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE)); |
||||
this.inputManager.addMapping("Gravity", new KeyTrigger(KeyInput.KEY_G)); |
||||
this.inputManager.addListener(this.actionListener, "Lefts"); |
||||
this.inputManager.addListener(this.actionListener, "Rights"); |
||||
this.inputManager.addListener(this.actionListener, "Ups"); |
||||
this.inputManager.addListener(this.actionListener, "Downs"); |
||||
this.inputManager.addListener(this.actionListener, "Jumps"); |
||||
this.inputManager.addListener(this.actionListener, "Gravity"); |
||||
} |
||||
private boolean left; |
||||
private boolean right; |
||||
private boolean up; |
||||
private boolean down; |
||||
private final ActionListener actionListener = new ActionListener() { |
||||
|
||||
@Override |
||||
public void onAction(final String name, final boolean keyPressed, final float tpf) { |
||||
if (name.equals("Lefts")) { |
||||
if (keyPressed) { |
||||
TerrainGridTest.this.left = true; |
||||
} else { |
||||
TerrainGridTest.this.left = false; |
||||
} |
||||
} else if (name.equals("Rights")) { |
||||
if (keyPressed) { |
||||
TerrainGridTest.this.right = true; |
||||
} else { |
||||
TerrainGridTest.this.right = false; |
||||
} |
||||
} else if (name.equals("Ups")) { |
||||
if (keyPressed) { |
||||
TerrainGridTest.this.up = true; |
||||
} else { |
||||
TerrainGridTest.this.up = false; |
||||
} |
||||
} else if (name.equals("Downs")) { |
||||
if (keyPressed) { |
||||
TerrainGridTest.this.down = true; |
||||
} else { |
||||
TerrainGridTest.this.down = false; |
||||
} |
||||
} else if (name.equals("Jumps")) { |
||||
TerrainGridTest.this.player3.jump(); |
||||
} |
||||
} |
||||
}; |
||||
private final Vector3f walkDirection = new Vector3f(); |
||||
|
||||
@Override |
||||
public void simpleUpdate(final float tpf) { |
||||
Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f); |
||||
Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f); |
||||
this.walkDirection.set(0, 0, 0); |
||||
if (this.left) { |
||||
this.walkDirection.addLocal(camLeft); |
||||
} |
||||
if (this.right) { |
||||
this.walkDirection.addLocal(camLeft.negate()); |
||||
} |
||||
if (this.up) { |
||||
this.walkDirection.addLocal(camDir); |
||||
} |
||||
if (this.down) { |
||||
this.walkDirection.addLocal(camDir.negate()); |
||||
} |
||||
|
||||
this.player3.setWalkDirection(this.walkDirection); |
||||
this.cam.setLocation(this.player3.getPhysicsLocation()); |
||||
} |
||||
} |