start caves

pull/12/head
valoeghese 2020-02-29 23:22:26 +13:00
parent cfbdab79c7
commit bfe9767be9
7 changed files with 136 additions and 8 deletions

View File

@ -11,6 +11,7 @@ public class Block
{ // add properties to this builder!
private boolean visible = true;
private boolean fullCube = true;
private boolean canCaveCarve = false;
private final String identifier;
public Properties(String identifier)
@ -27,10 +28,16 @@ public class Block
this.visible = visible;
return this;
}
public Properties canCaveCarve(boolean canCaveCarve)
{
this.canCaveCarve = canCaveCarve;
return this;
}
}
public final TexturedModel model;
private final boolean visible, fullCube;
private final boolean visible, fullCube, canCaveCarve;
public final String identifier;
public boolean isFullCube()
@ -39,6 +46,9 @@ public class Block
public boolean isVisible()
{ return this.visible; }
public boolean canCaveCarve()
{ return this.canCaveCarve; }
protected Block(Properties properties)
{ this((TexturedModel) null, properties); }
@ -51,6 +61,7 @@ public class Block
this.visible = properties.visible;
this.fullCube = properties.fullCube;
this.identifier = properties.identifier;
this.canCaveCarve = properties.canCaveCarve;
IDENTIFIER_TO_BLOCK.put(this.identifier, this);
}

View File

@ -5,11 +5,11 @@ import com.github.halotroop.litecraft.types.block.Block.Properties;
public final class Blocks
{
public static final Block AIR = new Block(new Properties("air").visible(false));
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties("dirt"));
public static final Block ANDESITE = new Block("block/cubes/stone/basic/andesite.png", new Properties("andesite"));
public static final Block DIORITE = new Block("block/cubes/stone/basic/diorite.png", new Properties("diorite"));
public static final Block GRANITE = new Block("block/cubes/stone/basic/granite.png", new Properties("granite"));
public static final Block GNEISS = new Block("block/cubes/stone/basic/gneiss.png", new Properties("gneiss"));
public static final Block DIRT = new Block("block/cubes/soil/dirt.png", new Properties("dirt").canCaveCarve(true));
public static final Block ANDESITE = new Block("block/cubes/stone/basic/andesite.png", new Properties("andesite").canCaveCarve(true));
public static final Block DIORITE = new Block("block/cubes/stone/basic/diorite.png", new Properties("diorite").canCaveCarve(true));
public static final Block GRANITE = new Block("block/cubes/stone/basic/granite.png", new Properties("granite").canCaveCarve(true));
public static final Block GNEISS = new Block("block/cubes/stone/basic/gneiss.png", new Properties("gneiss").canCaveCarve(true));
public static Block setup()
{
return AIR;

View File

@ -10,6 +10,7 @@ import com.github.halotroop.litecraft.types.block.*;
import com.github.halotroop.litecraft.world.block.BlockRenderer;
import com.github.halotroop.litecraft.world.dimension.Dimension;
import com.github.halotroop.litecraft.world.gen.*;
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
import com.github.hydos.ginger.engine.api.Ginger;
import com.github.hydos.ginger.engine.elements.objects.Player;
import com.github.hydos.ginger.engine.obj.ModelLoader;
@ -29,6 +30,7 @@ public class World implements BlockAccess, WorldGenConstants
public Player player;
int renderBound;
int renderBoundVertical;
// dummy block instance for retrieving the default block model
private final BlockInstance dummy;
public World(long seed, int renderSize, Dimension<?> dim, LitecraftSave save)
{
@ -39,6 +41,11 @@ public class World implements BlockAccess, WorldGenConstants
this.seed = seed;
this.chunkGenerator = dim.createChunkGenerator(seed);
this.worldModifiers = dim.getWorldModifierArray();
// initialize world modifiers with seed
for (WorldModifier modifier : this.worldModifiers)
{
modifier.initialize(seed);
}
this.genBlockAccess = new GenerationWorld(this);
this.save = save;
this.dimension = dim.id;

View File

@ -3,6 +3,7 @@ package com.github.halotroop.litecraft.world.dimension;
import java.util.*;
import com.github.halotroop.litecraft.world.gen.*;
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
import it.unimi.dsi.fastutil.ints.*;

View File

@ -4,5 +4,5 @@ import com.github.halotroop.litecraft.world.gen.*;
public final class Dimensions
{
public static final Dimension<EarthChunkGenerator> OVERWORLD = new EarthDimension(0, "earth");
public static final Dimension<EarthChunkGenerator> OVERWORLD = new EarthDimension(0, "earth").addWorldModifier(new CavesModifier());
}

View File

@ -0,0 +1,108 @@
package com.github.halotroop.litecraft.world.gen;
import java.util.Random;
import com.github.halotroop.litecraft.types.block.Blocks;
import com.github.halotroop.litecraft.util.noise.OctaveSimplexNoise;
import com.github.halotroop.litecraft.world.BlockAccess;
import com.github.halotroop.litecraft.world.gen.modifier.WorldModifier;
public class CavesModifier implements WorldModifier, WorldGenConstants
{
private OctaveSimplexNoise caveNoise;
private static final double THRESHOLD = 0.3;
//
@Override
public void initialize(long seed)
{
Random rand = new Random(seed);
this.caveNoise = new OctaveSimplexNoise(rand, 2, 45.0, 1.0, 1.0);
}
@Override
public void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ)
{
final int subChunks = CHUNK_SIZE >> 2; // in 4x4x4 blocks
for (int subChunkX = 0; subChunkX < subChunks; subChunkX++)
{
int scOffsetX = subChunkX << 2; // sub chunk offset x
int scTotalX = scOffsetX + chunkStartX;
for (int subChunkZ = 0; subChunkZ < subChunks; subChunkZ++)
{
int scOffsetZ = subChunkZ << 2; // sub chunk offset z
int scTotalZ = scOffsetZ + chunkStartZ;
for (int subChunkY = 0; subChunkY < subChunks; subChunkY++)
{
int scOffsetY = subChunkY << 2; // sub chunk offset y
int scTotalY = scOffsetY + chunkStartY;
// calculate noise at each corner of the cube [lower|upper][south|north][west|east]
double noiseLSW = this.caveNoise.sample(scOffsetX, scOffsetY, scOffsetZ); // base = lower south west
double noiseUSW = this.caveNoise.sample(scOffsetX, scOffsetY + 1, scOffsetZ);
double noiseLNW = this.caveNoise.sample(scOffsetX, scOffsetY, scOffsetZ + 1);
double noiseUNW = this.caveNoise.sample(scOffsetX, scOffsetY + 1, scOffsetZ + 1);
double noiseLSE = this.caveNoise.sample(scOffsetX + 1, scOffsetY, scOffsetZ);
double noiseUSE = this.caveNoise.sample(scOffsetX + 1, scOffsetY + 1, scOffsetZ);
double noiseLNE = this.caveNoise.sample(scOffsetX + 1, scOffsetY, scOffsetZ + 1);
double noiseUNE = this.caveNoise.sample(scOffsetX + 1, scOffsetY + 1, scOffsetZ + 1);
// calculate y lerp progresses
// lerp = low + progress * (high - low)
double ypSW = 0.25 * (noiseUSW - noiseLSW);
double ypNW = 0.25 * (noiseUNW - noiseLNW);
double ypSE = 0.25 * (noiseUSE - noiseLSE);
double ypNE = 0.25 * (noiseUNE - noiseLNE);
// initial Y noises
double ySW = noiseLSW;
double ySE = noiseLSE;
double yNW = noiseLNW;
double yNE = noiseLNE;
// loop over y, adding the progress each time
for (int subY = 0; subY < 4; ++subY)
{
int totalY = subY + scTotalY;
// calculate z lerp progresses
double zpW = 0.25 * (yNW - ySW);
double zpE = 0.25 * (yNE - ySE);
// initial Z noises
double zW = ySW;
double zE = ySE;
// loop over z, adding the progress each time
for (int subZ = 0; subZ < 4; ++subZ)
{
int totalZ = subZ + scTotalZ;
// calculate x lerp progress
double lerpProg = 0.25 * (zE - zW);
// initial x noise
double lerpNoise = zW;
// loop over x, adding the progress each time
for (int subX = 0; subX < 4; ++subX)
{
int totalX = subX + scTotalX;
// calculate whether to replace block with air
// if the noise is within the threshold for caves
if (lerpNoise > -THRESHOLD && lerpNoise < THRESHOLD)
{
// if the cave can carve into the block
if (world.getBlock(totalX, totalY, totalZ).canCaveCarve())
{
world.setBlock(totalX, totalY, totalZ, Blocks.AIR);
}
}
// add progress to the noise
lerpNoise += lerpProg;
}
// add z progresses
zW += zpW;
zE += zpE;
}
// add y progresses
ySW += ypSW;
ySE += ypSE;
yNW += ypNW;
yNE += ypNE;
}
}
}
}
}
}

View File

@ -1,4 +1,4 @@
package com.github.halotroop.litecraft.world.gen;
package com.github.halotroop.litecraft.world.gen.modifier;
import java.util.Random;
@ -7,4 +7,5 @@ import com.github.halotroop.litecraft.world.BlockAccess;
public interface WorldModifier
{
void modifyWorld(BlockAccess world, Random rand, int chunkStartX, int chunkStartY, int chunkStartZ);
void initialize(long seed);
}