diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java index df01b75..e3899eb 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java @@ -118,7 +118,7 @@ public class Camera { Glm.perspective( computeFovY(), GraphicsInterface.getAspectRatio(), - 0.01f, 10000.0f, + 0.01f, 150.0f, helper.pushViewTransform() ).mul(previous); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSimple.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSimple.java index 88e3f52..d9034cb 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSimple.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSimple.java @@ -14,10 +14,16 @@ import ru.windcorp.progressia.common.world.block.BlockFace; public class TileRenderSimple extends TileRender implements OpaqueTile { private final Texture texture; + private final boolean opaque; - public TileRenderSimple(String id, Texture texture) { + public TileRenderSimple(String id, Texture texture, boolean opaque) { super(id); this.texture = texture; + this.opaque = opaque; + } + + public TileRenderSimple(String id, Texture texture) { + this(id, texture, false); } @Override @@ -27,7 +33,7 @@ public class TileRenderSimple extends TileRender implements OpaqueTile { @Override public boolean isOpaque(BlockFace face) { - return false; + return opaque; } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 352f288..4066a14 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -68,6 +68,14 @@ public class TestContent { register(new BlockRenderOpaqueCube("Test:Stone", getBlockTexture("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 BlockRenderOpaqueCube("Test:Compass", getBlockTexture("compass"))); register(new BlockLogic("Test:Compass")); @@ -93,6 +101,18 @@ public class TestContent { register(new TileData("Test:Sand")); register(new TileRenderSimple("Test:Sand", getTileTexture("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() { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 7c9f18a..9fe9c59 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -64,11 +64,19 @@ public class TestWorldGenerator extends AbstractWorldGenerator { chunk.setGenerationHint(false); 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 stone = BlockDataRegistry.getInstance().get("Test:Stone"); 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[][] gradMap = new double[bpc][bpc]; @@ -84,8 +92,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { if (layer < -4) { chunk.setBlock(pos, stone, false); } else if (layer < 0) { - if (gradMap[pos.x][pos.y] > 0.3) { - chunk.setBlock(pos, stone, false); + if (gradMap[pos.x][pos.y] > 0.5) { + BlockData granite = granites[random.nextInt(4)]; + chunk.setBlock(pos, granite, false); } else { chunk.setBlock(pos, dirt, false); } @@ -145,12 +154,18 @@ public class TestWorldGenerator extends AbstractWorldGenerator { Vec3i biw = new Vec3i(); - int minX = Coordinates.getInWorld(chunkPos.x, 0); - int maxX = Coordinates.getInWorld(chunkPos.x + 1, 0); - int minY = Coordinates.getInWorld(chunkPos.y, 0); - int maxY = Coordinates.getInWorld(chunkPos.y + 1, 0); - int minZ = Coordinates.getInWorld(chunkPos.z, 0); - int maxZ = Coordinates.getInWorld(chunkPos.z + 1, 0); + int minX = chunk.getMinX(); + int maxX = chunk.getMaxX() + 1; + int minY = chunk.getMinY(); + int maxY = chunk.getMaxY() + 1; + int minZ = chunk.getMinZ(); + 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.y = minY; biw.y < maxY; ++biw.y) { @@ -161,7 +176,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { if (biw.z == maxZ) 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 { 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); 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) { @@ -221,4 +240,94 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } } + 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); + } + } diff --git a/src/main/resources/assets/textures/blocks/dirt.png b/src/main/resources/assets/textures/blocks/dirt.png index fb2347e..f9efc1d 100644 Binary files a/src/main/resources/assets/textures/blocks/dirt.png and b/src/main/resources/assets/textures/blocks/dirt.png differ diff --git a/src/main/resources/assets/textures/blocks/granite_cracked.png b/src/main/resources/assets/textures/blocks/granite_cracked.png new file mode 100644 index 0000000..508a193 Binary files /dev/null and b/src/main/resources/assets/textures/blocks/granite_cracked.png differ diff --git a/src/main/resources/assets/textures/blocks/granite_gravel.png b/src/main/resources/assets/textures/blocks/granite_gravel.png new file mode 100644 index 0000000..7d7e35b Binary files /dev/null and b/src/main/resources/assets/textures/blocks/granite_gravel.png differ diff --git a/src/main/resources/assets/textures/blocks/granite_monolith.png b/src/main/resources/assets/textures/blocks/granite_monolith.png new file mode 100644 index 0000000..507fdad Binary files /dev/null and b/src/main/resources/assets/textures/blocks/granite_monolith.png differ diff --git a/src/main/resources/assets/textures/tiles/snow_half.png b/src/main/resources/assets/textures/tiles/snow_half.png new file mode 100644 index 0000000..ce9eece Binary files /dev/null and b/src/main/resources/assets/textures/tiles/snow_half.png differ diff --git a/src/main/resources/assets/textures/tiles/snow_opaque.png b/src/main/resources/assets/textures/tiles/snow_opaque.png new file mode 100644 index 0000000..a6851c8 Binary files /dev/null and b/src/main/resources/assets/textures/tiles/snow_opaque.png differ diff --git a/src/main/resources/assets/textures/tiles/snow_quarter.png b/src/main/resources/assets/textures/tiles/snow_quarter.png new file mode 100644 index 0000000..6e9beee Binary files /dev/null and b/src/main/resources/assets/textures/tiles/snow_quarter.png differ