diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java
new file mode 100644
index 0000000..f2438b3
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java
@@ -0,0 +1,25 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.common.util.math;
+
+@FunctionalInterface
+public interface FloatFunction {
+
+ float apply(float x);
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java
new file mode 100644
index 0000000..f41ea25
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java
@@ -0,0 +1,24 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.common.util.math;
+
+public interface FloatFunction2D {
+
+ float apply(float x, float y);
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java
new file mode 100644
index 0000000..3e5e7a7
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java
@@ -0,0 +1,24 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.common.util.math;
+
+public interface FloatFunction3D {
+
+ float apply(float x, float y, float z);
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java b/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java
new file mode 100644
index 0000000..051d7f2
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java
@@ -0,0 +1,124 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.common.util.math;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import glm.vec._2.Vec2;
+
+public class PiecewiseLinearFunction implements FloatFunction {
+
+ public static class Builder {
+
+ private final List points = new ArrayList<>();
+ private float slopeAtNegInf = 0;
+ private float slopeAtPosInf = 0;
+
+ public Builder add(float x, float y) {
+ points.add(new Vec2(x, y));
+ return this;
+ }
+
+ public Builder setNegativeSlope(float slope) {
+ slopeAtNegInf = slope;
+ return this;
+ }
+
+ public Builder setPositiveSlope(float slope) {
+ slopeAtPosInf = slope;
+ return this;
+ }
+
+ public Builder setDefaultUndefined() {
+ slopeAtPosInf = Float.NaN;
+ slopeAtNegInf = Float.NaN;
+ return this;
+ }
+
+ public PiecewiseLinearFunction build() {
+ float[] pointXs = new float[points.size()];
+ float[] pointYs = new float[points.size()];
+
+ points.sort(Comparator.comparingDouble(v -> v.x));
+ for (int i = 0; i < points.size(); ++i) {
+ pointXs[i] = points.get(i).x;
+ pointYs[i] = points.get(i).y;
+ }
+
+ return new PiecewiseLinearFunction(pointXs, pointYs, slopeAtNegInf, slopeAtPosInf);
+ }
+
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * The set of the X coordinates of all defining points, sorted in increasing order
+ */
+ private final float[] pointXs;
+
+ /**
+ * The set of the Y coordinates of all defining points, sorted to match the order of {@link #pointXs}
+ */
+ private final float[] pointYs;
+
+ /**
+ * Slope of the segment (-inf; x[0]), or NaN to exclude the segment from the function
+ */
+ private final float slopeAtNegInf;
+
+ /**
+ * Slope of the segment (x[x.length - 1]; +inf), or NaN to exclude the segment from the function
+ */
+ private final float slopeAtPosInf;
+
+ protected PiecewiseLinearFunction(float[] pointXs, float[] pointYs, float slopeAtNegInf, float slopeAtPosInf) {
+ this.pointXs = pointXs;
+ this.pointYs = pointYs;
+ this.slopeAtNegInf = slopeAtNegInf;
+ this.slopeAtPosInf = slopeAtPosInf;
+ }
+
+ @Override
+ public float apply(float x) {
+ int index = Arrays.binarySearch(pointXs, x);
+
+ if (index >= 0) {
+ // Wow, exact match, me surprised
+ return pointYs[index];
+ }
+
+ int bigger = -index - 1;
+ int smaller = bigger - 1;
+
+ if (smaller == -1) {
+ return pointYs[bigger] + (x - pointXs[bigger]) * slopeAtNegInf;
+ } else if (bigger == pointXs.length) {
+ return pointYs[smaller] + (x - pointXs[smaller]) * slopeAtPosInf;
+ } else {
+ float t = (x - pointXs[smaller]) / (pointXs[bigger] - pointXs[smaller]);
+ return pointYs[smaller] * (1 - t) + pointYs[bigger] * t;
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java
index b2c5c8c..dad0435 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java
@@ -24,7 +24,6 @@ import java.util.List;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
-import ru.windcorp.progressia.common.util.FloatRangeMap;
import ru.windcorp.progressia.common.util.VectorUtil;
import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.DecodingException;
@@ -32,7 +31,7 @@ import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
-import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer;
+import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier;
public class PlanetGenerator extends AbstractWorldGenerator {
@@ -46,7 +45,7 @@ public class PlanetGenerator extends AbstractWorldGenerator {
Server server,
Planet planet,
SurfaceFloatField heightMap,
- FloatRangeMap layers,
+ TerrainSupplier terrain,
List features
) {
super(id, server, Boolean.class, "Test:PlanetGravityModel");
@@ -56,7 +55,7 @@ public class PlanetGenerator extends AbstractWorldGenerator {
PlanetGravityModel model = (PlanetGravityModel) this.getGravityModel();
model.configure(planet.getGravityModelSettings());
- this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, layers);
+ this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, terrain);
this.featureGenerator = new PlanetFeatureGenerator(this, features);
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java
index cb4507c..368a59a 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java
@@ -21,7 +21,6 @@ import java.util.Map;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
-import ru.windcorp.progressia.common.util.FloatRangeMap;
import ru.windcorp.progressia.common.util.VectorUtil;
import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.Coordinates;
@@ -33,7 +32,7 @@ import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.generation.surface.Surface;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceTerrainGenerator;
-import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer;
+import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier;
class PlanetTerrainGenerator {
@@ -43,7 +42,7 @@ class PlanetTerrainGenerator {
public PlanetTerrainGenerator(
PlanetGenerator generator,
SurfaceFloatField heightMap,
- FloatRangeMap layers
+ TerrainSupplier terrain
) {
this.parent = generator;
@@ -53,7 +52,7 @@ class PlanetTerrainGenerator {
face -> new SurfaceTerrainGenerator(
new Surface(face, seaLevel),
heightMap,
- layers
+ terrain
)
);
}
diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java
index ea7cb9b..ead1d47 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java
@@ -19,7 +19,6 @@ package ru.windcorp.progressia.server.world.generation.surface;
import glm.vec._3.Vec3;
import glm.vec._3.i.Vec3i;
-import ru.windcorp.progressia.common.util.FloatRangeMap;
import ru.windcorp.progressia.common.util.Vectors;
import ru.windcorp.progressia.common.world.DefaultChunkData;
import ru.windcorp.progressia.common.world.block.BlockData;
@@ -33,12 +32,12 @@ public class SurfaceTerrainGenerator {
private final Surface surface;
private final SurfaceFloatField heightMap;
- private final FloatRangeMap layers;
+ private final TerrainSupplier terrain;
- public SurfaceTerrainGenerator(Surface surface, SurfaceFloatField heightMap, FloatRangeMap layers) {
+ public SurfaceTerrainGenerator(Surface surface, SurfaceFloatField heightMap, TerrainSupplier terrain) {
this.surface = surface;
this.heightMap = heightMap;
- this.layers = layers;
+ this.terrain = terrain;
}
public void generateTerrain(Server server, DefaultChunkData chunk) {
@@ -74,7 +73,7 @@ public class SurfaceTerrainGenerator {
location.set(north, west, altitude);
SurfaceBlockContext blockContext = context.push(location);
- BlockData block = layers.get(depth).get(blockContext, depth);
+ BlockData block = terrain.get(blockContext, depth);
blockContext.pop();
diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainSupplier.java
similarity index 96%
rename from src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java
rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainSupplier.java
index 5ec131c..a3a1376 100644
--- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java
+++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainSupplier.java
@@ -21,7 +21,7 @@ import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
@FunctionalInterface
-public interface TerrainLayer {
+public interface TerrainSupplier {
BlockData get(SurfaceBlockContext context, float depth);
diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java
index 8396e21..75e32e4 100644
--- a/src/main/java/ru/windcorp/progressia/test/TestContent.java
+++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java
@@ -104,6 +104,8 @@ public class TestContent {
registerSimplestBlock("Dirt");
registerSimplestBlock("Chernozem");
registerSimplestBlock("Stone");
+ registerSimplestBlock("Mantle");
+ registerSimplestBlock("Water");
registerSimplestBlock("Brick");
registerSimplestBlock("BrickWhite");
registerSimplestBlock("Sand");
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java
index ee0f312..2147889 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java
@@ -24,21 +24,18 @@ import java.util.List;
import java.util.function.Function;
import ru.windcorp.progressia.common.Units;
-import ru.windcorp.progressia.common.util.ArrayFloatRangeMap;
-import ru.windcorp.progressia.common.util.FloatRangeMap;
import ru.windcorp.progressia.common.util.noise.discrete.WorleyProceduralNoise;
import ru.windcorp.progressia.common.world.Coordinates;
-import ru.windcorp.progressia.common.world.block.BlockData;
-import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.generation.WorldGenerator;
import ru.windcorp.progressia.server.world.generation.planet.Planet;
import ru.windcorp.progressia.server.world.generation.planet.PlanetGenerator;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
-import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer;
-import ru.windcorp.progressia.test.Rocks.RockVariant;
+import ru.windcorp.progressia.test.Rocks.Rock;
import ru.windcorp.progressia.test.TestContent;
+import ru.windcorp.progressia.test.gen.feature.*;
+import ru.windcorp.progressia.test.gen.terrain.*;
public class TestGenerationConfig {
@@ -62,47 +59,45 @@ public class TestGenerationConfig {
TestHeightMap heightMap = new TestHeightMap(planet, planet.getRadius() / 4, FIELDS);
- FloatRangeMap layers = new ArrayFloatRangeMap<>();
- registerTerrainLayers(layers);
+ LayeredTerrain terrain = new LayeredTerrain();
+ registerTerrainLayers(terrain);
List features = new ArrayList<>();
registerFeatures(features);
- return server -> new PlanetGenerator("Test:PlanetGenerator", server, planet, heightMap, layers, features);
+ return server -> new PlanetGenerator("Test:PlanetGenerator", server, planet, heightMap, terrain, features);
}
- private static void registerTerrainLayers(FloatRangeMap layers) {
- BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt");
- BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
-
+ private static void registerTerrainLayers(LayeredTerrain terrain) {
SurfaceFloatField cliffs = FIELDS.get("Test:Cliff");
+ SurfaceFloatField beaches = FIELDS.register(
+ "Test:Beach",
+ f -> multiply(
+ anti(FIELDS.get("Test:Cliff", f))
+ )
+ );
+ RockStrata rockStrata = createStrata();
- WorleyProceduralNoise.Builder builder = WorleyProceduralNoise.builder();
- TestContent.ROCKS.getRocks().forEach(rock -> {
- builder.add((c, d) -> {
- if (c.getRandom().nextInt(3) == 0) {
- return rock.getBlock(RockVariant.CRACKED);
- } else {
- return rock.getBlock(RockVariant.MONOLITH);
- }
- }, 1);
- });
+ terrain.addLayer(new AirLayer("Test:Air"));
+ terrain.addLayer(new MantleLayer("Test:Mantle"));
+ terrain.addLayer(new CrustLayer("Test:Crust", rockStrata));
+ terrain.addLayer(new WaterLayer("Test:Water"));
+ terrain.addLayer(new SoilLayer("Test:Soil"));
+ terrain.addLayer(new CliffLayer("Test:Cliffs", cliffs, rockStrata));
+ terrain.addLayer(new BeachLayer("Test:Beaches", beaches, rockStrata));
+ }
+
+ private static RockStrata createStrata() {
+ WorleyProceduralNoise.Builder builder = WorleyProceduralNoise.builder();
+ TestContent.ROCKS.getRocks().forEach(rock -> builder.add(rock, 1));
+
SurfaceFloatField rockDepthOffsets = FIELDS.register(
"Test:RockDepthOffsets",
() -> tweak(FIELDS.primitive(), 40, 5)
);
- RockLayer rockLayer = new RockLayer(builder.build(SEED), rockDepthOffsets);
-
- layers.put(Float.NEGATIVE_INFINITY, 0, (c, d) -> air);
- layers.put(0, 4, (c, d) -> {
- if (cliffs.get(c.getSurface().getUp(), c.getLocation().x, c.getLocation().y) > 0) {
- return rockLayer.get(c, d);
- } else {
- return dirt;
- }
- });
- layers.put(4, Float.POSITIVE_INFINITY, rockLayer);
+
+ return new RockStrata(builder.build(SEED), rockDepthOffsets);
}
private static void registerFeatures(List features) {
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java
similarity index 98%
rename from src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java
rename to src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java
index 5cfcc43..ecd738d 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.feature;
import java.util.Set;
import java.util.function.Consumer;
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java
similarity index 97%
rename from src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java
rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java
index ca2765c..b559582 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.feature;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.block.BlockData;
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java
similarity index 98%
rename from src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java
rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java
index 33460a1..19a97aa 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.feature;
import java.util.Set;
import java.util.function.Function;
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java
similarity index 93%
rename from src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java
rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java
index 2c564b7..add06ec 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.feature;
import java.util.List;
import java.util.Set;
@@ -104,7 +104,17 @@ public class TestGrassFeature extends SurfaceTopLayerFeature {
}
private void growGrass(SurfaceBlockContext context, double grassiness) {
- TileData flatGrass = flatGrasses.get((float) grassiness);
+
+ double flatGrassiness = grassiness;
+ BlockData soil = context.getBlock();
+ if (soil.getId().endsWith("Sand")) {
+ flatGrassiness = flatGrassiness / 2 - 0.2;
+ if (flatGrassiness < 0) {
+ flatGrassiness = 0;
+ }
+ }
+
+ TileData flatGrass = flatGrasses.get((float) flatGrassiness);
if (flatGrass != null) {
for (RelFace face : RelFace.getFaces()) {
if (face == RelFace.DOWN)
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java
similarity index 98%
rename from src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java
rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java
index d08862e..611ec07 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.feature;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.block.BlockData;
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java
new file mode 100644
index 0000000..dbafbd4
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java
@@ -0,0 +1,42 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public class AirLayer extends TerrainLayer {
+
+ private final BlockData air = BlockDataRegistry.getInstance().get("Test:Air");
+
+ public AirLayer(String id) {
+ super(id);
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+ return air;
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ return depth <= 0 ? 1 : 0;
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java
new file mode 100644
index 0000000..24880ab
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java
@@ -0,0 +1,55 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+import ru.windcorp.progressia.test.Rocks.RockVariant;
+
+public class BeachLayer extends TerrainLayer {
+
+ private final SurfaceFloatField beachSelector;
+ private final RockStrata strata;
+
+ public BeachLayer(String id, SurfaceFloatField beachSelector, RockStrata strata) {
+ super(id);
+ this.beachSelector = beachSelector;
+ this.strata = strata;
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+ return strata.get(context, depth).getBlock(RockVariant.SAND);
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ if (depth < 0 || depth > 3) {
+ return 0;
+ }
+
+ float altitude = context.getLocation().z;
+ if (altitude < -5| altitude > 1) {
+ return 0;
+ }
+
+ return 3 * beachSelector.get(context);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java
new file mode 100644
index 0000000..59f487a
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java
@@ -0,0 +1,64 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+import ru.windcorp.progressia.test.Rocks.RockVariant;
+
+public class CliffLayer extends TerrainLayer {
+
+ private final SurfaceFloatField cliffSelector;
+ private final RockStrata strata;
+
+ public CliffLayer(String id, SurfaceFloatField cliffSelector, RockStrata strata) {
+ super(id);
+ this.cliffSelector = cliffSelector;
+ this.strata = strata;
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+
+ RockVariant variant;
+ switch (context.getRandom().nextInt(4)) {
+ case 0:
+ variant = RockVariant.GRAVEL;
+ break;
+ case 1:
+ variant = RockVariant.MONOLITH;
+ break;
+ default:
+ variant = RockVariant.CRACKED;
+ break;
+ }
+
+ return strata.get(context, depth).getBlock(variant);
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ if (depth < 0 || depth > 7) {
+ return 0;
+ }
+
+ return 100 * cliffSelector.get(context);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java
new file mode 100644
index 0000000..2ce53a6
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java
@@ -0,0 +1,69 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.util.ArrayFloatRangeMap;
+import ru.windcorp.progressia.common.util.FloatRangeMap;
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+import ru.windcorp.progressia.test.Rocks.RockVariant;
+
+public class CrustLayer extends TerrainLayer {
+
+ private static final FloatRangeMap WEAR_TABLE = new ArrayFloatRangeMap<>();
+ static {
+ WEAR_TABLE.put(Float.NEGATIVE_INFINITY, 0.25f, RockVariant.MONOLITH);
+ WEAR_TABLE.put(0.25f, 0.5f, RockVariant.CRACKED);
+ WEAR_TABLE.put(0.5f, 0.75f, RockVariant.GRAVEL);
+ WEAR_TABLE.put(0.75f, Float.POSITIVE_INFINITY, RockVariant.SAND);
+ }
+
+ private final RockStrata strata;
+
+ public CrustLayer(String id, RockStrata strata) {
+ super(id);
+ this.strata = strata;
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+
+ RockVariant variant;
+ if (depth < 8) {
+ float wear = 1 - depth / 8;
+ float offset = (context.getRandom().nextFloat() * 2 - 1) * 0.5f;
+ variant = WEAR_TABLE.get(wear + offset);
+ } else {
+ variant = RockVariant.MONOLITH;
+ }
+
+ return strata.get(context, depth).getBlock(variant);
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ if (depth < 0) {
+ return 0;
+ } else if (context.getLocation().z > -100) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java
new file mode 100644
index 0000000..ac802c2
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java
@@ -0,0 +1,61 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public class LayeredTerrain implements TerrainSupplier {
+
+ private final List layers = new ArrayList<>();
+
+ public void addLayer(TerrainLayer layer) {
+ this.layers.add(layer);
+ }
+
+ @Override
+ public BlockData get(SurfaceBlockContext context, float depth) {
+ TerrainLayer layer = null;
+ float intensity = 0;
+
+ for (int i = 0; i < layers.size(); ++i) {
+ TerrainLayer currentLayer = layers.get(i);
+
+ float currentIntensity = currentLayer.getIntensity(context, depth);
+ if (currentIntensity <= 0) {
+ continue;
+ }
+
+ if (intensity < currentIntensity) {
+ intensity = currentIntensity;
+ layer = currentLayer;
+ }
+ }
+
+ if (layer == null) {
+ layer = layers.get(0);
+ }
+
+ return layer.generate(context, depth, intensity);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java
new file mode 100644
index 0000000..a72f95e
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java
@@ -0,0 +1,42 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public class MantleLayer extends TerrainLayer {
+
+ private final BlockData material = BlockDataRegistry.getInstance().get("Test:Mantle");
+
+ public MantleLayer(String id) {
+ super(id);
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+ return material;
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ return context.getLocation().z <= -100 ? 1 : 0;
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java
similarity index 64%
rename from src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java
rename to src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java
index 5b41ef1..218b51a 100644
--- a/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java
@@ -15,43 +15,38 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package ru.windcorp.progressia.test.gen;
+package ru.windcorp.progressia.test.gen.terrain;
import ru.windcorp.progressia.common.util.noise.discrete.DiscreteNoise;
-import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField;
-import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer;
import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+import ru.windcorp.progressia.test.Rocks.Rock;
-public class RockLayer implements TerrainLayer {
-
- private final DiscreteNoise strata;
+public class RockStrata {
+
+ private final DiscreteNoise distribution;
private final SurfaceFloatField depthOffsets;
- private final double horizontalScale = 200;
- private final double verticalScale = 10;
- private final double depthInfluense = 0.1;
+ private final double horizontalScale = 800;
+ private final double verticalScale = 20;
+ private final double depthInfluence = 0.1;
- public RockLayer(DiscreteNoise strata, SurfaceFloatField depthOffsets) {
- this.strata = strata;
+ public RockStrata(DiscreteNoise distribution, SurfaceFloatField depthOffsets) {
+ this.distribution = distribution;
this.depthOffsets = depthOffsets;
}
-
- @Override
- public BlockData get(SurfaceBlockContext context, float depth) {
-
+
+ public Rock get(SurfaceBlockContext context, float depth) {
double z = context.getLocation().z;
- z -= depth * depthInfluense;
+ z -= depth * depthInfluence;
z += depthOffsets.get(context);
z /= verticalScale;
- return strata
- .get(
+ return distribution.get(
context.getLocation().x / horizontalScale,
context.getLocation().y / horizontalScale,
z
- )
- .get(context, depth);
+ );
}
}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java
new file mode 100644
index 0000000..44875a0
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java
@@ -0,0 +1,59 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.Units;
+import ru.windcorp.progressia.common.util.math.PiecewiseLinearFunction;
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public class SoilLayer extends TerrainLayer {
+
+ private static final PiecewiseLinearFunction THICKNESS = PiecewiseLinearFunction.builder()
+ .add(Units.get("-5 m"), Units.get("1 m"))
+ .add(Units.get("0 m"), Units.get("4 m"))
+ .add(Units.get("5 km"), Units.get("0 m"))
+ .build();
+
+ private final BlockData soil = BlockDataRegistry.getInstance().get("Test:Dirt");
+
+ public SoilLayer(String id) {
+ super(id);
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+ return soil;
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ if (depth < 0) return 0;
+
+ float altitude = context.getLocation().z;
+ float thickness = THICKNESS.apply(altitude);
+
+ if (depth < thickness) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java
new file mode 100644
index 0000000..e9eeb4b
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java
@@ -0,0 +1,34 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.util.namespaces.Namespaced;
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public abstract class TerrainLayer extends Namespaced {
+
+ public TerrainLayer(String id) {
+ super(id);
+ }
+
+ public abstract BlockData generate(SurfaceBlockContext context, float depth, float intensity);
+
+ public abstract float getIntensity(SurfaceBlockContext context, float depth);
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java
new file mode 100644
index 0000000..3813f68
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java
@@ -0,0 +1,45 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.test.gen.terrain;
+
+import ru.windcorp.progressia.common.world.block.BlockData;
+import ru.windcorp.progressia.common.world.block.BlockDataRegistry;
+import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext;
+
+public class WaterLayer extends TerrainLayer {
+
+ private final BlockData water = BlockDataRegistry.getInstance().get("Test:Water");
+
+ public WaterLayer(String id) {
+ super(id);
+ }
+
+ @Override
+ public BlockData generate(SurfaceBlockContext context, float depth, float intensity) {
+ return water;
+ }
+
+ @Override
+ public float getIntensity(SurfaceBlockContext context, float depth) {
+ if (depth <= 0 && context.getLocation().z <= 0) {
+ return 2;
+ }
+ return 0;
+ }
+
+}
diff --git a/src/main/resources/assets/textures/blocks/Mantle.png b/src/main/resources/assets/textures/blocks/Mantle.png
new file mode 100644
index 0000000..838daff
Binary files /dev/null and b/src/main/resources/assets/textures/blocks/Mantle.png differ
diff --git a/src/main/resources/assets/textures/blocks/Water.png b/src/main/resources/assets/textures/blocks/Water.png
new file mode 100644
index 0000000..e609712
Binary files /dev/null and b/src/main/resources/assets/textures/blocks/Water.png differ