Added granite & snow, updated dirt texture
- Added granite (monolith, cracked and gravel variants) - Generates as a random combination of the variants instead of stone on mountain cliffs - Added snow (opaque, half and quarter variants) - Generates at altitudes above 1500 m - Distribution is bad atm, not fixing until proper worldgen is introduced - Reduced cliff areas - Hotfixed texture flickering - Changed dirt texture
@ -118,7 +118,7 @@ public class Camera {
|
|||||||
Glm.perspective(
|
Glm.perspective(
|
||||||
computeFovY(),
|
computeFovY(),
|
||||||
GraphicsInterface.getAspectRatio(),
|
GraphicsInterface.getAspectRatio(),
|
||||||
0.01f, 10000.0f,
|
0.01f, 150.0f,
|
||||||
helper.pushViewTransform()
|
helper.pushViewTransform()
|
||||||
).mul(previous);
|
).mul(previous);
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,16 @@ import ru.windcorp.progressia.common.world.block.BlockFace;
|
|||||||
public class TileRenderSimple extends TileRender implements OpaqueTile {
|
public class TileRenderSimple extends TileRender implements OpaqueTile {
|
||||||
|
|
||||||
private final Texture texture;
|
private final Texture texture;
|
||||||
|
private final boolean opaque;
|
||||||
|
|
||||||
public TileRenderSimple(String id, Texture texture) {
|
public TileRenderSimple(String id, Texture texture, boolean opaque) {
|
||||||
super(id);
|
super(id);
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
|
this.opaque = opaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileRenderSimple(String id, Texture texture) {
|
||||||
|
this(id, texture, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,7 +33,7 @@ public class TileRenderSimple extends TileRender implements OpaqueTile {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpaque(BlockFace face) {
|
public boolean isOpaque(BlockFace face) {
|
||||||
return false;
|
return opaque;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,6 +68,14 @@ public class TestContent {
|
|||||||
register(new BlockRenderOpaqueCube("Test:Stone", getBlockTexture("stone")));
|
register(new BlockRenderOpaqueCube("Test:Stone", getBlockTexture("stone")));
|
||||||
register(new BlockLogic("Test:Stone"));
|
register(new BlockLogic("Test:Stone"));
|
||||||
|
|
||||||
|
for (String type : new String[] {"Monolith", "Cracked", "Gravel"}) {
|
||||||
|
String id = "Test:Granite" + type;
|
||||||
|
|
||||||
|
register(new BlockData(id));
|
||||||
|
register(new BlockRenderOpaqueCube(id, getBlockTexture("granite_" + type.toLowerCase())));
|
||||||
|
register(new BlockLogic(id));
|
||||||
|
}
|
||||||
|
|
||||||
register(new BlockData("Test:Compass"));
|
register(new BlockData("Test:Compass"));
|
||||||
register(new BlockRenderOpaqueCube("Test:Compass", getBlockTexture("compass")));
|
register(new BlockRenderOpaqueCube("Test:Compass", getBlockTexture("compass")));
|
||||||
register(new BlockLogic("Test:Compass"));
|
register(new BlockLogic("Test:Compass"));
|
||||||
@ -93,6 +101,18 @@ public class TestContent {
|
|||||||
register(new TileData("Test:Sand"));
|
register(new TileData("Test:Sand"));
|
||||||
register(new TileRenderSimple("Test:Sand", getTileTexture("sand")));
|
register(new TileRenderSimple("Test:Sand", getTileTexture("sand")));
|
||||||
register(new HangingTileLogic("Test:Sand"));
|
register(new HangingTileLogic("Test:Sand"));
|
||||||
|
|
||||||
|
register(new TileData("Test:SnowOpaque"));
|
||||||
|
register(new TileRenderSimple("Test:SnowOpaque", getTileTexture("snow_opaque"), true));
|
||||||
|
register(new HangingTileLogic("Test:SnowOpaque"));
|
||||||
|
|
||||||
|
register(new TileData("Test:SnowHalf"));
|
||||||
|
register(new TileRenderSimple("Test:SnowHalf", getTileTexture("snow_half")));
|
||||||
|
register(new HangingTileLogic("Test:SnowHalf"));
|
||||||
|
|
||||||
|
register(new TileData("Test:SnowQuarter"));
|
||||||
|
register(new TileRenderSimple("Test:SnowQuarter", getTileTexture("snow_quarter")));
|
||||||
|
register(new HangingTileLogic("Test:SnowQuarter"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerEntities() {
|
private static void registerEntities() {
|
||||||
|
@ -64,11 +64,19 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
chunk.setGenerationHint(false);
|
chunk.setGenerationHint(false);
|
||||||
|
|
||||||
final int bpc = ChunkData.BLOCKS_PER_CHUNK;
|
final int bpc = ChunkData.BLOCKS_PER_CHUNK;
|
||||||
|
Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z);
|
||||||
|
|
||||||
BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt");
|
BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt");
|
||||||
BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone");
|
BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone");
|
||||||
BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
|
BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
|
||||||
|
|
||||||
|
BlockData[] granites = new BlockData[] {
|
||||||
|
BlockDataRegistry.getInstance().get("Test:GraniteGravel"),
|
||||||
|
BlockDataRegistry.getInstance().get("Test:GraniteGravel"),
|
||||||
|
BlockDataRegistry.getInstance().get("Test:GraniteCracked"),
|
||||||
|
BlockDataRegistry.getInstance().get("Test:GraniteMonolith")
|
||||||
|
};
|
||||||
|
|
||||||
double[][] heightMap = new double[bpc][bpc];
|
double[][] heightMap = new double[bpc][bpc];
|
||||||
double[][] gradMap = new double[bpc][bpc];
|
double[][] gradMap = new double[bpc][bpc];
|
||||||
|
|
||||||
@ -84,8 +92,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
if (layer < -4) {
|
if (layer < -4) {
|
||||||
chunk.setBlock(pos, stone, false);
|
chunk.setBlock(pos, stone, false);
|
||||||
} else if (layer < 0) {
|
} else if (layer < 0) {
|
||||||
if (gradMap[pos.x][pos.y] > 0.3) {
|
if (gradMap[pos.x][pos.y] > 0.5) {
|
||||||
chunk.setBlock(pos, stone, false);
|
BlockData granite = granites[random.nextInt(4)];
|
||||||
|
chunk.setBlock(pos, granite, false);
|
||||||
} else {
|
} else {
|
||||||
chunk.setBlock(pos, dirt, false);
|
chunk.setBlock(pos, dirt, false);
|
||||||
}
|
}
|
||||||
@ -145,12 +154,18 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
|
|
||||||
Vec3i biw = new Vec3i();
|
Vec3i biw = new Vec3i();
|
||||||
|
|
||||||
int minX = Coordinates.getInWorld(chunkPos.x, 0);
|
int minX = chunk.getMinX();
|
||||||
int maxX = Coordinates.getInWorld(chunkPos.x + 1, 0);
|
int maxX = chunk.getMaxX() + 1;
|
||||||
int minY = Coordinates.getInWorld(chunkPos.y, 0);
|
int minY = chunk.getMinY();
|
||||||
int maxY = Coordinates.getInWorld(chunkPos.y + 1, 0);
|
int maxY = chunk.getMaxY() + 1;
|
||||||
int minZ = Coordinates.getInWorld(chunkPos.z, 0);
|
int minZ = chunk.getMinZ();
|
||||||
int maxZ = Coordinates.getInWorld(chunkPos.z + 1, 0);
|
int maxZ = chunk.getMaxZ() + 1;
|
||||||
|
|
||||||
|
final int bpc = ChunkData.BLOCKS_PER_CHUNK;
|
||||||
|
double[][] heightMap = new double[bpc][bpc];
|
||||||
|
double[][] gradMap = new double[bpc][bpc];
|
||||||
|
|
||||||
|
terrainGen.compute(minX, minY, heightMap, gradMap);
|
||||||
|
|
||||||
for (biw.x = minX; biw.x < maxX; ++biw.x) {
|
for (biw.x = minX; biw.x < maxX; ++biw.x) {
|
||||||
for (biw.y = minY; biw.y < maxY; ++biw.y) {
|
for (biw.y = minY; biw.y < maxY; ++biw.y) {
|
||||||
@ -161,7 +176,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
if (biw.z == maxZ) continue;
|
if (biw.z == maxZ) continue;
|
||||||
if (biw.z < minZ) continue;
|
if (biw.z < minZ) continue;
|
||||||
|
|
||||||
addTiles(chunk, biw, world, random, world.getBlock(biw) == dirt);
|
int xic = Coordinates.convertInWorldToInChunk(biw.x);
|
||||||
|
int yic = Coordinates.convertInWorldToInChunk(biw.y);
|
||||||
|
|
||||||
|
addTiles(chunk, biw, world, random, world.getBlock(biw) == dirt, heightMap[xic][yic], gradMap[xic][yic]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,9 +187,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
chunk.setGenerationHint(true);
|
chunk.setGenerationHint(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTiles(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt) {
|
private void addTiles(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt, double height, double grad) {
|
||||||
if (isDirt) addGrass(chunk, biw, world, random);
|
if (isDirt) addGrass(chunk, biw, world, random);
|
||||||
addDecor(chunk, biw, world, random, isDirt);
|
addDecor(chunk, biw, world, random, isDirt);
|
||||||
|
addSnow(chunk, biw, world, random, isDirt, height + 1000, grad);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addGrass(ChunkData chunk, Vec3i biw, WorldData world, Random random) {
|
private void addGrass(ChunkData chunk, Vec3i biw, WorldData world, Random random) {
|
||||||
@ -221,4 +240,94 @@ public class TestWorldGenerator extends AbstractWorldGenerator<Boolean> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSnow(
|
||||||
|
ChunkData chunk, Vec3i biw, WorldData world,
|
||||||
|
Random random,
|
||||||
|
boolean isDirt, double height, double grad
|
||||||
|
) {
|
||||||
|
if (height < 1500) return;
|
||||||
|
|
||||||
|
BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
|
||||||
|
|
||||||
|
double quarterChance = computeSnowQuarterChance(height, grad);
|
||||||
|
double halfChance = computeSnowHalfChance(height, grad);
|
||||||
|
double opaqueChance = computeSnowOpaqueChance(height, grad);
|
||||||
|
|
||||||
|
for (BlockFace face : BlockFace.getFaces()) {
|
||||||
|
if (face == BlockFace.BOTTOM) continue;
|
||||||
|
|
||||||
|
if (face.getVector().z == 0) {
|
||||||
|
biw.add(face.getVector());
|
||||||
|
BlockData neighbour = world.getBlock(biw);
|
||||||
|
biw.sub(face.getVector());
|
||||||
|
|
||||||
|
if (neighbour != air) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileData tile;
|
||||||
|
|
||||||
|
double maxValue = height > 3000 ? 3 : (1 + 2 * ((height - 1500) / 1500));
|
||||||
|
double value = random.nextDouble() * maxValue;
|
||||||
|
if (value < quarterChance) {
|
||||||
|
tile = TileDataRegistry.getInstance().get("Test:SnowQuarter");
|
||||||
|
} else if ((value -= quarterChance) < halfChance) {
|
||||||
|
tile = TileDataRegistry.getInstance().get("Test:SnowHalf");
|
||||||
|
} else if ((value -= halfChance) < opaqueChance) {
|
||||||
|
tile = TileDataRegistry.getInstance().get("Test:SnowOpaque");
|
||||||
|
} else {
|
||||||
|
tile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile != null) {
|
||||||
|
world.getTiles(biw, face).addFarthest(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeSnowQuarterChance(double height, double grad) {
|
||||||
|
double heightCoeff;
|
||||||
|
|
||||||
|
if (height < 1500) heightCoeff = 0;
|
||||||
|
else if (height < 2000) heightCoeff = (height - 1500) / 500;
|
||||||
|
else heightCoeff = 1;
|
||||||
|
|
||||||
|
if (heightCoeff < 1e-4) return 0;
|
||||||
|
|
||||||
|
double gradCoeff = computeSnowGradCoeff(height, grad);
|
||||||
|
return heightCoeff * gradCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeSnowHalfChance(double height, double grad) {
|
||||||
|
double heightCoeff;
|
||||||
|
|
||||||
|
if (height < 2000) heightCoeff = 0;
|
||||||
|
else if (height < 2500) heightCoeff = (height - 2000) / 500;
|
||||||
|
else heightCoeff = 1;
|
||||||
|
|
||||||
|
if (heightCoeff < 1e-4) return 0;
|
||||||
|
|
||||||
|
double gradCoeff = computeSnowGradCoeff(height, grad);
|
||||||
|
return heightCoeff * gradCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeSnowOpaqueChance(double height, double grad) {
|
||||||
|
double heightCoeff;
|
||||||
|
|
||||||
|
if (height < 2500) heightCoeff = 0;
|
||||||
|
else if (height < 3000) heightCoeff = (height - 2500) / 500;
|
||||||
|
else heightCoeff = 1;
|
||||||
|
|
||||||
|
if (heightCoeff < 1e-4) return 0;
|
||||||
|
|
||||||
|
double gradCoeff = computeSnowGradCoeff(height, grad);
|
||||||
|
return heightCoeff * gradCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double computeSnowGradCoeff(double height, double grad) {
|
||||||
|
final double a = -0.00466666666666667;
|
||||||
|
final double b = 12.66666666666667;
|
||||||
|
double characteristicGrad = 1 / (a * height + b);
|
||||||
|
return Math.exp(-grad / characteristicGrad);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 7.2 KiB |
BIN
src/main/resources/assets/textures/blocks/granite_cracked.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
src/main/resources/assets/textures/blocks/granite_gravel.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
src/main/resources/assets/textures/blocks/granite_monolith.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
src/main/resources/assets/textures/tiles/snow_half.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
src/main/resources/assets/textures/tiles/snow_opaque.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
src/main/resources/assets/textures/tiles/snow_quarter.png
Normal file
After Width: | Height: | Size: 13 KiB |