- add abstraction layer for TerrainGrid that allows serving in full TerrainQuads
- add serialization to TerrainGrid - add AssetQuadGrid loading TerrainQuads from j3o files (WIP) git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8677 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
b53c8737c0
commit
fc23b0173e
@ -31,10 +31,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.terrain.geomipmap;
|
package com.jme3.terrain.geomipmap;
|
||||||
|
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.scene.control.UpdateControl;
|
import com.jme3.scene.control.UpdateControl;
|
||||||
import com.jme3.bullet.PhysicsSpace;
|
import com.jme3.bullet.PhysicsSpace;
|
||||||
import com.jme3.bullet.control.RigidBodyControl;
|
import com.jme3.bullet.control.RigidBodyControl;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
import com.jme3.terrain.heightmap.HeightMap;
|
import com.jme3.terrain.heightmap.HeightMap;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -101,6 +106,7 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
protected int quarterSize;
|
protected int quarterSize;
|
||||||
protected int quadSize;
|
protected int quadSize;
|
||||||
protected HeightMapGrid heightMapGrid;
|
protected HeightMapGrid heightMapGrid;
|
||||||
|
protected TerrainQuadGrid terrainQuadGrid;
|
||||||
protected Vector3f[] quadIndex;
|
protected Vector3f[] quadIndex;
|
||||||
protected Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
protected Map<String, TerrainGridListener> listeners = new HashMap<String, TerrainGridListener>();
|
||||||
protected Material material;
|
protected Material material;
|
||||||
@ -134,11 +140,17 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
final Vector3f temp = location.add(quadIndex[quadIdx]);
|
final Vector3f temp = location.add(quadIndex[quadIdx]);
|
||||||
TerrainQuad q = cache.get(temp);
|
TerrainQuad q = cache.get(temp);
|
||||||
if (q == null) {
|
if (q == null) {
|
||||||
// create the new Quad since it doesn't exist
|
if (heightMapGrid != null) {
|
||||||
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
// create the new Quad since it doesn't exist
|
||||||
q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap());
|
HeightMap heightMapAt = heightMapGrid.getHeightMapAt(temp);
|
||||||
q.setMaterial(material.clone());
|
q = new TerrainQuad(getName() + "Quad" + temp, patchSize, quadSize, heightMapAt == null ? null : heightMapAt.getHeightMap());
|
||||||
log.log(Level.FINE, "Loaded TerrainQuad {0}", q.getName());
|
q.setMaterial(material.clone());
|
||||||
|
log.log(Level.FINE, "Loaded TerrainQuad {0} from HeightMapGrid", q.getName());
|
||||||
|
} else if (terrainQuadGrid != null) {
|
||||||
|
q = terrainQuadGrid.getTerrainQuadAt(location);
|
||||||
|
q.setMaterial(material);
|
||||||
|
log.log(Level.FINE, "Loaded TerrainQuad {0} from TerrainQuadGrid", q.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cache.put(temp, q);
|
cache.put(temp, q);
|
||||||
|
|
||||||
@ -179,6 +191,50 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
return 0; // error
|
return 0; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: unify constructors
|
||||||
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, TerrainQuadGrid terrainQuadGrid,
|
||||||
|
Vector2f offset, float offsetAmount) {
|
||||||
|
this.name = name;
|
||||||
|
this.patchSize = patchSize;
|
||||||
|
this.size = maxVisibleSize;
|
||||||
|
this.quarterSize = maxVisibleSize >> 2;
|
||||||
|
this.quadSize = (maxVisibleSize + 1) >> 1;
|
||||||
|
this.stepScale = scale;
|
||||||
|
this.terrainQuadGrid = terrainQuadGrid;
|
||||||
|
terrainQuadGrid.setSize(this.size);
|
||||||
|
terrainQuadGrid.setPatchSize(this.patchSize);
|
||||||
|
terrainQuadGrid.setQuadSize(this.quadSize);
|
||||||
|
this.totalSize = maxVisibleSize;
|
||||||
|
this.offset = offset;
|
||||||
|
this.offsetAmount = offsetAmount;
|
||||||
|
this.gridOffset = new int[]{0, 0};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -z
|
||||||
|
* |
|
||||||
|
* 1|3
|
||||||
|
* -x ----+---- x
|
||||||
|
* 2|4
|
||||||
|
* |
|
||||||
|
* z
|
||||||
|
*/
|
||||||
|
this.quadIndex = new Vector3f[]{
|
||||||
|
new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(2, 0, -1),
|
||||||
|
new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
||||||
|
new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
||||||
|
new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2)};
|
||||||
|
|
||||||
|
addControl(new UpdateControl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, TerrainQuadGrid terrainQuadGrid) {
|
||||||
|
this(name, patchSize, maxVisibleSize, scale, terrainQuadGrid, new Vector2f(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, TerrainQuadGrid terrainQuadGrid) {
|
||||||
|
this(name, patchSize, maxVisibleSize, Vector3f.UNIT_XYZ, terrainQuadGrid);
|
||||||
|
}
|
||||||
|
|
||||||
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
public TerrainGrid(String name, int patchSize, int maxVisibleSize, Vector3f scale, HeightMapGrid heightMapGrid,
|
||||||
Vector2f offset, float offsetAmount) {
|
Vector2f offset, float offsetAmount) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -192,8 +248,8 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
this.totalSize = maxVisibleSize;
|
this.totalSize = maxVisibleSize;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.offsetAmount = offsetAmount;
|
this.offsetAmount = offsetAmount;
|
||||||
this.gridOffset = new int[]{0,0};
|
this.gridOffset = new int[]{0, 0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -z
|
* -z
|
||||||
* |
|
* |
|
||||||
@ -204,10 +260,10 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
* z
|
* z
|
||||||
*/
|
*/
|
||||||
this.quadIndex = new Vector3f[]{
|
this.quadIndex = new Vector3f[]{
|
||||||
new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(2, 0, -1),
|
new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(2, 0, -1),
|
||||||
new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
||||||
new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
||||||
new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2)};
|
new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2)};
|
||||||
|
|
||||||
addControl(new UpdateControl());
|
addControl(new UpdateControl());
|
||||||
}
|
}
|
||||||
@ -242,10 +298,10 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
// 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
|
// 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 cam = locations.get(0);
|
||||||
Vector3f camCell = this.getCamCell(cam); // get the grid index value of where the camera is (ie. 2,1)
|
Vector3f camCell = this.getCamCell(cam); // get the grid index value of where the camera is (ie. 2,1)
|
||||||
if(cellsLoaded>1){ // Check if cells are updated before updating gridoffset.
|
if (cellsLoaded > 1) { // Check if cells are updated before updating gridoffset.
|
||||||
gridOffset[0] = Math.round(camCell.x*(size/2));
|
gridOffset[0] = Math.round(camCell.x * (size / 2));
|
||||||
gridOffset[1] = Math.round(camCell.z*(size/2));
|
gridOffset[1] = Math.round(camCell.z * (size / 2));
|
||||||
cellsLoaded=0;
|
cellsLoaded = 0;
|
||||||
}
|
}
|
||||||
if (camCell.x != this.currentCamCell.x || camCell.z != currentCamCell.z) {
|
if (camCell.x != this.currentCamCell.x || camCell.z != currentCamCell.z) {
|
||||||
// if the camera has moved into a new cell, load new terrain into the visible 4 center quads
|
// if the camera has moved into a new cell, load new terrain into the visible 4 center quads
|
||||||
@ -263,7 +319,7 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
Vector3f shifted = tile.subtract(offsetHalf);
|
Vector3f shifted = tile.subtract(offsetHalf);
|
||||||
return new Vector3f(FastMath.floor(shifted.x), 0, FastMath.floor(shifted.z));
|
return new Vector3f(FastMath.floor(shifted.x), 0, FastMath.floor(shifted.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Centered at 0,0.
|
* Centered at 0,0.
|
||||||
* Get the tile index location in integer form:
|
* Get the tile index location in integer form:
|
||||||
@ -292,7 +348,7 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
*/
|
*/
|
||||||
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
protected void attachQuadAt(TerrainQuad q, int quadrant, Vector3f cam) {
|
||||||
this.removeQuad(quadrant);
|
this.removeQuad(quadrant);
|
||||||
|
|
||||||
q.setQuadrant((short) quadrant);
|
q.setQuadrant((short) quadrant);
|
||||||
this.attachChild(q);
|
this.attachChild(q);
|
||||||
|
|
||||||
@ -318,7 +374,7 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
* @param camCell the cell the camera is in
|
* @param camCell the cell the camera is in
|
||||||
*/
|
*/
|
||||||
protected void updateChildrens(Vector3f camCell) {
|
protected void updateChildrens(Vector3f camCell) {
|
||||||
|
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
if (currentCamCell != null) {
|
if (currentCamCell != null) {
|
||||||
@ -394,10 +450,61 @@ public class TerrainGrid extends TerrainQuad {
|
|||||||
}
|
}
|
||||||
super.adjustHeight(xz, height);
|
super.adjustHeight(xz, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getHeightmapHeight(int x, int z) {
|
protected float getHeightmapHeight(int x, int z) {
|
||||||
return super.getHeightmapHeight(x-gridOffset[0], z-gridOffset[1]);
|
return super.getHeightmapHeight(x - gridOffset[0], z - gridOffset[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
super.read(im);
|
||||||
|
InputCapsule c = im.getCapsule(this);
|
||||||
|
name = c.readString("name", null);
|
||||||
|
size = c.readInt("size", 0);
|
||||||
|
patchSize = c.readInt("patchSize", 0);
|
||||||
|
stepScale = (Vector3f) c.readSavable("stepScale", null);
|
||||||
|
offset = (Vector2f) c.readSavable("offset", null);
|
||||||
|
offsetAmount = c.readFloat("offsetAmount", 0);
|
||||||
|
terrainQuadGrid = (TerrainQuadGrid) c.readSavable("terrainQuadGrid", null);
|
||||||
|
// terrainQuadGrid.setSize(this.size);
|
||||||
|
// terrainQuadGrid.setPatchSize(this.patchSize);
|
||||||
|
// terrainQuadGrid.setQuadSize(this.quadSize);
|
||||||
|
|
||||||
|
int maxVisibleSize = size;
|
||||||
|
this.quarterSize = maxVisibleSize >> 2;
|
||||||
|
this.quadSize = (maxVisibleSize + 1) >> 1;
|
||||||
|
this.totalSize = maxVisibleSize;
|
||||||
|
|
||||||
|
this.gridOffset = new int[]{0, 0};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -z
|
||||||
|
* |
|
||||||
|
* 1|3
|
||||||
|
* -x ----+---- x
|
||||||
|
* 2|4
|
||||||
|
* |
|
||||||
|
* z
|
||||||
|
*/
|
||||||
|
this.quadIndex = new Vector3f[]{
|
||||||
|
new Vector3f(-1, 0, -1), new Vector3f(0, 0, -1), new Vector3f(1, 0, -1), new Vector3f(2, 0, -1),
|
||||||
|
new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 0, 0), new Vector3f(2, 0, 0),
|
||||||
|
new Vector3f(-1, 0, 1), new Vector3f(0, 0, 1), new Vector3f(1, 0, 1), new Vector3f(2, 0, 1),
|
||||||
|
new Vector3f(-1, 0, 2), new Vector3f(0, 0, 2), new Vector3f(1, 0, 2), new Vector3f(2, 0, 2)};
|
||||||
|
|
||||||
|
addControl(new UpdateControl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
super.write(ex);
|
||||||
|
OutputCapsule c = ex.getCapsule(this);
|
||||||
|
c.write(terrainQuadGrid, "terrainQuadGrid", null);
|
||||||
|
c.write(size, "size", 0);
|
||||||
|
c.write(patchSize, "patchSize", 0);
|
||||||
|
c.write(stepScale, "stepScale", null);
|
||||||
|
c.write(offset, "offset", null);
|
||||||
|
c.write(offsetAmount, "offsetAmount", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.terrain.geomipmap;
|
||||||
|
|
||||||
|
import com.jme3.export.Savable;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author normenhansen
|
||||||
|
*/
|
||||||
|
public interface TerrainQuadGrid extends Savable {
|
||||||
|
|
||||||
|
public TerrainQuad getTerrainQuadAt(Vector3f location);
|
||||||
|
|
||||||
|
public void setSize(int size);
|
||||||
|
|
||||||
|
public void setPatchSize(int patchSize);
|
||||||
|
|
||||||
|
public void setQuadSize(int quadSize);
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.terrain.geomipmap.grid;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainQuad;
|
||||||
|
import com.jme3.terrain.geomipmap.TerrainQuadGrid;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author normenhansen
|
||||||
|
*/
|
||||||
|
public class AssetQuadGrid implements TerrainQuadGrid {
|
||||||
|
|
||||||
|
private AssetManager manager;
|
||||||
|
private String assetPath;
|
||||||
|
private String name;
|
||||||
|
private int size;
|
||||||
|
private int patchSize;
|
||||||
|
private int quadSize;
|
||||||
|
|
||||||
|
public AssetQuadGrid() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AssetQuadGrid(AssetManager manager, String name, String assetPath, int size, int patchSize, int quadSize) {
|
||||||
|
this.manager = manager;
|
||||||
|
this.name = name;
|
||||||
|
this.assetPath = assetPath;
|
||||||
|
this.size = size;
|
||||||
|
this.patchSize = patchSize;
|
||||||
|
this.quadSize = quadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerrainQuad getTerrainQuadAt(Vector3f location) {
|
||||||
|
TerrainQuad quad = (TerrainQuad) manager.loadModel(assetPath + "/" + name + "-" + Math.round(location.x) + "/" + Math.round(location.y) + "/" + Math.round(location.z));
|
||||||
|
if (quad == null) {
|
||||||
|
createNewQuad(location);
|
||||||
|
}
|
||||||
|
return quad;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPatchSize(int patchSize) {
|
||||||
|
this.patchSize = patchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuadSize(int quadSize) {
|
||||||
|
this.quadSize = quadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TerrainQuad createNewQuad(Vector3f location) {
|
||||||
|
TerrainQuad q = new TerrainQuad("Quad" + location, patchSize, quadSize, null);
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
OutputCapsule c = ex.getCapsule(this);
|
||||||
|
c.write(assetPath, "assetPath", null);
|
||||||
|
c.write(size, "size", 0);
|
||||||
|
c.write(name, "name", null);
|
||||||
|
c.write(patchSize, "patchSize", 0);
|
||||||
|
c.write(quadSize, "quadSize", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
InputCapsule c = im.getCapsule(this);
|
||||||
|
manager = im.getAssetManager();
|
||||||
|
assetPath = c.readString("assetPath", null);
|
||||||
|
name = c.readString("name", null);
|
||||||
|
size = c.readInt("size", 0);
|
||||||
|
patchSize = c.readInt("patchSize", 0);
|
||||||
|
quadSize = c.readInt("quadSize", 0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user