@Override public void process(GeneratingRegion region) { // will give funny results for regions that are not exactly chunk sized, but it is better than // sinking in the water on spawn Vector3i centerChunkPos = new Vector3i(ChunkConstants.CHUNK_REGION.center()); if (region.getRegion().encompasses(centerChunkPos)) { SurfaceHeightFacet facet = region.getRegionFacet(SurfaceHeightFacet.class); SeaLevelFacet seaLevelFacet = region.getRegionFacet(SeaLevelFacet.class); float seaLevel = seaLevelFacet.getSeaLevel(); float targetHeight = seaLevel + 1; // one block above the seaLevel // update the surface height so that it spikes up to sea level Vector2i middlePos = new Vector2i(centerChunkPos.x, centerChunkPos.z); for (BaseVector2i pos : facet.getWorldRegion().contents()) { float originalValue = facet.getWorld(pos); if (seaLevel > originalValue) { // the surface is below sea level float scaleTowardsSeaLevel = (float) pos.gridDistance(middlePos) / (float) (ChunkConstants.SIZE_X / 2); if (scaleTowardsSeaLevel < 1f) { facet.setWorld( pos, TeraMath.lerp(originalValue, targetHeight, 1f - scaleTowardsSeaLevel)); } } } } }
private Optional<Road> tryDirect( BaseVector2i posA, BaseVector2i posB, float width, BuildableTerrainFacet terrainFacet) { double length = posA.distance(posB); int segCount = TeraMath.ceilToInt(length / segLength); // ceil avoids division by zero for short distances List<Vector2i> segPoints = new ArrayList<>(); segPoints.add(new Vector2i(posA)); for (int i = 1; i < segCount; i++) { Vector2i pos = BaseVector2i.lerp(posA, posB, (float) i / segCount, RoundingMode.HALF_UP); // first and last point receive only half the noise distortion to smoothen the end points float applyFactor = (i == 1 || i == segCount - 1) ? 0.5f : 1f; pos.x += noiseX.noise(pos.x * smooth, 0, pos.y * smooth) * noiseAmp * applyFactor; pos.y += noiseY.noise(pos.x * smooth, 0, pos.y * smooth) * noiseAmp * applyFactor; if (!terrainFacet.isPassable(pos)) { return Optional.empty(); } segPoints.add(pos); } segPoints.add(new Vector2i(posB)); return Optional.of(new Road(segPoints, width)); }