- improve AssetQuadGrid

- add test for TerrainQuadGrid
- add test data for TerrainGrid

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8678 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
nor..67 2011-11-15 19:36:44 +00:00
parent fc23b0173e
commit 4105689fea
21 changed files with 268 additions and 26 deletions

@ -13,6 +13,8 @@ import com.jme3.math.Vector3f;
import com.jme3.terrain.geomipmap.TerrainQuad; import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.geomipmap.TerrainQuadGrid; import com.jme3.terrain.geomipmap.TerrainQuadGrid;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* *
@ -30,19 +32,26 @@ public class AssetQuadGrid implements TerrainQuadGrid {
public AssetQuadGrid() { public AssetQuadGrid() {
} }
public AssetQuadGrid(AssetManager manager, String name, String assetPath, int size, int patchSize, int quadSize) { public AssetQuadGrid(AssetManager manager, String name, String assetPath) {
this.manager = manager; this.manager = manager;
this.name = name; this.name = name;
this.assetPath = assetPath; this.assetPath = assetPath;
this.size = size;
this.patchSize = patchSize;
this.quadSize = quadSize;
} }
public TerrainQuad getTerrainQuadAt(Vector3f location) { public TerrainQuad getTerrainQuadAt(Vector3f location) {
TerrainQuad quad = (TerrainQuad) manager.loadModel(assetPath + "/" + name + "-" + Math.round(location.x) + "/" + Math.round(location.y) + "/" + Math.round(location.z)); String modelName = assetPath + "/" + name + "_" + Math.round(location.x) + "_" + Math.round(location.y) + "_" + Math.round(location.z) + ".j3o";
Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Load terrain grid tile: {0}", modelName);
TerrainQuad quad = null;
try {
quad = (TerrainQuad) manager.loadModel(modelName);
} catch (Exception e) {
// e.printStackTrace();
}
if (quad == null) { if (quad == null) {
createNewQuad(location); Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Could not load terrain grid tile: {0}", modelName);
quad = createNewQuad(location);
} else {
Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Loaded terrain grid tile: {0}", modelName);
} }
return quad; return quad;
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,8 +1,6 @@
package jme3test.terrain; package jme3test.terrain;
import com.jme3.terrain.geomipmap.TerrainQuad; import com.jme3.terrain.geomipmap.TerrainQuad;
import java.util.ArrayList;
import java.util.List;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.app.state.ScreenshotAppState; import com.jme3.app.state.ScreenshotAppState;
@ -11,14 +9,13 @@ import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.control.CharacterControl; import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl; import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.terrain.geomipmap.TerrainGrid; import com.jme3.terrain.geomipmap.TerrainGrid;
import com.jme3.terrain.geomipmap.TerrainGridListener; import com.jme3.terrain.geomipmap.TerrainGridListener;
import com.jme3.terrain.geomipmap.TerrainLodControl; import com.jme3.terrain.geomipmap.TerrainLodControl;
@ -26,6 +23,10 @@ import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.terrain.heightmap.FractalHeightMapGrid; import com.jme3.terrain.heightmap.FractalHeightMapGrid;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode; import com.jme3.texture.Texture.WrapMode;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.novyon.noise.ShaderUtils; import org.novyon.noise.ShaderUtils;
import org.novyon.noise.basis.FilteredBasis; import org.novyon.noise.basis.FilteredBasis;
import org.novyon.noise.filter.IterativeFilter; import org.novyon.noise.filter.IterativeFilter;
@ -176,6 +177,13 @@ public class TerrainFractalGridTest extends SimpleApplication {
} }
public void tileAttached(Vector3f cell, TerrainQuad quad) { public void tileAttached(Vector3f cell, TerrainQuad quad) {
//uncomment to create data for TerrainQuadGridTest
// try {
// BinaryExporter.getInstance().save(quad, new File("/Users/normenhansen/Documents/Code/jme3/engine/src/test-data/TerrainGrid/"
// + "testgrid_" + Math.round(cell.x) + "_" + Math.round(cell.y) + "_" + Math.round(cell.z) + ".j3o"));
// } catch (IOException ex) {
// Logger.getLogger(TerrainFractalGridTest.class.getName()).log(Level.SEVERE, null, ex);
// }
quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0)); quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
bulletAppState.getPhysicsSpace().add(quad); bulletAppState.getPhysicsSpace().add(quad);
} }
@ -184,7 +192,6 @@ public class TerrainFractalGridTest extends SimpleApplication {
bulletAppState.getPhysicsSpace().remove(quad); bulletAppState.getPhysicsSpace().remove(quad);
quad.removeControl(RigidBodyControl.class); quad.removeControl(RigidBodyControl.class);
} }
}); });
} }
this.terrain.initialize(cam.getLocation()); this.terrain.initialize(cam.getLocation());
@ -247,21 +254,21 @@ public class TerrainFractalGridTest extends SimpleApplication {
@Override @Override
public void simpleUpdate(final float tpf) { public void simpleUpdate(final float tpf) {
Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f); Vector3f camDir = this.cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f); Vector3f camLeft = this.cam.getLeft().clone().multLocal(0.4f);
this.walkDirection.set(0, 0, 0); this.walkDirection.set(0, 0, 0);
if (this.left) { if (this.left) {
this.walkDirection.addLocal(camLeft); this.walkDirection.addLocal(camLeft);
} }
if (this.right) { if (this.right) {
this.walkDirection.addLocal(camLeft.negate()); this.walkDirection.addLocal(camLeft.negate());
} }
if (this.up) { if (this.up) {
this.walkDirection.addLocal(camDir); this.walkDirection.addLocal(camDir);
} }
if (this.down) { if (this.down) {
this.walkDirection.addLocal(camDir.negate()); this.walkDirection.addLocal(camDir.negate());
} }
if (usePhysics) { if (usePhysics) {
this.player3.setWalkDirection(this.walkDirection); this.player3.setWalkDirection(this.walkDirection);

@ -0,0 +1,226 @@
package jme3test.terrain;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.ScreenshotAppState;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.asset.plugins.ZipLocator;
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.terrain.geomipmap.TerrainGrid;
import com.jme3.terrain.geomipmap.TerrainGridListener;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.geomipmap.grid.AssetQuadGrid;
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import java.io.File;
public class TerrainQuadGridTest extends SimpleApplication {
private Material mat_terrain;
private TerrainGrid terrain;
private float grassScale = 64;
private float dirtScale = 16;
private float rockScale = 128;
private boolean usePhysics = true;
private boolean physicsAdded = false;
public static void main(final String[] args) {
TerrainQuadGridTest app = new TerrainQuadGridTest();
app.start();
}
private CharacterControl player3;
@Override
public void simpleInitApp() {
File file = new File("mountains.zip");
if (!file.exists()) {
assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/mountains.zip", HttpZipLocator.class);
} else {
assetManager.registerLocator("mountains.zip", ZipLocator.class);
}
this.flyCam.setMoveSpeed(100f);
ScreenshotAppState state = new ScreenshotAppState();
this.stateManager.attach(state);
// TERRAIN TEXTURE material
this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
// Parameters to material:
// regionXColorMap: X = 1..4 the texture that should be appliad to state X
// regionX: a Vector3f containing the following information:
// regionX.x: the start height of the region
// regionX.y: the end height of the region
// regionX.z: the texture scale for the region
// it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
// slopeColorMap: the texture to be used for cliffs, and steep mountain sites
// slopeTileFactor: the texture scale for slopes
// terrainSize: the total size of the terrain (used for scaling the texture)
// GRASS texture
Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
this.mat_terrain.setTexture("region1ColorMap", grass);
this.mat_terrain.setVector3("region1", new Vector3f(88, 200, this.grassScale));
// DIRT texture
Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
this.mat_terrain.setTexture("region2ColorMap", dirt);
this.mat_terrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale));
// ROCK texture
Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
rock.setWrap(WrapMode.Repeat);
this.mat_terrain.setTexture("region3ColorMap", rock);
this.mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale));
this.mat_terrain.setTexture("region4ColorMap", rock);
this.mat_terrain.setVector3("region4", new Vector3f(198, 260, this.rockScale));
this.mat_terrain.setTexture("slopeColorMap", rock);
this.mat_terrain.setFloat("slopeTileFactor", 32);
this.mat_terrain.setFloat("terrainSize", 129);
//quad.getHeightMap(), terrain.getLocalScale()), 0
AssetQuadGrid grid = new AssetQuadGrid(assetManager, "testgrid", "TerrainGrid");
this.terrain = new TerrainGrid("terrain", 33, 129, grid);
this.terrain.setMaterial(this.mat_terrain);
this.terrain.setLocalTranslation(0, 0, 0);
this.terrain.setLocalScale(2f, 1f, 2f);
this.rootNode.attachChild(this.terrain);
TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera());
control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
this.terrain.addControl(control);
final BulletAppState bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
this.getCamera().setLocation(new Vector3f(0, 256, 0));
this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
if (usePhysics) {
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(0.5f, 1.8f, 1);
player3 = new CharacterControl(capsuleShape, 0.5f);
player3.setJumpSpeed(20);
player3.setFallSpeed(10);
player3.setGravity(10);
player3.setPhysicsLocation(new Vector3f(cam.getLocation().x, 256, cam.getLocation().z));
bulletAppState.getPhysicsSpace().add(player3);
terrain.addListener("physicsStartListener", new TerrainGridListener() {
public void gridMoved(Vector3f newCenter) {
}
public Material tileLoaded(Material material, Vector3f cell) {
return material;
}
public void tileAttached(Vector3f cell, TerrainQuad quad) {
quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrain.getLocalScale()), 0));
bulletAppState.getPhysicsSpace().add(quad);
}
public void tileDetached(Vector3f cell, TerrainQuad quad) {
bulletAppState.getPhysicsSpace().remove(quad);
quad.removeControl(RigidBodyControl.class);
}
});
}
this.terrain.initialize(cam.getLocation());
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.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");
}
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) {
TerrainQuadGridTest.this.left = true;
} else {
TerrainQuadGridTest.this.left = false;
}
} else if (name.equals("Rights")) {
if (keyPressed) {
TerrainQuadGridTest.this.right = true;
} else {
TerrainQuadGridTest.this.right = false;
}
} else if (name.equals("Ups")) {
if (keyPressed) {
TerrainQuadGridTest.this.up = true;
} else {
TerrainQuadGridTest.this.up = false;
}
} else if (name.equals("Downs")) {
if (keyPressed) {
TerrainQuadGridTest.this.down = true;
} else {
TerrainQuadGridTest.this.down = false;
}
} else if (name.equals("Jumps")) {
TerrainQuadGridTest.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());
}
if (usePhysics) {
this.player3.setWalkDirection(this.walkDirection);
this.cam.setLocation(this.player3.getPhysicsLocation());
}
}
}