Hi,
im programming a network based simulation game. So the terrain is downloaded from the sever in 64x64 chunks (as hightmap). This hightmap gets interpolated so i have 128x128 and i used Terrain Grid to display the terrain. All is like i want so far. With one Chunk
Now i want to display multiple chunks. Depending on the Kamera Position the chunks are loaded from the server and added to a custom node. But I can’t see anything. I see the polygon count getting bigger. I added a cube to the scene. That is displayed correctly.
Any suggestions?
(tile = chunk - we had to refactor)
[java]package conveyance.client.map;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.terrain.heightmap.HeightMap;
import conveyance.common.messages.MapUpdate;
import conveyance.common.types.TileCoordinate;
import java.util.List;
/**
*
-
@author Drummer
/
public class NetworkTerrainControl extends AbstractControl implements TileProvider.TileupdateListener{
List<Camera> cameras;
float distanceInMemory;
float sqrDistanceInMemory;
TileProvider tileprovider;
TileBasedTerrain terrain;
public NetworkTerrainControl(TileProvider tileprovider, List<Camera> cameras, float distanceInMemory) {
this.tileprovider = tileprovider;
this.cameras = cameras;
this.distanceInMemory = distanceInMemory;
this.sqrDistanceInMemory = distanceInMemorydistanceInMemory;
}
private NetworkTerrainControl(NetworkTerrainControl n) {
this.terrain = n.terrain;
this.tileprovider = n.tileprovider;
this.cameras = n.cameras;
this.distanceInMemory = n.distanceInMemory;
this.sqrDistanceInMemory = n.sqrDistanceInMemory;
}
@Override
protected void controlUpdate(float tpf) {
for (Camera camera : cameras) {
Vector3f cloc = camera.getLocation().clone();
cloc.y = 0.0f;
int x = (int)cloc.x;
int z = (int)cloc.z;
int dist = (int)FastMath.ceil(distanceInMemory);
for (int i = x-dist; i < x+dist; i++) {
for (int j = z-dist; j < z+dist; j++) {
if (!terrain.containsQuad(i, j)
&& i>=0 && j>=0) {
tileprovider.requestTile(new TileCoordinate(i, j));
}
}
//TODO remove tiles
//Math.floor(-0.5);
}
}
}
public void tileUpdate(HeightMap h, TileCoordinate t) {
terrain.addQuad(h, t.getX(), t.getZ());
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
public Control cloneForSpatial(Spatial spatial) {
NetworkTerrainControl n = new NetworkTerrainControl(this);
setSpatial(spatial);
n.terrain = (TileBasedTerrain)spatial;
return n;
}
@Override
public void setSpatial(Spatial spatial) {
if (!(spatial instanceof TileBasedTerrain))
throw new IllegalArgumentException("only for TileBasedTerrain");
super.setSpatial(spatial);
terrain = (TileBasedTerrain)spatial;
}
}[/java]
[java]
package conveyance.client.map;
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.geomipmap.lodcalc.DistanceLodCalculator;
import com.jme3.terrain.heightmap.HeightMap;
import java.util.HashMap;
import java.util.List;
/**
*
-
@author Drummer
*/
public class TileBasedTerrain extends Node{
int patchSize;
int size;
Vector3f scale;
HashMap<Long, TileBasedTerrainQuad> quads; //Key: concatinated x and y coordinates of the tile
float lodMultiplicator;
List<Camera> cameras;
Material material;
public TileBasedTerrain(String name, int patchSize, int size, Vector3f scale, float lodMultiplicator, List<Camera> cameras) {
super(name);
quads = new HashMap<Long, TileBasedTerrainQuad>();
this.lodMultiplicator = lodMultiplicator;
this.cameras = cameras;
}
public TileBasedTerrainQuad getQuad(int x, int z) {
return quads.get((long)x<<Integer.SIZE +z);
}
public void addQuad(HeightMap h, int x, int z) {
TileBasedTerrainQuad q = new TileBasedTerrainQuad(x, z,
"terrain (" + x + ", " + z + ")",
patchSize, size, scale, h.getHeightMap());
quads.put((long)x<<Integer.SIZE +z, q);
q.setMaterial(material);
TerrainLodControl control = new TerrainLodControl(q, cameras);
control.setLodCalculator(new DistanceLodCalculator(patchSize, lodMultiplicator)); // patch size, and a multiplier
q.addControl(control);
attachChild(q);
}
public void removeQuad(int x, int z) {
TileBasedTerrainQuad q = quads.remove((long)x<<Integer.SIZE +z);
if (q != null)
detachChild(q);
}
public boolean containsQuad(int x, int z) {
return quads.containsKey((long)x<<Integer.SIZE +z);
}
public HashMap<Long, TileBasedTerrainQuad> getQuads() {
return quads;
}
@Override
public void setMaterial(Material mat) {
material = mat;
super.setMaterial(mat);
}
}
[/java]
[java]package conveyance.client.map;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.terrain.geomipmap.TerrainQuad;
/**
*
-
@author Drummer
*/
public class TileBasedTerrainQuad extends TerrainQuad{
private final int positionX;
private final int positionZ;
public TileBasedTerrainQuad(int x, int z, String name, int patchSize, int size, Vector3f scale, float[] heightMap) {
super(name, patchSize, size, scale, heightMap);
this.positionX = x;
this.positionZ = z;
setLocalTranslation(x, 0, z);
}
@Override
protected TerrainQuad findDownQuad() {
Node parent = getParent();
if (parent == null)
return null;
if (!(parent instanceof TileBasedTerrain ))
return super.findDownQuad();
TileBasedTerrain t = (TileBasedTerrain)parent;
return t.getQuad(positionX, positionZ - 1);
}
@Override
protected TerrainQuad findLeftQuad() {
Node parent = getParent();
if (parent == null)
return null;
if (!(parent instanceof TileBasedTerrain ))
return super.findLeftQuad();
TileBasedTerrain t = (TileBasedTerrain)parent;
return t.getQuad(positionX + 1, positionZ);
}
@Override
protected TerrainQuad findRightQuad() {
Node parent = getParent();
if (parent == null)
return null;
if (!(parent instanceof TileBasedTerrain ))
return super.findRightQuad();
TileBasedTerrain t = (TileBasedTerrain)parent;
return t.getQuad(positionX - 1, positionZ);
}
@Override
protected TerrainQuad findTopQuad() {
Node parent = getParent();
if (parent == null)
return null;
if (!(parent instanceof TileBasedTerrain ))
return super.findTopQuad();
TileBasedTerrain t = (TileBasedTerrain)parent;
return t.getQuad(positionX, positionZ + 1);
}
}[/java]