Skip to content

Commit

Permalink
3D chunking
Browse files Browse the repository at this point in the history
  • Loading branch information
Indexu committed Nov 5, 2017
1 parent 51f06e1 commit a78af4b
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 61 deletions.
51 changes: 27 additions & 24 deletions src/core/src/com/ru/tgra/ourcraft/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class GameManager

public static WorldGenerator worldGenerator;
public static Block.BlockType[][][] worldBlocks;
public static Chunk[][] chunks;
public static Chunk[][][] chunks;

public static boolean mainMenu;
public static boolean loaded;
Expand Down Expand Up @@ -48,8 +48,9 @@ public static void createWorld()

public static void drawWorld()
{
int chunkX = (int) player.getPosition().x / Settings.chunkWidth;
int chunkY = (int) player.getPosition().z / Settings.chunkHeight;
int chunkX = MathUtils.getChunkX((int) player.getPosition().x, Settings.chunkX);
int chunkY = MathUtils.getChunkX((int) player.getPosition().y, Settings.chunkY);
int chunkZ = MathUtils.getChunkX((int) player.getPosition().z, Settings.chunkZ);

int startX = chunkX - Settings.chunkDrawRadius;
startX = (startX < 0 ? 0 : startX);
Expand All @@ -63,11 +64,20 @@ public static void drawWorld()
int endY = chunkY + Settings.chunkDrawRadius;
endY = (chunks[0].length-1 < endY ? chunks[0].length-1 : endY);

int startZ = chunkZ - Settings.chunkDrawRadius;
startZ = (startZ < 0 ? 0 : startZ);

int endZ = chunkZ + Settings.chunkDrawRadius;
endZ = (chunks[0][0].length-1 < endZ ? chunks[0][0].length-1 : endZ);

for (int x = startX; x <= endX; x++)
{
for (int y = startY; y <= endY; y++)
{
chunks[x][y].drawBlocks();
for (int z = startZ; z <= endZ; z++)
{
chunks[x][y][z].drawBlocks();
}
}
}
}
Expand All @@ -88,8 +98,9 @@ public static void addBlock(Point3D pos, Block.BlockType type)
return;
}

int chunkX = MathUtils.getChunkX(x, Settings.chunkWidth);
int chunkY = MathUtils.getChunkY(z, Settings.chunkHeight);
int chunkX = MathUtils.getChunkX(x, Settings.chunkX);
int chunkY = MathUtils.getChunkY(y, Settings.chunkY);
int chunkZ = MathUtils.getChunkZ(z, Settings.chunkZ);

setWorldBlocksBlock(pos, type);

Expand All @@ -100,12 +111,13 @@ public static void addBlock(Point3D pos, Block.BlockType type)
BlockUtils.createBlockMask(x, y, z, worldBlocks),
type,
chunkX,
chunkY
chunkY,
chunkZ
);

redoMasksForAdjacentBlocks(block);

chunks[block.getChunkX()][block.getChunkY()].addBlock(block);
chunks[block.getChunkX()][block.getChunkY()][block.getChunkZ()].addBlock(block);

AudioManager.playPlaceBlock();
}
Expand All @@ -121,22 +133,12 @@ public static void removeBlocks()
{
setWorldBlocksBlock(block.getPosition(), Block.BlockType.EMPTY);
redoMasksForAdjacentBlocks(block);
chunks[block.getChunkX()][block.getChunkY()].removeBlock(block.getID());
chunks[block.getChunkX()][block.getChunkY()][block.getChunkZ()].removeBlock(block.getID());
}

blocksToRemove.clear();
}

public static Block getBlock(int x, int y, int z)
{
int chunkX = MathUtils.getChunkX(x, Settings.chunkWidth);
int chunkY = MathUtils.getChunkY(z, Settings.chunkHeight);

int ID = MathUtils.cartesianHash(x, y, z);

return chunks[chunkX][chunkY].getBlock(ID);
}

private static void createTorch()
{
torch = new Torch();
Expand Down Expand Up @@ -226,19 +228,20 @@ private static void redoBlock(int x, int y, int z)

CubeMask mask = BlockUtils.createBlockMask(x, y, z, worldBlocks);

int chunkX = MathUtils.getChunkX(x, Settings.chunkWidth);
int chunkY = MathUtils.getChunkY(z, Settings.chunkHeight);
int chunkX = MathUtils.getChunkX(x, Settings.chunkX);
int chunkY = MathUtils.getChunkY(y, Settings.chunkY);
int chunkZ = MathUtils.getChunkZ(z, Settings.chunkZ);

int ID = MathUtils.cartesianHash(x, y, z);

if (mask.isInvisible())
{
chunks[chunkX][chunkY].removeBlock(ID);
chunks[chunkX][chunkY][chunkZ].removeBlock(ID);
}
else
{
chunks[chunkX][chunkY].assertBlock(ID, x, y, z, worldBlocks[x][y][z]);
chunks[chunkX][chunkY].setBlockMask(ID, mask);
chunks[chunkX][chunkY][chunkZ].assertBlock(ID, x, y, z, worldBlocks[x][y][z]);
chunks[chunkX][chunkY][chunkZ].setBlockMask(ID, mask);
}
}
}
6 changes: 4 additions & 2 deletions src/core/src/com/ru/tgra/ourcraft/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ public class Settings
public static final int worldX = 512;
public static final int worldZ = 512;
public static final int worldY = 128;
public static final int worldScale = 128;
public static final int worldFeatureSize = 8;
public static final int worldSmoothness = 16;
public static final int cavernMinHeight = 3;
public static final int cavernMaxHeight = 6;
public static final int chunkWidth = 16;
public static final int chunkHeight = 16;
public static final int chunkX = 16;
public static final int chunkY = 16;
public static final int chunkZ = 16;
public static final Vector3D blockSize = new Vector3D(1f, 1f, 1f);
public static final Vector3D torchSize = new Vector3D(0.1f, 0.5f, 0.1f);
public static final float dayNightCycleSpeed = 0.01f;
Expand Down
8 changes: 6 additions & 2 deletions src/core/src/com/ru/tgra/ourcraft/models/Chunk.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ru.tgra.ourcraft.models;

import com.ru.tgra.ourcraft.GameManager;
import com.ru.tgra.ourcraft.Settings;
import com.ru.tgra.ourcraft.objects.Block;
import com.ru.tgra.ourcraft.objects.Torch;
Expand All @@ -12,12 +13,14 @@ public class Chunk
private Map<Integer, Block> blockMap;
private int chunkX;
private int chunkY;
private int chunkZ;

public Chunk(Map<Integer, Block> blockMap, int chunkX, int chunkY)
public Chunk(Map<Integer, Block> blockMap, int chunkX, int chunkY, int chunkZ)
{
this.blockMap = blockMap;
this.chunkX = chunkX;
this.chunkY = chunkY;
this.chunkZ = chunkZ;
}

public void drawBlocks()
Expand Down Expand Up @@ -67,7 +70,8 @@ public void assertBlock(int ID, int x, int y, int z, Block.BlockType type)
new CubeMask(),
type,
chunkX,
chunkY
chunkY,
chunkZ
);

addBlock(block);
Expand Down
9 changes: 8 additions & 1 deletion src/core/src/com/ru/tgra/ourcraft/objects/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ public enum TargetFace
protected float distanceFromPlayer;
protected int chunkX;
protected int chunkY;
protected int chunkZ;
protected TargetFace targetFace;

protected Point3D leftBottom;
protected Point3D rightTop;

private float grassTimer;

public Block(int ID, Point3D position, Vector3D scale, CubeMask mask, BlockType type, int chunkX, int chunkY)
public Block(int ID, Point3D position, Vector3D scale, CubeMask mask, BlockType type, int chunkX, int chunkY, int chunkZ)
{
super();

Expand All @@ -72,6 +73,7 @@ public Block(int ID, Point3D position, Vector3D scale, CubeMask mask, BlockType
blockType = type;
this.chunkX = chunkX;
this.chunkY = chunkY;
this.chunkZ = chunkZ;

renderMask = new CubeMask(mask);
minimapMask = new CubeMask(false, false, false, false, true, false);
Expand Down Expand Up @@ -244,6 +246,11 @@ public int getChunkY()
return chunkY;
}

public int getChunkZ()
{
return chunkZ;
}

public TargetFace getTargetFace()
{
return targetFace;
Expand Down
13 changes: 9 additions & 4 deletions src/core/src/com/ru/tgra/ourcraft/utilities/MathUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,19 @@ public static int cartesianHash(int x, int y, int z)
return x + (y << 10) + (z << 20);
}

public static int getChunkX(int x, int chunkWidth)
public static int getChunkX(int x, int chunkX)
{
return (x / chunkWidth);
return (x / chunkX);
}

public static int getChunkY(int y, int chunkHeight)
public static int getChunkY(int y, int chunkY)
{
return (y / chunkHeight);
return (y / chunkY);
}

public static int getChunkZ(int z, int chunkZ)
{
return (z / chunkZ);
}

public static float lerp(float a, float b, float t)
Expand Down
54 changes: 26 additions & 28 deletions src/core/src/com/ru/tgra/ourcraft/utilities/WorldGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public class WorldGenerator
{
private Block.BlockType[][][] worldBlocks;
private Chunk[][] chunks;
private Chunk[][][] chunks;
private OpenSimplexNoise noise;
private int[][] overworldHeightMap;
private int maxX;
Expand All @@ -34,21 +34,12 @@ public WorldGenerator()
maxZ = Settings.worldZ;
}

public void generateWorld()
{
System.out.println("Lowest Y: " + lowestY);
System.out.println("Highest Y: " + highestY);
System.out.println("Chunks X: " + chunks.length);
System.out.println("Chunks Y: " + chunks[0].length);
System.out.println("Chunks: " + (chunks.length * chunks[0].length));
}

public Block.BlockType[][][] getWorldBlocks()
{
return worldBlocks;
}

public Chunk[][] getChunks()
public Chunk[][][] getChunks()
{
return chunks;
}
Expand Down Expand Up @@ -90,7 +81,7 @@ public void smoothenOverworldHeightMap()

private void generateHeightMap(int[][] heightmap)
{
float scalar = Settings.worldY / 2;
float scalar = Settings.worldScale / 2;

noise = new OpenSimplexNoise(new Date().getTime());

Expand Down Expand Up @@ -230,16 +221,20 @@ public void generateChunks()
{
long startTime = System.nanoTime();

int chunkX = Settings.worldX / Settings.chunkWidth;
int chunkY = Settings.worldZ / Settings.chunkHeight;
int chunkX = Settings.worldX / Settings.chunkX;
int chunkY = Settings.worldY / Settings.chunkY;
int chunkZ = Settings.worldZ / Settings.chunkZ;

chunks = new Chunk[chunkX][chunkY];
chunks = new Chunk[chunkX][chunkY][chunkZ];

for (int x = 0; x < Settings.worldX; x += Settings.chunkWidth)
for (int x = 0; x < Settings.worldX; x += Settings.chunkX)
{
for (int y = 0; y < Settings.worldZ; y += Settings.chunkHeight)
for (int y = 0; y < Settings.worldY; y += Settings.chunkY)
{
createChunk(x, y);
for (int z = 0; z < Settings.worldZ; z += Settings.chunkZ)
{
createChunk(x, y, z);
}
}
}

Expand All @@ -251,15 +246,15 @@ public void generateChunks()
System.out.println("\nWorld generated in " + totalTime / million + "ms\n");
}

private void createChunk(int startX, int startZ)
private void createChunk(int startX, int startY, int startZ)
{
Map<Integer, Block> blockMap = new HashMap<>();

for (int x = startX; x < (startX + Settings.chunkWidth); x++)
for (int x = startX; x < (startX + Settings.chunkX); x++)
{
for (int y = 0; y < maxY; y++)
for (int y = startY; y < (startY + Settings.chunkY); y++)
{
for (int z = startZ; z < (startZ + Settings.chunkHeight); z++)
for (int z = startZ; z < (startZ + Settings.chunkZ); z++)
{
if (worldBlocks[x][y][z] != Block.BlockType.EMPTY && worldBlocks[x][y][z] != null)
{
Expand All @@ -270,8 +265,9 @@ private void createChunk(int startX, int startZ)
Point3D position = new Point3D(x, y, z);
int ID = MathUtils.cartesianHash(x, y, z);

int chunkX = MathUtils.getChunkX(x, Settings.chunkWidth);
int chunkY = MathUtils.getChunkY(z, Settings.chunkHeight);
int chunkX = MathUtils.getChunkX(x, Settings.chunkX);
int chunkY = MathUtils.getChunkY(y, Settings.chunkY);
int chunkZ = MathUtils.getChunkZ(z, Settings.chunkZ);

Block block = new Block
(
Expand All @@ -281,7 +277,8 @@ private void createChunk(int startX, int startZ)
mask,
worldBlocks[x][y][z],
chunkX,
chunkY
chunkY,
chunkZ
);

blockMap.put(ID, block);
Expand All @@ -291,10 +288,11 @@ private void createChunk(int startX, int startZ)
}
}

int chunkX = startX / Settings.chunkWidth;
int chunkY = startZ / Settings.chunkHeight;
int chunkX = startX / Settings.chunkX;
int chunkY = startY / Settings.chunkY;
int chunkZ = startZ / Settings.chunkZ;

chunks[chunkX][chunkY] = new Chunk(blockMap, chunkX, chunkY);
chunks[chunkX][chunkY][chunkZ] = new Chunk(blockMap, chunkX, chunkY, chunkZ);
}

public void createStone()
Expand Down

0 comments on commit a78af4b

Please sign in to comment.