diff --git a/src/main/java/com/github/halotroop/litecraft/world/BlockAccess.java b/src/main/java/com/github/halotroop/litecraft/world/BlockAccess.java new file mode 100644 index 0000000..c698170 --- /dev/null +++ b/src/main/java/com/github/halotroop/litecraft/world/BlockAccess.java @@ -0,0 +1,14 @@ +package com.github.halotroop.litecraft.world; + +import com.github.halotroop.litecraft.types.block.Block; + +public interface BlockAccess +{ + Block getBlock(int x, int y, int z); + void setBlock(int x, int y, int z, Block block); + + static final int POS_SHIFT = 3; + static final int DOUBLE_SHIFT = POS_SHIFT * 2; + static final int CHUNK_SIZE = (int) Math.pow(2, POS_SHIFT); + static final int MAX_POS = CHUNK_SIZE - 1; +} diff --git a/src/main/java/com/github/halotroop/litecraft/world/Chunk.java b/src/main/java/com/github/halotroop/litecraft/world/Chunk.java index 77100fa..f6ffa5c 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/Chunk.java +++ b/src/main/java/com/github/halotroop/litecraft/world/Chunk.java @@ -3,20 +3,19 @@ package com.github.halotroop.litecraft.world; import java.util.*; import com.github.halotroop.litecraft.types.block.*; -import com.github.hydos.ginger.engine.elements.objects.RenderObject; import com.github.hydos.ginger.engine.math.vectors.Vector3f; import com.github.hydos.ginger.engine.render.renderers.ObjectRenderer; import it.unimi.dsi.fastutil.longs.*; -public class Chunk implements TileAccess +public class Chunk implements BlockAccess { /** @param x in-chunk x coordinate. * @param y in-chunk y coordinate. * @param z in-chunk z coordinate. * @return creates a long that represents a coordinate, for use as a key in maps. */ private static long posHash(int x, int y, int z) - { return ((long) x & 0b111) | (((long) y & 0b111) << 3) | (((long) z & 0b111) << 6); } + { return ((long) x & MAX_POS) | (((long) y & MAX_POS) << POS_SHIFT) | (((long) z & MAX_POS) << DOUBLE_SHIFT); } List renderList; private final Long2ObjectMap blocks = new Long2ObjectArrayMap<>(); @@ -57,9 +56,9 @@ public class Chunk implements TileAccess renderList.clear(); if (render) { - for(int i = 0; i < 8; i++) { - for(int j = 0; j < 8; j++) { - for(int k = 0; k < 8; k++) { + for(int i = 0; i < CHUNK_SIZE; i++) { + for(int j = 0; j < CHUNK_SIZE; j++) { + for(int k = 0; k < CHUNK_SIZE; k++) { BlockEntity block = getBlockEntity(i, j, k); renderList.add(block); } @@ -74,14 +73,14 @@ public class Chunk implements TileAccess @Override public void setBlock(int x, int y, int z, Block block) { - if (x > 7) - x = 7; + if (x > MAX_POS) + x = MAX_POS; else if (x < 0) x = 0; - if (y > 7) - y = 7; + if (y > MAX_POS) + y = MAX_POS; else if (y < 0) y = 0; - if (z > 7) - z = 7; + if (z > MAX_POS) + z = MAX_POS; else if (z < 0) z = 0; long hash = posHash(x, y, z); this.blocks.put(hash, block); @@ -95,9 +94,9 @@ public class Chunk implements TileAccess public static Chunk generateChunk(int chunkX, int chunkY, int chunkZ) { Chunk result = new Chunk(chunkX, chunkY, chunkZ); - for (int x = 0; x < 8; ++x) { - for (int z = 0; z < 8; ++z) { - for (int y = 0; y < 8; ++y) { + for (int x = 0; x < CHUNK_SIZE; ++x) { + for (int z = 0; z < CHUNK_SIZE; ++z) { + for (int y = 0; y < CHUNK_SIZE; ++y) { result.setBlock(x, y, z, y == 7 ? Block.GRASS : Block.DIRT); } } @@ -110,11 +109,11 @@ public class Chunk implements TileAccess { if (render && !this.render) // if it has been changed to true { - for (int x = 0; x < 8; ++x) + for (int x = 0; x < CHUNK_SIZE; ++x) { - for (int y = 0; y < 8; ++y) + for (int y = 0; y < CHUNK_SIZE; ++y) { - for (int z = 0; z < 8; ++z) + for (int z = 0; z < CHUNK_SIZE; ++z) { long hash = posHash(x, y, z); Block block = this.blocks.get(hash); diff --git a/src/main/java/com/github/halotroop/litecraft/world/TileAccess.java b/src/main/java/com/github/halotroop/litecraft/world/TileAccess.java deleted file mode 100644 index 7e4a7ae..0000000 --- a/src/main/java/com/github/halotroop/litecraft/world/TileAccess.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.halotroop.litecraft.world; - -import com.github.halotroop.litecraft.types.block.Block; - -public interface TileAccess -{ - Block getBlock(int x, int y, int z); - - void setBlock(int x, int y, int z, Block block); -} diff --git a/src/main/java/com/github/halotroop/litecraft/world/World.java b/src/main/java/com/github/halotroop/litecraft/world/World.java index afcb326..538ad1b 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/World.java +++ b/src/main/java/com/github/halotroop/litecraft/world/World.java @@ -1,45 +1,44 @@ package com.github.halotroop.litecraft.world; -import java.util.*; - +import com.github.halotroop.litecraft.types.block.Block; import com.github.hydos.ginger.engine.render.renderers.ObjectRenderer; -public class World +import it.unimi.dsi.fastutil.longs.*; + +public class World implements BlockAccess { - public List chunks; - - public World() { - chunks = new ArrayList(); + private final Long2ObjectMap chunks; + + public World(long seed) + { + chunks = new Long2ObjectArrayMap<>(); } - - public void generateWorld() { - - } - - public void optimiseChunks() { - for(Chunk c: chunks) { - optimiseChunk(c); - } - } - - public void optimiseChunk(int ID) { - Chunk chunk = chunks.get(ID); - optimiseChunk(chunk); - } - + + public Chunk getChunk(int chunkX, int chunkY, int chunkZ) + { return this.chunks.computeIfAbsent(posHash(chunkX, chunkY, chunkZ), pos -> Chunk.generateChunk(chunkX, chunkY, chunkZ)); } + + private static long posHash(int x, int y, int z) + { return ((long) x & 0x3FF) | (((long) y & 0x3FF) << 10) | (((long) z & 0x3FF) << 20); } + + @Override + public Block getBlock(int x, int y, int z) + { return this.getChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).getBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS); } + + @Override + public void setBlock(int x, int y, int z, Block block) + { this.getChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).setBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS, block); } + + public void optimiseChunks() + { this.chunks.forEach((pos, chunk) -> optimiseChunk(chunk)); } + //used for model combining and culling - public Chunk optimiseChunk(Chunk chunk) { + public Chunk optimiseChunk(Chunk chunk) + { //TODO: use this - + return null; } public void render(ObjectRenderer entityRenderer) - { - for(Chunk chunk: chunks) { - chunk.render(entityRenderer); - } - } - - + { this.chunks.forEach((pos, chunk) -> chunk.render(entityRenderer)); } } diff --git a/src/main/java/com/github/hydos/ginger/Litecraft.java b/src/main/java/com/github/hydos/ginger/Litecraft.java index c19a61f..68729b7 100644 --- a/src/main/java/com/github/hydos/ginger/Litecraft.java +++ b/src/main/java/com/github/hydos/ginger/Litecraft.java @@ -44,17 +44,15 @@ public class Litecraft extends Game data.handleGuis = false; ginger3D.setup(new MasterRenderer(camera), this); //YeS? - world = new World(); + world = new World(0L); for(int i = 0; i<10;i++) { for(int k = 0; k<10;k++) { - Chunk exampleManualChunk = Chunk.generateChunk(i, -1, k); + Chunk exampleManualChunk = world.getChunk(i, -1, k); exampleManualChunk.setRender(true); - world.chunks.add(exampleManualChunk); } } - FontType font = new FontType(Loader.loadFontAtlas("candara.png"), "candara.fnt"); ginger3D.setGlobalFont(font); GUIText titleText = ginger3D.registerText("LiteCraft", 3, new Vector2f(0, 0), 1f, true, "PLAYBUTTON");