world update routine based on chunk states
parent
6ea3fbc8aa
commit
ed45ddc12a
|
@ -35,16 +35,18 @@ public class Voxel extends SimpleApplication {
|
|||
|
||||
pos.set(this.getCamera().getLocation());
|
||||
worldManager.initWorld();
|
||||
// worldManager.benchmark();
|
||||
}
|
||||
public void simpleUpdate(float tpf) {
|
||||
pos.set(this.getCamera().getLocation());
|
||||
// if (!(pos.equals(oldCamPos))) System.out.println(pos);
|
||||
oldCamPos.set(pos);
|
||||
|
||||
worldManager.render();
|
||||
worldManager.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleRender(RenderManager rm) {
|
||||
worldManager.render();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ public class Config {
|
|||
public static int VOXEL_SIZE = 1 ;
|
||||
public static int CHUNK_LENGTH = CHUNK_SIZE * VOXEL_SIZE;
|
||||
|
||||
public static int HILBERT_BITS = 1;
|
||||
public static int HILBERT_BITS = 2;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import com.jme3.scene.Node;
|
|||
|
||||
public class Chunk {
|
||||
|
||||
public Vector3f pos;
|
||||
public int posx, posy, posz;
|
||||
public IntervalMap<Blocks> blocks = new IntervalMap<>();
|
||||
public Node chunkNode = new Node();
|
||||
// A bit field representing the state of the chunk, where each bit is an operation done on the chunk
|
||||
|
@ -19,12 +19,15 @@ public class Chunk {
|
|||
public static byte CHUNK_STATE_MESHED = 2;
|
||||
public static byte CHUNK_STATE_LOADED = 4;
|
||||
public Chunk() {
|
||||
this(Vector3f.ZERO);
|
||||
this(0,0,0);
|
||||
}
|
||||
|
||||
public Chunk(Vector3f pos_) {
|
||||
this.pos = pos_;
|
||||
chunkNode.setLocalTranslation(pos.mult(Config.CHUNK_SIZE).mult(Config.VOXEL_SIZE));
|
||||
public Chunk(int x_, int y_, int z_) {
|
||||
this.posx = x_;
|
||||
this.posy = y_;
|
||||
this.posz = z_;
|
||||
chunkNode.setLocalTranslation(posx, posy, posz);
|
||||
chunkNode.setLocalTranslation(chunkNode.getLocalTranslation().mult(Config.CHUNK_SIZE).mult(Config.VOXEL_SIZE));
|
||||
|
||||
// I still have to decided if this is necessary. With an empty tree this
|
||||
// takes O(1)
|
||||
|
|
|
@ -22,42 +22,20 @@ public class WorldManager {
|
|||
|
||||
Node worldNode = new Node();
|
||||
|
||||
ConcurrentHashMap<Vector3f, Chunk> chunks = new ConcurrentHashMap<>();
|
||||
ConcurrentHashMap<String, Chunk> chunks = new ConcurrentHashMap<>();
|
||||
|
||||
public WorldManager(final Voxel game_) {
|
||||
this.game = game_;
|
||||
}
|
||||
|
||||
public void initWorld() {
|
||||
// game.getRootNode().attachChild(worldNode);
|
||||
// System.out.println(Arrays.toString(game.getRootNode().getChildren().toArray()));
|
||||
|
||||
|
||||
// Chunk c = new Chunk(new Vector3f(0,0,0));
|
||||
// c.arrayGenerateCorner();
|
||||
// chunkRenderer.greedyMeshing(this, c);
|
||||
// game.getRootNode().attachChild(c.chunkNode);
|
||||
// chunks.put(new Vector3f(0,0,0), new Chunk(new Vector3f(0,0,0)));
|
||||
// chunks.get(new Vector3f(0,0,0)).generatePlane();
|
||||
// chunkRenderer.stupidArrayMeshing(this, chunks.get(new Vector3f(0,0,0)));
|
||||
// game.getRootNode().attachChild(chunks.get(new Vector3f(0,0,0)).chunkNode);
|
||||
|
||||
// chunks.put(new Vector3f(0,0,1), new Chunk(new Vector3f(0,0,1)));
|
||||
// chunks.get(new Vector3f(0,0,1)).generatePlane();
|
||||
// chunkRenderer.stupidArrayMeshing(this, chunks.get(new Vector3f(0,0,1)));
|
||||
// game.getRootNode().attachChild(chunks.get(new Vector3f(0,0,1)).chunkNode);
|
||||
// chunks.put(new Vector3f(0,0,2), new Chunk(new Vector3f(0,0,2)));
|
||||
// chunks.get(new Vector3f(0,0,2)).generatePlane();
|
||||
// chunkRenderer.stupidArrayMeshing(this, chunks.get(new Vector3f(0,0,2)));
|
||||
// game.getRootNode().attachChild(chunks.get(new Vector3f(0,0,2)).chunkNode);
|
||||
}
|
||||
|
||||
Chunk c;
|
||||
Vector3f v = new Vector3f();
|
||||
String s;
|
||||
int chunkX, chunkY, chunkZ;
|
||||
public boolean generated = false, meshed = false;
|
||||
|
||||
public void render() {
|
||||
public void update() {
|
||||
camx = (int) (game.pos.getX());
|
||||
camy = (int) (game.pos.getY());
|
||||
camz = (int) (game.pos.getZ());
|
||||
|
@ -79,20 +57,14 @@ public class WorldManager {
|
|||
for (int k = Math.max(0, chunkZ - Config.RENDER_DISTANCE); k < chunkZ + Config.RENDER_DISTANCE; k++) {
|
||||
if(!Utils.withinDistance(chunkX, chunkY, chunkZ, i,j,k,Config.RENDER_DISTANCE)) continue;
|
||||
|
||||
v = new Vector3f(i, j, k); // this part has to be revised, i can see spikes in memory usage
|
||||
|
||||
if (chunks.get(v) == null) {
|
||||
c = new Chunk(v);
|
||||
c.arrayGenerateCorner();
|
||||
c.setState(Chunk.CHUNK_STATE_GENERATED, true);
|
||||
//chunkRenderer.greedyMeshing(this, c);
|
||||
//game.getRootNode().attachChild(c.chunkNode);
|
||||
chunks.put(v, c);
|
||||
}
|
||||
v = null;
|
||||
s = i + "," + j + "," + k;
|
||||
if (!chunks.containsKey(s)) chunks.put(s, new Chunk(i,j,k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generated = false;
|
||||
meshed = false;
|
||||
for(Chunk c : chunks.values()){
|
||||
if(!generated && !c.bgetState(Chunk.CHUNK_STATE_GENERATED)) {
|
||||
c.arrayGenerateCorner();
|
||||
|
@ -100,27 +72,34 @@ public class WorldManager {
|
|||
generated = true;
|
||||
}
|
||||
if(!meshed && c.bgetState(Chunk.CHUNK_STATE_GENERATED)&& !c.bgetState(Chunk.CHUNK_STATE_MESHED)) {
|
||||
//chunkRenderer.greedyMeshing(this, c);
|
||||
chunkRenderer.greedyMeshing(this, c);
|
||||
c.setState(Chunk.CHUNK_STATE_MESHED, true);
|
||||
meshed = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(!generated && ! meshed) System.out.println("Finished world generation");
|
||||
|
||||
}
|
||||
public void render(){
|
||||
for(Chunk c : chunks.values()){
|
||||
if(!c.bgetState(Chunk.CHUNK_STATE_LOADED) && c.bgetState(Chunk.CHUNK_STATE_GENERATED) && c.bgetState(Chunk.CHUNK_STATE_MESHED)){
|
||||
game.getRootNode().attachChild(c.chunkNode);
|
||||
c.setState(Chunk.CHUNK_STATE_LOADED, true);
|
||||
}
|
||||
if(!Utils.withinDistance(chunkX, chunkY, chunkZ, (int)c.pos.x, (int)c.pos.y, (int)c.pos.z, Config.RENDER_DISTANCE)){
|
||||
if(!Utils.withinDistance(chunkX, chunkY, chunkZ, (int)c.posx, (int)c.posy, (int)c.posz, Config.RENDER_DISTANCE)){
|
||||
c.chunkNode.removeFromParent();
|
||||
chunks.remove(c.pos);
|
||||
chunks.remove(c.posx + "," + c.posy + "," + c.posz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean chunkInCameraLimits(Chunk c) {
|
||||
int vx = (int) c.pos.x;
|
||||
int vy = (int) c.pos.y;
|
||||
int vz = (int) c.pos.z;
|
||||
int vx = (int) c.posx;
|
||||
int vy = (int) c.posy;
|
||||
int vz = (int) c.posz;
|
||||
return vx >= Math.min(0, chunkX - Config.RENDER_DISTANCE ) && vx < Math.min(0, chunkX + Config.RENDER_DISTANCE) && vy >= chunkY - Config.RENDER_DISTANCE && vy < Math.min(0, chunkY + Config.RENDER_DISTANCE) && vz >= chunkZ - Config.RENDER_DISTANCE && vz < Math.min(0, chunkZ + Config.RENDER_DISTANCE);
|
||||
}
|
||||
|
||||
|
@ -128,7 +107,7 @@ public class WorldManager {
|
|||
for(int i = 0; i < Config.RENDER_DISTANCE*2; i++)
|
||||
for(int j = 0; j < Config.RENDER_DISTANCE*2; j++)
|
||||
for(int k = 0; k < Config.RENDER_DISTANCE*2; k++){
|
||||
Chunk c = new Chunk(new Vector3f(i,j,k));
|
||||
Chunk c = new Chunk(i,j,k);
|
||||
c.arrayGenerateCorner();
|
||||
chunkRenderer.greedyMeshing(this, c);
|
||||
game.getRootNode().attachChild(c.chunkNode);
|
||||
|
|
Loading…
Reference in New Issue